Add weather API bundle adapter
This commit is contained in:
@@ -2,6 +2,8 @@ package timeutil
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
@@ -10,6 +12,12 @@ const DateLayout = "2006-01-02"
|
||||
const LocalDateTimeLayout = "2006-01-02T15:04"
|
||||
|
||||
func LoadLocation(name string) (*time.Location, error) {
|
||||
if location, ok := timezoneAliases[name]; ok {
|
||||
return location, nil
|
||||
}
|
||||
if location, ok := parseUTCOffset(name); ok {
|
||||
return location, nil
|
||||
}
|
||||
location, err := time.LoadLocation(name)
|
||||
if err == nil {
|
||||
return location, nil
|
||||
@@ -24,6 +32,52 @@ func LoadLocation(name string) (*time.Location, error) {
|
||||
return nil, fmt.Errorf("load timezone %q: %w", name, err)
|
||||
}
|
||||
|
||||
var timezoneAliases = map[string]*time.Location{
|
||||
"Chicago": mustLocation("America/Chicago"),
|
||||
"Stl": mustLocation("America/Chicago"),
|
||||
"EST": time.FixedZone("EST", -5*60*60),
|
||||
"EDT": time.FixedZone("EDT", -4*60*60),
|
||||
"CST": time.FixedZone("CST", -6*60*60),
|
||||
"CDT": time.FixedZone("CDT", -5*60*60),
|
||||
"MST": time.FixedZone("MST", -7*60*60),
|
||||
"MDT": time.FixedZone("MDT", -6*60*60),
|
||||
"PST": time.FixedZone("PST", -8*60*60),
|
||||
"PDT": time.FixedZone("PDT", -7*60*60),
|
||||
}
|
||||
|
||||
func mustLocation(name string) *time.Location {
|
||||
location, err := time.LoadLocation(name)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return location
|
||||
}
|
||||
|
||||
var utcOffsetPattern = regexp.MustCompile(`^([+-])(\d{1,2})(?::?(\d{2}))?$`)
|
||||
|
||||
func parseUTCOffset(value string) (*time.Location, bool) {
|
||||
matches := utcOffsetPattern.FindStringSubmatch(value)
|
||||
if matches == nil {
|
||||
return nil, false
|
||||
}
|
||||
hours, err := strconv.Atoi(matches[2])
|
||||
if err != nil || hours > 23 {
|
||||
return nil, false
|
||||
}
|
||||
minutes := 0
|
||||
if matches[3] != "" {
|
||||
minutes, err = strconv.Atoi(matches[3])
|
||||
if err != nil || minutes > 59 {
|
||||
return nil, false
|
||||
}
|
||||
}
|
||||
offset := (hours*60 + minutes) * 60
|
||||
if matches[1] == "-" {
|
||||
offset = -offset
|
||||
}
|
||||
return time.FixedZone(value, offset), true
|
||||
}
|
||||
|
||||
func LocalDate(now time.Time, location *time.Location) time.Time {
|
||||
local := now.In(location)
|
||||
return time.Date(local.Year(), local.Month(), local.Day(), 0, 0, 0, 0, location)
|
||||
|
||||
Reference in New Issue
Block a user