| package datetime |
|
|
| import ( |
| "testing" |
| "time" |
|
|
| "github.com/stretchr/testify/assert" |
| ) |
|
|
| func TestParseRFC9557(t *testing.T) { |
| tests := []struct { |
| name string |
| input string |
| wantTime time.Time |
| wantErr bool |
| }{ |
| { |
| name: "RFC9557 with America/New_York summer time", |
| input: "2021-07-01T12:34:56-04:00[America/New_York]", |
| wantTime: time.Date(2021, 7, 1, 12, 34, 56, 0, MustLoadLocation(t, "America/New_York")), |
| wantErr: false, |
| }, |
| { |
| name: "RFC9557 with America/New_York winter time", |
| input: "2021-12-01T12:34:56-05:00[America/New_York]", |
| wantTime: time.Date(2021, 12, 1, 12, 34, 56, 0, MustLoadLocation(t, "America/New_York")), |
| wantErr: false, |
| }, |
| { |
| name: "RFC9557 with Europe/Berlin", |
| input: "2021-07-01T18:34:56+02:00[Europe/Berlin]", |
| wantTime: time.Date(2021, 7, 1, 18, 34, 56, 0, MustLoadLocation(t, "Europe/Berlin")), |
| wantErr: false, |
| }, |
| { |
| name: "RFC9557 with Asia/Tokyo", |
| input: "2021-07-01T21:34:56+09:00[Asia/Tokyo]", |
| wantTime: time.Date(2021, 7, 1, 21, 34, 56, 0, MustLoadLocation(t, "Asia/Tokyo")), |
| wantErr: false, |
| }, |
| { |
| name: "RFC9557 with UTC timezone", |
| input: "2021-07-01T16:34:56Z[UTC]", |
| wantTime: time.Date(2021, 7, 1, 16, 34, 56, 0, time.UTC), |
| wantErr: false, |
| }, |
| { |
| name: "RFC9557 with fractional seconds", |
| input: "2021-07-01T12:34:56.123456789-04:00[America/New_York]", |
| wantTime: time.Date(2021, 7, 1, 12, 34, 56, 123456789, MustLoadLocation(t, "America/New_York")), |
| wantErr: false, |
| }, |
|
|
| { |
| name: "standard RFC3339 without timezone suffix", |
| input: "2021-07-01T16:34:56Z", |
| wantTime: time.Date(2021, 7, 1, 16, 34, 56, 0, time.UTC), |
| wantErr: false, |
| }, |
| { |
| name: "standard RFC3339 with offset, no suffix", |
| input: "2021-07-01T12:34:56-04:00", |
| wantTime: time.Date(2021, 7, 1, 12, 34, 56, 0, time.FixedZone("", -4*3600)), |
| wantErr: false, |
| }, |
| { |
| name: "ISO8601 with fractional seconds", |
| input: "2156-10-05T18:36:46.924Z", |
| wantTime: time.Date(2156, 10, 5, 18, 36, 46, 924000000, time.UTC), |
| wantErr: false, |
| }, |
| { |
| name: "ISO8601 format without timezone suffix", |
| input: "2021-07-01T16:34:56Z", |
| wantTime: time.Date(2021, 7, 1, 16, 34, 56, 0, time.UTC), |
| wantErr: false, |
| }, |
| { |
| name: "ISO8601 with milliseconds", |
| input: "2021-07-01T16:34:56.123Z", |
| wantTime: time.Date(2021, 7, 1, 16, 34, 56, 123000000, time.UTC), |
| wantErr: false, |
| }, |
| { |
| name: "ISO8601 with microseconds", |
| input: "2021-07-01T16:34:56.123456Z", |
| wantTime: time.Date(2021, 7, 1, 16, 34, 56, 123456000, time.UTC), |
| wantErr: false, |
| }, |
|
|
| |
| { |
| name: "invalid timezone in suffix", |
| input: "2021-07-01T12:34:56-04:00[Invalid/Timezone]", |
| wantTime: time.Time{}, |
| wantErr: true, |
| }, |
| { |
| name: "malformed timestamp", |
| input: "invalid-timestamp[America/New_York]", |
| wantTime: time.Time{}, |
| wantErr: true, |
| }, |
| { |
| name: "missing closing bracket", |
| input: "2021-07-01T12:34:56-04:00[America/New_York", |
| wantTime: time.Time{}, |
| wantErr: true, |
| }, |
| { |
| name: "missing opening bracket", |
| input: "2021-07-01T12:34:56-04:00America/New_York]", |
| wantTime: time.Time{}, |
| wantErr: true, |
| }, |
| { |
| name: "empty timezone suffix", |
| input: "2021-07-01T12:34:56-04:00[]", |
| wantTime: time.Time{}, |
| wantErr: true, |
| }, |
| { |
| name: "brackets not at end", |
| input: "2021-07-01T12:34:56-04:00[America/New_York]extra", |
| wantTime: time.Time{}, |
| wantErr: true, |
| }, |
| { |
| name: "nested brackets - malformed", |
| input: "2021-07-01T12:34:56-04:00[America/[nested]New_York]", |
| wantTime: time.Time{}, |
| wantErr: true, |
| }, |
| { |
| name: "multiple bracket pairs", |
| input: "2021-07-01T12:34:56-04:00[first][America/New_York]", |
| wantTime: time.Time{}, |
| wantErr: true, |
| }, |
| { |
| name: "only opening bracket", |
| input: "2021-07-01T12:34:56-04:00[America/New_York", |
| wantTime: time.Time{}, |
| wantErr: true, |
| }, |
| { |
| name: "only closing bracket", |
| input: "2021-07-01T12:34:56-04:00America/New_York]", |
| wantTime: time.Time{}, |
| wantErr: true, |
| }, |
| { |
| name: "empty string", |
| input: "", |
| wantTime: time.Time{}, |
| wantErr: true, |
| }, |
| { |
| name: "very short timestamp with brackets", |
| input: "2021[UTC]", |
| wantTime: time.Time{}, |
| wantErr: true, |
| }, |
| { |
| name: "timezone with special characters", |
| input: "2021-07-01T12:34:56-04:00[America/New_York-Test]", |
| wantTime: time.Time{}, |
| wantErr: true, |
| }, |
| } |
|
|
| for _, tt := range tests { |
| t.Run(tt.name, func(t *testing.T) { |
| got, err := Parse(tt.input) |
|
|
| if tt.wantErr { |
| assert.Error(t, err, "expected error for input: %s", tt.input) |
| return |
| } |
|
|
| assert.NoError(t, err, "expected no error for input: %s, got: %v", tt.input, err) |
| assert.True(t, got.Equal(tt.wantTime), "parsed time mismatch: got %v, want %v", got, tt.wantTime) |
| }) |
| } |
| } |
|
|