Skip to content

Commit f8648cb

Browse files
authored
add timezone conversions (#272)
1 parent f171aab commit f8648cb

2 files changed

Lines changed: 185 additions & 0 deletions

File tree

go/type/v1/timezone.go

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package type_v1
2+
3+
import (
4+
"fmt"
5+
"time"
6+
)
7+
8+
// ToLocation converts a Timezone enum value to a *time.Location.
9+
func (tz Timezone) ToLocation() (*time.Location, error) {
10+
iana, ok := timezoneToIANA[tz]
11+
if !ok {
12+
return nil, fmt.Errorf("unsupported timezone: %s", tz)
13+
}
14+
return time.LoadLocation(iana)
15+
}
16+
17+
// ToIANAString converts a Timezone enum value to its IANA timezone string.
18+
func (tz Timezone) ToIANAString() (string, error) {
19+
iana, ok := timezoneToIANA[tz]
20+
if !ok {
21+
return "", fmt.Errorf("unsupported timezone: %s", tz)
22+
}
23+
return iana, nil
24+
}
25+
26+
// timezoneToIANA maps each Timezone enum value to its IANA timezone string.
27+
var timezoneToIANA = map[Timezone]string{
28+
Timezone_TIMEZONE_UTC: "UTC",
29+
Timezone_TIMEZONE_EUROPE_LONDON: "Europe/London",
30+
Timezone_TIMEZONE_AFRICA_CASABLANCA: "Africa/Casablanca",
31+
Timezone_TIMEZONE_AFRICA_LAGOS: "Africa/Lagos",
32+
Timezone_TIMEZONE_EUROPE_PARIS: "Europe/Paris",
33+
Timezone_TIMEZONE_AFRICA_JOHANNESBURG: "Africa/Johannesburg",
34+
Timezone_TIMEZONE_AFRICA_MAPUTO: "Africa/Maputo",
35+
Timezone_TIMEZONE_EUROPE_ATHENS: "Europe/Athens",
36+
Timezone_TIMEZONE_AFRICA_CAIRO: "Africa/Cairo",
37+
Timezone_TIMEZONE_ASIA_JERUSALEM: "Asia/Jerusalem",
38+
Timezone_TIMEZONE_EUROPE_MOSCOW: "Europe/Moscow",
39+
Timezone_TIMEZONE_EUROPE_ISTANBUL: "Europe/Istanbul",
40+
Timezone_TIMEZONE_AFRICA_NAIROBI: "Africa/Nairobi",
41+
Timezone_TIMEZONE_ASIA_RIYADH: "Asia/Riyadh",
42+
Timezone_TIMEZONE_ASIA_TEHRAN: "Asia/Tehran",
43+
Timezone_TIMEZONE_ASIA_DUBAI: "Asia/Dubai",
44+
Timezone_TIMEZONE_ASIA_KARACHI: "Asia/Karachi",
45+
Timezone_TIMEZONE_ASIA_KOLKATA: "Asia/Kolkata",
46+
Timezone_TIMEZONE_ASIA_DHAKA: "Asia/Dhaka",
47+
Timezone_TIMEZONE_ASIA_BANGKOK: "Asia/Bangkok",
48+
Timezone_TIMEZONE_ASIA_SHANGHAI: "Asia/Shanghai",
49+
Timezone_TIMEZONE_ASIA_SINGAPORE: "Asia/Singapore",
50+
Timezone_TIMEZONE_ASIA_HONG_KONG: "Asia/Hong_Kong",
51+
Timezone_TIMEZONE_AUSTRALIA_PERTH: "Australia/Perth",
52+
Timezone_TIMEZONE_ASIA_TOKYO: "Asia/Tokyo",
53+
Timezone_TIMEZONE_ASIA_SEOUL: "Asia/Seoul",
54+
Timezone_TIMEZONE_AUSTRALIA_ADELAIDE: "Australia/Adelaide",
55+
Timezone_TIMEZONE_AUSTRALIA_BRISBANE: "Australia/Brisbane",
56+
Timezone_TIMEZONE_AUSTRALIA_SYDNEY: "Australia/Sydney",
57+
Timezone_TIMEZONE_PACIFIC_AUCKLAND: "Pacific/Auckland",
58+
Timezone_TIMEZONE_AMERICA_SAO_PAULO: "America/Sao_Paulo",
59+
Timezone_TIMEZONE_AMERICA_ARGENTINA_BUENOS_AIRES: "America/Argentina/Buenos_Aires",
60+
Timezone_TIMEZONE_AMERICA_CARACAS: "America/Caracas",
61+
Timezone_TIMEZONE_AMERICA_SANTIAGO: "America/Santiago",
62+
Timezone_TIMEZONE_AMERICA_NEW_YORK: "America/New_York",
63+
Timezone_TIMEZONE_AMERICA_CHICAGO: "America/Chicago",
64+
Timezone_TIMEZONE_AMERICA_DENVER: "America/Denver",
65+
Timezone_TIMEZONE_AMERICA_LOS_ANGELES: "America/Los_Angeles",
66+
Timezone_TIMEZONE_AMERICA_ANCHORAGE: "America/Anchorage",
67+
Timezone_TIMEZONE_PACIFIC_HONOLULU: "Pacific/Honolulu",
68+
}

go/type/v1/timezone_test.go

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
package type_v1
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/assert"
7+
"github.com/stretchr/testify/require"
8+
)
9+
10+
func TestTimezone_ToLocation(t *testing.T) {
11+
tests := []struct {
12+
name string
13+
tz Timezone
14+
wantErr bool
15+
wantName string
16+
}{
17+
{
18+
name: "UTC",
19+
tz: Timezone_TIMEZONE_UTC,
20+
wantName: "UTC",
21+
},
22+
{
23+
name: "America/New_York",
24+
tz: Timezone_TIMEZONE_AMERICA_NEW_YORK,
25+
wantName: "America/New_York",
26+
},
27+
{
28+
name: "Asia/Tokyo",
29+
tz: Timezone_TIMEZONE_ASIA_TOKYO,
30+
wantName: "Asia/Tokyo",
31+
},
32+
{
33+
name: "Australia/Sydney",
34+
tz: Timezone_TIMEZONE_AUSTRALIA_SYDNEY,
35+
wantName: "Australia/Sydney",
36+
},
37+
{
38+
name: "Europe/Paris",
39+
tz: Timezone_TIMEZONE_EUROPE_PARIS,
40+
wantName: "Europe/Paris",
41+
},
42+
{
43+
name: "unsupported timezone",
44+
tz: Timezone(9999),
45+
wantErr: true,
46+
},
47+
}
48+
49+
for _, tt := range tests {
50+
t.Run(tt.name, func(t *testing.T) {
51+
loc, err := tt.tz.ToLocation()
52+
if tt.wantErr {
53+
require.Error(t, err)
54+
assert.Nil(t, loc)
55+
assert.Contains(t, err.Error(), "unsupported timezone")
56+
} else {
57+
require.NoError(t, err)
58+
require.NotNil(t, loc)
59+
assert.Equal(t, tt.wantName, loc.String())
60+
}
61+
})
62+
}
63+
}
64+
65+
func TestTimezone_ToIANAString(t *testing.T) {
66+
tests := []struct {
67+
name string
68+
tz Timezone
69+
wantErr bool
70+
wantIANA string
71+
}{
72+
{
73+
name: "UTC",
74+
tz: Timezone_TIMEZONE_UTC,
75+
wantIANA: "UTC",
76+
},
77+
{
78+
name: "America/Los_Angeles",
79+
tz: Timezone_TIMEZONE_AMERICA_LOS_ANGELES,
80+
wantIANA: "America/Los_Angeles",
81+
},
82+
{
83+
name: "Asia/Singapore",
84+
tz: Timezone_TIMEZONE_ASIA_SINGAPORE,
85+
wantIANA: "Asia/Singapore",
86+
},
87+
{
88+
name: "Africa/Johannesburg",
89+
tz: Timezone_TIMEZONE_AFRICA_JOHANNESBURG,
90+
wantIANA: "Africa/Johannesburg",
91+
},
92+
{
93+
name: "Pacific/Auckland",
94+
tz: Timezone_TIMEZONE_PACIFIC_AUCKLAND,
95+
wantIANA: "Pacific/Auckland",
96+
},
97+
{
98+
name: "unsupported timezone",
99+
tz: Timezone(9999),
100+
wantErr: true,
101+
},
102+
}
103+
104+
for _, tt := range tests {
105+
t.Run(tt.name, func(t *testing.T) {
106+
iana, err := tt.tz.ToIANAString()
107+
if tt.wantErr {
108+
require.Error(t, err)
109+
assert.Empty(t, iana)
110+
assert.Contains(t, err.Error(), "unsupported timezone")
111+
} else {
112+
require.NoError(t, err)
113+
assert.Equal(t, tt.wantIANA, iana)
114+
}
115+
})
116+
}
117+
}

0 commit comments

Comments
 (0)