Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion .github/workflows/coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ on:
- main
tags:
- 'v*'
pull_request:
branches:
- main

permissions:
contents: read
Expand Down Expand Up @@ -47,6 +50,7 @@ jobs:
uses: codecov/codecov-action@v5
with:
files: coverage.out
fail_ci_if_error: true
# Fork PRs upload tokenlessly, which can be flaky; don't fail their CI.
fail_ci_if_error: ${{ github.event_name != 'pull_request' }}
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
10 changes: 10 additions & 0 deletions .golangci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -112,3 +112,13 @@ linters:
desc: Use github.com/go-resty/resty/v2 instead
- pkg: github.com/aws/smithy-go/ptr$
desc: Use github.com/aws/aws-sdk-go-v2/aws instead

exclusions:
rules:
# TimeZone intentionally mixes receivers: Scan/LoadString/Unmarshal* need
# pointer receivers to mutate, while the rest stay value receivers to keep
# the zero-value-as-UTC value semantics.
- linters:
- recvcheck
path: time_zone.go
text: 'the methods of "TimeZone"'
12 changes: 12 additions & 0 deletions time_zone.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,18 @@ func LoadTimeZone(name string) (TimeZone, error) {
return z, nil
}

// MustLoadTimeZone is like [LoadTimeZone] but panics if the name is invalid.
// It is intended for use in variable initializations and tests where the
// time zone name is known to be valid.
func MustLoadTimeZone(name string) TimeZone {
z, err := LoadTimeZone(name)
if err != nil {
panic(err)
}

return z
}

// Location returns the *time.Location for this TimeZone.
// The zero value (UTC) returns time.UTC; it never returns nil.
func (z TimeZone) Location() *time.Location {
Expand Down
17 changes: 14 additions & 3 deletions time_zone_example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,14 @@ func ExampleTimeZone_zeroValue() {
// true
}

func ExampleMustLoadTimeZone() {
z := tz.MustLoadTimeZone("America/New_York")
fmt.Println(z.String())

// Output:
// America/New_York
}

func ExampleTimeZone_Scan() {
var z tz.TimeZone
if err := z.Scan("America/New_York"); err != nil {
Expand Down Expand Up @@ -71,15 +79,15 @@ func ExampleTimeZone_Value_zeroValue() {
}

func ExampleUTCTimeZone() {
z, _ := tz.LoadTimeZone("UTC")
z := tz.MustLoadTimeZone("UTC")
fmt.Println(z == tz.UTCTimeZone)

// Output:
// true
}

func ExampleTimeZone_MarshalText() {
z, _ := tz.LoadTimeZone("Asia/Tokyo")
z := tz.MustLoadTimeZone("Asia/Tokyo")
text, _ := z.MarshalText()
fmt.Println(string(text))

Expand All @@ -103,7 +111,10 @@ func ExampleTimeZone_MarshalJSON() {
TimeZone tz.TimeZone `json:"time_zone"`
}

e := Event{Name: "Meeting", TimeZone: func() tz.TimeZone { z, _ := tz.LoadTimeZone("Europe/London"); return z }()}
e := Event{
Name: "Meeting",
TimeZone: tz.MustLoadTimeZone("Europe/London"),
}

data, err := json.Marshal(e)
if err != nil {
Expand Down
55 changes: 55 additions & 0 deletions time_zone_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,61 @@ func TestLoadTimeZone(t *testing.T) {
}
}

func TestMustLoadTimeZone(t *testing.T) {
t.Parallel()

tests := []struct {
testName string
name string
want tz.TimeZone
wantPanic bool
}{
{
testName: "Empty",
name: "",
want: tz.TimeZone{},
wantPanic: false,
},
{
testName: "UTC",
name: "UTC",
want: tz.TimeZone{},
wantPanic: false,
},
{
testName: "America/New_York",
name: "America/New_York",
want: mustLoadTimeZone(t, "America/New_York"),
wantPanic: false,
},
{
testName: "Local",
name: "Local",
wantPanic: true,
},
{
testName: "InvalidName",
name: "Invalid/Zone",
wantPanic: true,
},
}
for _, tt := range tests {
t.Run(tt.testName, func(t *testing.T) {
t.Parallel()

if tt.wantPanic {
assert.Panics(t, func() {
tz.MustLoadTimeZone(tt.name)
})

return
}

assert.Equal(t, tt.want, tz.MustLoadTimeZone(tt.name))
})
}
}

func TestTimeZone_Location_ZeroValueReturnUTC(t *testing.T) {
t.Parallel()
assert.Same(t, tz.TimeZone{}.Location(), time.UTC)
Expand Down
Loading