github.com/Aoi-hosizora/ahlib@v1.5.1-0.20230404072829-241b93cf91c7/xtime/xtime_test.go (about) 1 package xtime 2 3 import ( 4 "fmt" 5 "github.com/Aoi-hosizora/ahlib/xtesting" 6 "testing" 7 "time" 8 ) 9 10 func TestSetXXX(t *testing.T) { 11 now := time.Date(2020, time.Month(9), 30, 23, 39, 18, 789, time.FixedZone("", 8*60*60)) 12 zero := time.Time{} 13 14 for _, tc := range []struct { 15 giveFn1 func() time.Time 16 giveFn2 func() 17 want string 18 }{ 19 {nil, func() {}, "0001-01-01T00:00:00Z"}, 20 21 {func() time.Time { return SetYear(zero, now.Year()) }, nil, "2020-01-01T00:00:00Z"}, 22 {func() time.Time { return SetMonth(zero, int(now.Month())) }, nil, "0001-09-01T00:00:00Z"}, 23 {func() time.Time { return SetDay(zero, now.Day()) }, nil, "0001-01-30T00:00:00Z"}, 24 {func() time.Time { return SetHour(zero, now.Hour()) }, nil, "0001-01-01T23:00:00Z"}, 25 {func() time.Time { return SetMinute(zero, now.Minute()) }, nil, "0001-01-01T00:39:00Z"}, 26 {func() time.Time { return SetSecond(zero, now.Second()) }, nil, "0001-01-01T00:00:18Z"}, 27 {func() time.Time { return SetMillisecond(zero, 123) }, nil, "0001-01-01T00:00:00.123Z"}, 28 {func() time.Time { return SetMicrosecond(zero, 123456) }, nil, "0001-01-01T00:00:00.123456Z"}, 29 {func() time.Time { return SetNanosecond(zero, 123456789) }, nil, "0001-01-01T00:00:00.123456789Z"}, 30 {func() time.Time { return SetLocation(zero, now.Location()) }, nil, "0001-01-01T00:00:00+08:00"}, 31 32 {nil, func() { zero = SetYear(zero, now.Year()) }, "2020-01-01T00:00:00Z"}, 33 {nil, func() { zero = SetMonth(zero, int(now.Month())) }, "2020-09-01T00:00:00Z"}, 34 {nil, func() { zero = SetDay(zero, now.Day()) }, "2020-09-30T00:00:00Z"}, 35 {nil, func() { zero = SetHour(zero, now.Hour()) }, "2020-09-30T23:00:00Z"}, 36 {nil, func() { zero = SetMinute(zero, now.Minute()) }, "2020-09-30T23:39:00Z"}, 37 {nil, func() { zero = SetSecond(zero, now.Second()) }, "2020-09-30T23:39:18Z"}, 38 {nil, func() { zero = SetMillisecond(zero, 123) }, "2020-09-30T23:39:18.123Z"}, 39 {nil, func() { zero = SetMicrosecond(zero, 123456) }, "2020-09-30T23:39:18.123456Z"}, 40 {nil, func() { zero = SetNanosecond(zero, now.Nanosecond()) }, "2020-09-30T23:39:18.000000789Z"}, 41 {nil, func() { zero = SetLocation(zero, now.Location()) }, "2020-09-30T23:39:18.000000789+08:00"}, 42 } { 43 if tc.giveFn1 != nil { 44 newTime := tc.giveFn1() 45 xtesting.Equal(t, newTime.Format(time.RFC3339Nano), tc.want) 46 } else { 47 tc.giveFn2() 48 xtesting.Equal(t, zero.Format(time.RFC3339Nano), tc.want) 49 } 50 } 51 52 xtesting.Equal(t, zero, now) 53 } 54 55 func TestToXXX(t *testing.T) { 56 now := time.Date(2020, time.Month(9), 30, 23, 39, 18, 789, time.FixedZone("test", 8*60*60)) 57 58 for _, tc := range []struct { 59 giveFn func() time.Time 60 wantTime time.Time 61 }{ 62 {func() time.Time { return ToDate(now) }, 63 time.Date(2020, time.Month(9), 30, 0, 0, 0, 0, time.FixedZone("", 8*60*60))}, 64 {func() time.Time { return ToDateTime(now) }, 65 time.Date(2020, time.Month(9), 30, 23, 39, 18, 0, time.FixedZone("", 8*60*60))}, 66 {func() time.Time { return ToDateTimeNS(now) }, 67 time.Date(2020, time.Month(9), 30, 23, 39, 18, 789, time.FixedZone("", 8*60*60))}, 68 } { 69 newTime := tc.giveFn() 70 xtesting.Equal(t, newTime.Year(), tc.wantTime.Year()) 71 xtesting.Equal(t, newTime.Month(), tc.wantTime.Month()) 72 xtesting.Equal(t, newTime.Day(), tc.wantTime.Day()) 73 xtesting.Equal(t, newTime.Hour(), tc.wantTime.Hour()) 74 xtesting.Equal(t, newTime.Minute(), tc.wantTime.Minute()) 75 xtesting.Equal(t, newTime.Second(), tc.wantTime.Second()) 76 xtesting.Equal(t, newTime.Nanosecond(), tc.wantTime.Nanosecond()) 77 xtesting.Equal(t, newTime.Location(), tc.wantTime.Location()) 78 } 79 } 80 81 func TestLocationDurationAndGetTimeLocation(t *testing.T) { 82 t1, _ := time.Parse(time.RFC3339, "2020-09-30T23:56:52Z") // UTC 83 t2, _ := time.Parse(time.RFC3339, "2020-09-30T23:56:52-07:00") // "" 84 t3, _ := time.Parse(CJKDateTime, "2020-09-30 23:56:52") // UTC 85 t4, _ := time.Parse(time.RFC3339, "2020-09-30T23:56:52+08:00") // Local 86 t5, _ := time.Parse(time.RFC3339, "2020-09-30T23:56:52+09:00") // "" 87 t6, _ := time.Parse(time.RFC3339, "2020-09-30T23:56:52-12:30") // "" 88 89 for _, tc := range []struct { 90 giveTime time.Time 91 wantDuration int 92 }{ 93 {t1, 0}, // +00:00 94 {t2, -7 * 3600}, // -07:00 95 {t3, 0}, // +00:00 96 {t4, 8 * 3600}, // +08:00 97 {t5, 9 * 3600}, // +09:00 98 {t6, -12*3600 - 30*60}, // -12:30 99 } { 100 duration := LocationDuration(tc.giveTime.Location()) 101 xtesting.Equal(t, int(duration.Seconds()), tc.wantDuration) 102 103 newLocation := GetTimeLocation(tc.giveTime) 104 xtesting.Equal(t, newLocation.String(), "") 105 newDuration := LocationDuration(newLocation) 106 xtesting.Equal(t, int(newDuration.Seconds()), tc.wantDuration) 107 } 108 109 loc := GetLocalLocation() 110 xtesting.Equal(t, loc.String(), "") 111 xtesting.Equal(t, loc, time.FixedZone("", int(LocationDuration(time.Local).Seconds()))) 112 } 113 114 func TestParseTimezone(t *testing.T) { 115 for _, tc := range []struct { 116 give string 117 want *time.Location 118 }{ 119 {"", nil}, 120 {"0", nil}, 121 {"09", nil}, 122 {"09:00", nil}, 123 {"+", nil}, 124 {"+0", time.FixedZone("UTC+00:00", 0)}, // +X 125 {"+09", time.FixedZone("UTC+09:00", 9*3600)}, // +XX 126 {"+009", nil}, 127 {"+09:", nil}, 128 {"-09", time.FixedZone("UTC-09:00", -9*3600)}, // -XX 129 {"-9:0", time.FixedZone("UTC-09:00", -9*3600)}, // -X:X 130 {"-9:00", time.FixedZone("UTC-09:00", -9*3600)}, // -X:XX 131 {"-09:0", time.FixedZone("UTC-09:00", -9*3600)}, // -XX:X 132 {"-09:30", time.FixedZone("UTC-09:30", -9*3600-30*60)}, // -XX:XX 133 {"-09:300", nil}, 134 } { 135 if tc.want == nil { 136 _, err := ParseTimezone(tc.give) 137 xtesting.NotNil(t, err) 138 } else { 139 loc, err := ParseTimezone(tc.give) 140 xtesting.Equal(t, loc, tc.want) 141 xtesting.Nil(t, err) 142 } 143 } 144 } 145 146 func TestTruncateTime(t *testing.T) { 147 for _, loc := range []*time.Location{ 148 time.UTC, 149 time.FixedZone("", 8*60*60), 150 time.FixedZone("", -9*60*60), 151 time.FixedZone("", -2*30*60), 152 } { 153 d1 := time.Date(2021, 12, 27, 23, 49, 57, 123456789, loc) 154 d2 := time.Date(2018, 5, 1, 3, 4, 6, 999000000, loc) 155 for _, tc := range []struct { 156 giveTime time.Time 157 giveDuration time.Duration 158 want time.Time 159 }{ 160 {d1, time.Nanosecond, time.Date(2021, 12, 27, 23, 49, 57, 123456789, loc)}, 161 {d1, time.Microsecond, time.Date(2021, 12, 27, 23, 49, 57, 123456000, loc)}, 162 {d1, time.Millisecond, time.Date(2021, 12, 27, 23, 49, 57, 123000000, loc)}, 163 {d1, time.Millisecond * 10, time.Date(2021, 12, 27, 23, 49, 57, 120000000, loc)}, 164 {d1, time.Second, time.Date(2021, 12, 27, 23, 49, 57, 0, loc)}, 165 {d1, time.Second * 2, time.Date(2021, 12, 27, 23, 49, 56, 0, loc)}, 166 {d1, time.Second * 5, time.Date(2021, 12, 27, 23, 49, 55, 0, loc)}, 167 {d1, time.Second * 10, time.Date(2021, 12, 27, 23, 49, 50, 0, loc)}, 168 {d1, time.Second * 20, time.Date(2021, 12, 27, 23, 49, 40, 0, loc)}, 169 {d1, time.Minute, time.Date(2021, 12, 27, 23, 49, 0, 0, loc)}, 170 {d1, time.Minute * 2, time.Date(2021, 12, 27, 23, 48, 0, 0, loc)}, 171 {d1, time.Minute * 5, time.Date(2021, 12, 27, 23, 45, 0, 0, loc)}, 172 {d1, time.Minute * 10, time.Date(2021, 12, 27, 23, 40, 0, 0, loc)}, 173 {d1, time.Minute * 20, time.Date(2021, 12, 27, 23, 40, 0, 0, loc)}, 174 // 175 {d2, time.Millisecond, time.Date(2018, 5, 1, 3, 4, 6, 999000000, loc)}, 176 {d2, time.Millisecond * 10, time.Date(2018, 5, 1, 3, 4, 6, 990000000, loc)}, 177 {d2, time.Second, time.Date(2018, 5, 1, 3, 4, 6, 0, loc)}, 178 {d2, time.Second * 2, time.Date(2018, 5, 1, 3, 4, 6, 0, loc)}, 179 {d2, time.Second * 20, time.Date(2018, 5, 1, 3, 4, 0, 0, loc)}, 180 {d2, time.Minute, time.Date(2018, 5, 1, 3, 4, 0, 0, loc)}, 181 {d2, time.Minute * 2, time.Date(2018, 5, 1, 3, 4, 0, 0, loc)}, 182 {d2, time.Minute * 20, time.Date(2018, 5, 1, 3, 0, 0, 0, loc)}, 183 // 184 {d1, time.Hour, time.Date(2021, 12, 27, 23, 0, 0, 0, loc)}, 185 {d1, time.Hour * 2, time.Date(2021, 12, 27, 22, 0, 0, 0, loc)}, 186 {d1, time.Hour * 3, time.Date(2021, 12, 27, 21, 0, 0, 0, loc)}, 187 {d1, time.Hour * 24, time.Date(2021, 12, 27, 0, 0, 0, 0, loc)}, 188 {d1, time.Hour * 24 * 2, time.Date(2021, 12, 27, 0, 0, 0, 0, loc)}, 189 {d1, time.Hour * 24 * 3, time.Date(2021, 12, 27, 0, 0, 0, 0, loc)}, 190 // 191 {d2, time.Hour, time.Date(2018, 5, 1, 3, 0, 0, 0, loc)}, 192 {d2, time.Hour * 2, time.Date(2018, 5, 1, 2, 0, 0, 0, loc)}, 193 {d2, time.Hour * 3, time.Date(2018, 5, 1, 3, 0, 0, 0, loc)}, 194 {d2, time.Hour * 24, time.Date(2018, 5, 1, 0, 0, 0, 0, loc)}, 195 {d2, time.Hour * 24 * 2, time.Date(2018, 5, 1, 0, 0, 0, 0, loc)}, 196 {d2, time.Hour * 24 * 3, time.Date(2018, 4, 29, 0, 0, 0, 0, loc)}, 197 } { 198 t.Run(fmt.Sprintf("%s_%s_%s", tc.giveTime.Format("20060102"), tc.giveDuration, LocationDuration(loc)), func(t *testing.T) { 199 xtesting.Equal(t, TruncateTime(tc.giveTime, tc.giveDuration), tc.want) 200 }) 201 } 202 } 203 } 204 205 func TestDurationComponent(t *testing.T) { 206 duration1 := 5*24*time.Hour + 5*time.Hour + 32*time.Minute + 24*time.Second + 123*time.Millisecond + 456*time.Microsecond + 789*time.Nanosecond 207 duration2 := 105 * 24 * time.Hour 208 duration3 := 24*time.Hour + 30*time.Minute + 1*time.Microsecond 209 duration4 := 5*time.Hour + 30*time.Minute + 1*time.Microsecond 210 duration5 := 0 * time.Second 211 212 for _, tc := range []struct { 213 give time.Duration 214 wantDay int 215 wantHour int 216 wantMinute int 217 wantSecond int 218 wantMs int 219 wantUs int 220 wantNs int 221 }{ 222 {duration1, 5, 5, 32, 24, 123, 456, 789}, 223 {duration2, 105, 0, 0, 0, 0, 0, 0}, 224 {duration3, 1, 0, 30, 0, 0, 1, 0}, 225 {duration4, 0, 5, 30, 0, 0, 1, 0}, 226 {duration5, 0, 0, 0, 0, 0, 0, 0}, 227 } { 228 xtesting.Equal(t, DurationDayComponent(tc.give), tc.wantDay) 229 xtesting.Equal(t, DurationHourComponent(tc.give), tc.wantHour) 230 xtesting.Equal(t, DurationMinuteComponent(tc.give), tc.wantMinute) 231 xtesting.Equal(t, DurationSecondComponent(tc.give), tc.wantSecond) 232 xtesting.Equal(t, DurationMillisecondComponent(tc.give), tc.wantMs) 233 xtesting.Equal(t, DurationMicrosecondComponent(tc.give), tc.wantUs) 234 xtesting.Equal(t, DurationNanosecondComponent(tc.give), tc.wantNs) 235 } 236 } 237 238 func TestDurationTotal(t *testing.T) { 239 duration1 := 5*24*time.Hour + 5*time.Hour + 32*time.Minute + 24*time.Second + 123*time.Millisecond + 456*time.Microsecond + 789*time.Nanosecond 240 duration2 := 105 * 24 * time.Hour 241 duration3 := 24*time.Hour + 30*time.Minute + 1*time.Microsecond 242 duration4 := 5*time.Hour + 30*time.Minute + 1*time.Microsecond 243 duration5 := 0 * time.Second 244 245 for _, tc := range []struct { 246 give time.Duration 247 wantDay float64 248 wantHour float64 249 wantMinute float64 250 wantSecond float64 251 wantMs int64 252 wantUs int64 253 wantNs int64 254 }{ 255 {duration1, 5.2308, 125.5400, 7532.4020, 451944.123456789, 451944123, 451944123456, 451944123456789}, 256 {duration2, 105, 2520, 151200, 9072000, 9072000000, 9072000000000, 9072000000000000}, 257 {duration3, 1.0208, 24.5, 1470., 88200., 88200000, 88200000001, 88200000001000}, 258 {duration4, 0.2292, 5.5, 330., 19800, 19800000, 19800000001, 19800000001000}, 259 {duration5, 0, 0, 0, 0, 0, 0, 0}, 260 } { 261 xtesting.Equal(t, DurationTotalNanoseconds(tc.give), tc.wantNs) 262 xtesting.Equal(t, DurationTotalMicroseconds(tc.give), tc.wantUs) 263 xtesting.Equal(t, DurationTotalMilliseconds(tc.give), tc.wantMs) 264 xtesting.InDelta(t, DurationTotalSeconds(tc.give), tc.wantSecond, 1e-3) 265 xtesting.InDelta(t, DurationTotalMinutes(tc.give), tc.wantMinute, 1e-3) 266 xtesting.InDelta(t, DurationTotalHours(tc.give), tc.wantHour, 1e-3) 267 xtesting.InDelta(t, DurationTotalDays(tc.give), tc.wantDay, 1e-3) 268 } 269 } 270 271 func TestClock(t *testing.T) { 272 xtesting.Equal(t, LocationDuration(UTC.Now().Location()), time.Duration(0)) 273 xtesting.Equal(t, LocationDuration(Local.Now().Location()), LocationDuration(time.Local)) 274 now := time.Date(2001, 1, 1, 0, 0, 0, 0, time.FixedZone("", 8*60*60)) 275 pNow := &now 276 clock := CustomClock(pNow) 277 xtesting.Equal(t, clock.Now(), time.Date(2001, 1, 1, 0, 0, 0, 0, time.FixedZone("", 8*60*60))) 278 *pNow = SetLocation(now, time.FixedZone("", -9*60*60)) 279 xtesting.Equal(t, clock.Now(), time.Date(2001, 1, 1, 0, 0, 0, 0, time.FixedZone("", -9*60*60))) 280 *pNow = SetYear(now, 2021) 281 *pNow = SetMonth(now, 12) 282 *pNow = SetDay(now, 30) 283 *pNow = SetLocation(now, time.UTC) 284 xtesting.Equal(t, clock.Now(), time.Date(2021, 12, 30, 0, 0, 0, 0, time.UTC)) 285 }