1package ztime 2 3import ( 4 "fmt" 5 "strings" 6 "testing" 7 "time" 8 9 "zgo.at/zstd/ztest" 10) 11 12func TestNew(t *testing.T) { 13 tz, err := time.LoadLocation("Asia/Makassar") 14 _ = tz 15 if err != nil { 16 t.Fatal(err) 17 } 18 tests := []struct { 19 in string 20 want time.Time 21 }{ 22 {"2020-06-18 14:15:16.999999999", time.Date(2020, 6, 18, 14, 15, 16, 999999999, time.UTC)}, 23 {"2020-06-18 14:15:16.0", time.Date(2020, 6, 18, 14, 15, 16, 0, time.UTC)}, 24 {"2020-06-18 14:15:16", time.Date(2020, 6, 18, 14, 15, 16, 0, time.UTC)}, 25 {"2020-06-18 14:15", time.Date(2020, 6, 18, 14, 15, 0, 0, time.UTC)}, 26 {"2020-06-18 14", time.Date(2020, 6, 18, 14, 0, 0, 0, time.UTC)}, 27 {"2020-06-18", time.Date(2020, 6, 18, 0, 0, 0, 0, time.UTC)}, 28 {"2020-06", time.Date(2020, 6, 1, 0, 0, 0, 0, time.UTC)}, 29 {"2020", time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC)}, 30 31 // {"2020-06-18 14:15:16.999999999 WITA", time.Date(2020, 6, 18, 14, 15, 16, 999999999, tz)}, 32 // {"2020-06-18 14:15:16.0 WITA", time.Date(2020, 6, 18, 14, 15, 16, 0, tz)}, 33 // {"2020-06-18 14:15:16 WITA", time.Date(2020, 6, 18, 14, 15, 16, 0, tz)}, 34 // {"2020-06-18 14:15 WITA", time.Date(2020, 6, 18, 14, 15, 0, 0, tz)}, 35 // {"2020-06-18 14 WITA", time.Date(2020, 6, 18, 14, 0, 0, 0, tz)}, 36 // {"2020-06-18 WITA", time.Date(2020, 6, 18, 0, 0, 0, 0, tz)}, 37 // {"2020-06 WITA", time.Date(2020, 6, 1, 0, 0, 0, 0, tz)}, 38 // {"2020 WITA", time.Date(2020, 1, 1, 0, 0, 0, 0, tz)}, 39 } 40 41 for _, tt := range tests { 42 t.Run("", func(t *testing.T) { 43 have := New(tt.in) 44 if !have.Equal(tt.want) { 45 t.Errorf("\nhave: %s\nwant: %s", have, tt.want) 46 } 47 }) 48 } 49} 50 51func TestStartOf(t *testing.T) { 52 var ( 53 periods = []Period{Second, Minute, QuarterHour, HalfHour, Hour, Day, WeekMonday, WeekSunday, Month, Quarter, HalfYear, Year} 54 f = "2006-01-02 15:04:05.999999999" 55 tt = Time{time.Date(2020, 6, 18, 14, 49, 20, 666, time.UTC)} 56 h = new(strings.Builder) 57 ) 58 h.WriteString(" StartOf: " + tt.Format(f) + "\n") 59 for _, p := range periods { 60 pad := strings.Repeat(" ", 14-len(p.String())) 61 fmt.Fprintln(h, p.String(), pad, 62 tt.StartOf(p).Format(f), 63 "", tt.StartOf(p).AddTime(-1).StartOf(p).Format(f), 64 "", tt.StartOf(p).AddTime(-1).StartOf(p).AddTime(-1).StartOf(p).Format(f), 65 "", tt.StartOf(p).AddTime(-1).StartOf(p).AddTime(-1).StartOf(p).AddTime(-1).StartOf(p).Format(f)) 66 } 67 68 have := h.String() 69 want := ` 70 StartOf: 2020-06-18 14:49:20.000000666 71 second 2020-06-18 14:49:20 2020-06-18 14:49:19 2020-06-18 14:49:18 2020-06-18 14:49:17 72 minute 2020-06-18 14:49:00 2020-06-18 14:48:00 2020-06-18 14:47:00 2020-06-18 14:46:00 73 quarter hour 2020-06-18 14:45:00 2020-06-18 14:30:00 2020-06-18 14:15:00 2020-06-18 14:00:00 74 half hour 2020-06-18 14:30:00 2020-06-18 14:00:00 2020-06-18 13:30:00 2020-06-18 13:00:00 75 hour 2020-06-18 14:00:00 2020-06-18 13:00:00 2020-06-18 12:00:00 2020-06-18 11:00:00 76 day 2020-06-18 00:00:00 2020-06-17 00:00:00 2020-06-16 00:00:00 2020-06-15 00:00:00 77 week (Monday) 2020-06-15 00:00:00 2020-06-08 00:00:00 2020-06-01 00:00:00 2020-05-25 00:00:00 78 week (Sunday) 2020-06-14 00:00:00 2020-06-07 00:00:00 2020-05-31 00:00:00 2020-05-24 00:00:00 79 month 2020-06-01 00:00:00 2020-05-01 00:00:00 2020-04-01 00:00:00 2020-03-01 00:00:00 80 quarter 2020-04-01 00:00:00 2020-01-01 00:00:00 2019-10-01 00:00:00 2019-07-01 00:00:00 81 half year 2020-01-01 00:00:00 2019-07-01 00:00:00 2019-01-01 00:00:00 2018-07-01 00:00:00 82 year 2020-01-01 00:00:00 2019-01-01 00:00:00 2018-01-01 00:00:00 2017-01-01 00:00:00` 83 if d := ztest.Diff(have, want, ztest.DiffNormalizeWhitespace); d != "" { 84 t.Error(d) 85 } 86} 87 88func TestEndOf(t *testing.T) { 89 var ( 90 periods = []Period{Second, Minute, QuarterHour, HalfHour, Hour, Day, WeekMonday, WeekSunday, Month, Quarter, HalfYear, Year} 91 f = "2006-01-02 15:04:05.999999999" 92 tt = Time{time.Date(2020, 6, 18, 14, 49, 20, 666, time.UTC)} 93 h = new(strings.Builder) 94 ) 95 h.WriteString("\n EndOf: " + tt.Format(f) + "\n") 96 for _, p := range periods { 97 pad := strings.Repeat(" ", 14-len(p.String())) 98 fmt.Fprintln(h, p.String(), pad, 99 tt.EndOf(p).Format(f), 100 "", tt.EndOf(p).AddTime(1).EndOf(p).Format(f), 101 "", tt.EndOf(p).AddTime(1).EndOf(p).AddTime(1).EndOf(p).Format(f), 102 "", tt.EndOf(p).AddTime(1).EndOf(p).AddTime(1).EndOf(p).AddTime(1).EndOf(p).Format(f)) 103 } 104 105 have := h.String() 106 want := ` 107 EndOf: 2020-06-18 14:49:20.000000666 108 second 2020-06-18 14:49:20.999999999 2020-06-18 14:49:21.999999999 2020-06-18 14:49:22.999999999 2020-06-18 14:49:23.999999999 109 minute 2020-06-18 14:49:59.999999999 2020-06-18 14:50:59.999999999 2020-06-18 14:51:59.999999999 2020-06-18 14:52:59.999999999 110 quarter hour 2020-06-18 14:59:59.999999999 2020-06-18 15:14:59.999999999 2020-06-18 15:29:59.999999999 2020-06-18 15:44:59.999999999 111 half hour 2020-06-18 14:59:59.999999999 2020-06-18 15:29:59.999999999 2020-06-18 15:59:59.999999999 2020-06-18 16:29:59.999999999 112 hour 2020-06-18 14:59:59.999999999 2020-06-18 15:59:59.999999999 2020-06-18 16:59:59.999999999 2020-06-18 17:59:59.999999999 113 day 2020-06-18 23:59:59.999999999 2020-06-19 23:59:59.999999999 2020-06-20 23:59:59.999999999 2020-06-21 23:59:59.999999999 114 week (Monday) 2020-06-21 23:59:59.999999999 2020-06-28 23:59:59.999999999 2020-07-05 23:59:59.999999999 2020-07-12 23:59:59.999999999 115 week (Sunday) 2020-06-20 23:59:59.999999999 2020-06-27 23:59:59.999999999 2020-07-04 23:59:59.999999999 2020-07-11 23:59:59.999999999 116 month 2020-06-30 23:59:59.999999999 2020-07-31 23:59:59.999999999 2020-08-31 23:59:59.999999999 2020-09-30 23:59:59.999999999 117 quarter 2020-06-30 23:59:59.999999999 2020-09-30 23:59:59.999999999 2020-12-31 23:59:59.999999999 2021-03-31 23:59:59.999999999 118 half year 2020-06-30 23:59:59.999999999 2020-12-31 23:59:59.999999999 2021-06-30 23:59:59.999999999 2021-12-31 23:59:59.999999999 119 year 2020-12-31 23:59:59.999999999 2021-12-31 23:59:59.999999999 2022-12-31 23:59:59.999999999 2023-12-31 23:59:59.999999999` 120 if d := ztest.Diff(have, want, ztest.DiffNormalizeWhitespace); d != "" { 121 t.Error(d) 122 } 123} 124 125func TestWeek(t *testing.T) { 126 var ( 127 mon = Time{time.Date(2021, 4, 5, 14, 49, 20, 666, time.UTC)} 128 sun = Time{time.Date(2021, 4, 4, 14, 49, 20, 666, time.UTC)} 129 f = "Mon Jan _2" 130 h = new(strings.Builder) 131 ) 132 133 h.WriteString("Monday:\n") 134 for i := 0; i < 7; i++ { 135 fmt.Fprintf(h, "%d %s → %s %s\n", i, mon.Add(i, Day).Format(f), 136 mon.Add(i, Day).StartOf(Week(false)).Format(f), 137 mon.Add(i, Day).EndOf(Week(false)).Format(f)) 138 } 139 h.WriteString("\nSunday:\n") 140 for i := 0; i < 7; i++ { 141 fmt.Fprintf(h, "%d %s → %s %s\n", i, sun.Add(i, Day).Format(f), 142 sun.Add(i, Day).StartOf(Week(true)).Format(f), 143 sun.Add(i, Day).EndOf(Week(true)).Format(f)) 144 } 145 146 have := h.String() 147 want := ` 148 Monday: 149 0 Mon Apr 5 → Mon Apr 5 Sun Apr 11 150 1 Tue Apr 6 → Mon Apr 5 Sun Apr 11 151 2 Wed Apr 7 → Mon Apr 5 Sun Apr 11 152 3 Thu Apr 8 → Mon Apr 5 Sun Apr 11 153 4 Fri Apr 9 → Mon Apr 5 Sun Apr 11 154 5 Sat Apr 10 → Mon Apr 5 Sun Apr 11 155 6 Sun Apr 11 → Mon Apr 5 Sun Apr 11 156 157 Sunday: 158 0 Sun Apr 4 → Sun Apr 4 Sat Apr 10 159 1 Mon Apr 5 → Sun Apr 4 Sat Apr 10 160 2 Tue Apr 6 → Sun Apr 4 Sat Apr 10 161 3 Wed Apr 7 → Sun Apr 4 Sat Apr 10 162 4 Thu Apr 8 → Sun Apr 4 Sat Apr 10 163 5 Fri Apr 9 → Sun Apr 4 Sat Apr 10 164 6 Sat Apr 10 → Sun Apr 4 Sat Apr 10` 165 if d := ztest.Diff(have, want, ztest.DiffNormalizeWhitespace); d != "" { 166 t.Error(d) 167 } 168} 169 170func TestAdd(t *testing.T) { 171 tests := []struct { 172 in string 173 n int 174 p Period 175 want string 176 }{ 177 {"2021-06-18 12:12:12", 1, Second, "2021-06-18 12:12:13"}, 178 {"2021-06-18 12:12:12", -1, Second, "2021-06-18 12:12:11"}, 179 {"2021-06-18 12:12:12", 61, Second, "2021-06-18 12:13:13"}, 180 181 {"2021-06-18 12:12:12", 1, Minute, "2021-06-18 12:13:12"}, 182 {"2021-06-18 12:12:12", -1, Minute, "2021-06-18 12:11:12"}, 183 184 {"2021-06-18 12:12:12", 1, QuarterHour, "2021-06-18 12:27:12"}, 185 {"2021-06-18 12:12:12", -1, QuarterHour, "2021-06-18 11:57:12"}, 186 187 {"2021-06-18 12:12:12", 1, HalfHour, "2021-06-18 12:42:12"}, 188 {"2021-06-18 12:12:12", -1, HalfHour, "2021-06-18 11:42:12"}, 189 190 {"2021-06-18 12:12:12", 1, Hour, "2021-06-18 13:12:12"}, 191 {"2021-06-18 12:12:12", -1, Hour, "2021-06-18 11:12:12"}, 192 193 {"2021-06-18", 1, Day, "2021-06-19"}, 194 {"2021-06-18", -1, Day, "2021-06-17"}, 195 {"2021-01-31", 1, Day, "2021-02-01"}, 196 197 {"2021-06-18", 1, WeekMonday, "2021-06-25"}, 198 {"2021-06-18", 1, WeekSunday, "2021-06-25"}, 199 {"2021-06-18", -1, WeekMonday, "2021-06-11"}, 200 {"2021-06-18", -1, WeekSunday, "2021-06-11"}, 201 202 {"2021-06-18", 1, Month, "2021-07-18"}, 203 {"2021-06-18", -1, Month, "2021-05-18"}, 204 {"2021-03-31", -1, Month, "2021-02-28"}, // Correct if number of days is less. 205 {"2021-03-31", 1, Month, "2021-04-30"}, 206 {"2021-01-31", 10, Month, "2021-11-30"}, 207 {"2020-03-31", -1, Month, "2020-02-29"}, // Leap year fun. 208 {"2020-02-29", 1, Month, "2020-03-29"}, 209 {"2020-02-29", -1, Month, "2020-01-29"}, 210 211 {"2021-06-18", 1, Quarter, "2021-09-18"}, 212 {"2021-06-18", -1, Quarter, "2021-03-18"}, 213 {"2021-01-31", 1, Quarter, "2021-04-30"}, // Fewer days. 214 {"2021-12-31", -1, Quarter, "2021-09-30"}, 215 {"2020-05-31", -1, Quarter, "2020-02-29"}, // Leap year 216 217 {"2021-06-18", 1, HalfYear, "2021-12-18"}, 218 {"2021-06-18", -1, HalfYear, "2020-12-18"}, 219 220 {"2021-06-18", 1, Year, "2022-06-18"}, 221 {"2021-06-18", -1, Year, "2020-06-18"}, 222 {"2020-02-29", 1, Year, "2021-02-28"}, // Leap year 223 {"2020-02-29", -1, Year, "2019-02-28"}, 224 } 225 226 for _, tt := range tests { 227 t.Run(fmt.Sprintf("%+d %s", tt.n, tt.p), func(t *testing.T) { 228 have := Add(New(tt.in), tt.n, tt.p) 229 want := New(tt.want) 230 if !have.Equal(want) { 231 t.Errorf("\nhave: %s\nwant: %s", have, want) 232 } 233 }) 234 } 235} 236