forked from snowflakedb/gosnowflake
-
Notifications
You must be signed in to change notification settings - Fork 0
/
location.go
89 lines (82 loc) · 2.09 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
// Copyright (c) 2017-2019 Snowflake Computing Inc. All right reserved.
package gosnowflake
import (
"fmt"
"strconv"
"sync"
"time"
)
var timezones map[int]*time.Location
var 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)
}
}