-
Notifications
You must be signed in to change notification settings - Fork 125
/
location.go
106 lines (98 loc) · 2.46 KB
/
location.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
// Copyright (c) 2017-2022 Snowflake Computing Inc. All rights reserved.
package gosnowflake
import (
"fmt"
"strconv"
"sync"
"time"
)
var (
timezones map[int]*time.Location
updateTimezoneMutex *sync.Mutex
)
// Location returns an offset (minutes) based Location object for Snowflake database.
func Location(offset int) *time.Location {
updateTimezoneMutex.Lock()
defer updateTimezoneMutex.Unlock()
loc := timezones[offset]
if loc != nil {
return loc
}
loc = genTimezone(offset)
timezones[offset] = loc
return loc
}
// LocationWithOffsetString returns an offset based Location object. The offset string must consist of sHHMI where one sign
// character '+'/'-' followed by zero filled hours and minutes.
func LocationWithOffsetString(offsets string) (loc *time.Location, err error) {
if len(offsets) != 5 {
return nil, &SnowflakeError{
Number: ErrInvalidOffsetStr,
SQLState: SQLStateInvalidDataTimeFormat,
Message: errMsgInvalidOffsetStr,
MessageArgs: []interface{}{offsets},
}
}
if offsets[0] != '-' && offsets[0] != '+' {
return nil, &SnowflakeError{
Number: ErrInvalidOffsetStr,
SQLState: SQLStateInvalidDataTimeFormat,
Message: errMsgInvalidOffsetStr,
MessageArgs: []interface{}{offsets},
}
}
s := 1
if offsets[0] == '-' {
s = -1
}
var h, m int64
h, err = strconv.ParseInt(offsets[1:3], 10, 64)
if err != nil {
return
}
m, err = strconv.ParseInt(offsets[3:], 10, 64)
if err != nil {
return
}
offset := s * (int(h)*60 + int(m))
loc = Location(offset)
return
}
func genTimezone(offset int) *time.Location {
var offsetSign string
var toffset int
if offset < 0 {
offsetSign = "-"
toffset = -offset
} else {
offsetSign = "+"
toffset = offset
}
logger.Debugf("offset: %v", offset)
return time.FixedZone(
fmt.Sprintf("%v%02d%02d",
offsetSign, toffset/60, toffset%60), int(offset)*60)
}
func init() {
updateTimezoneMutex = &sync.Mutex{}
timezones = make(map[int]*time.Location, 48)
// pre-generate all common timezones
for i := -720; i <= 720; i += 30 {
logger.Debugf("offset: %v", i)
timezones[i] = genTimezone(i)
}
}
// retrieve current location based on connection
func getCurrentLocation(params map[string]*string) *time.Location {
loc := time.Now().Location()
var err error
paramsMutex.Lock()
if tz, ok := params["timezone"]; ok && tz != nil {
loc, err = time.LoadLocation(*tz)
if err != nil {
loc = time.Now().Location()
}
}
paramsMutex.Unlock()
return loc
}