Browse Source

add new test, better fail-check, and non-transitioning tz fix

Colin Davidson 9 months ago
parent
commit
c9158b3220

+ 16 - 0
core/time/timezone/tz_windows.odin

@@ -203,6 +203,22 @@ generate_rrule_from_tzi :: proc(tzi: ^REG_TZI_FORMAT, abbrevs: TZ_Abbrev, alloca
 	if err != nil { return }
 	if err != nil { return }
 	defer if err != nil { delete(std_name, allocator) }
 	defer if err != nil { delete(std_name, allocator) }
 
 
+	if (tzi.std_date.month == 0) {
+		return datetime.TZ_RRule{
+			has_dst = false,
+
+			std_name = std_name,
+			std_offset = -(i64(tzi.bias) + i64(tzi.std_bias)) * 60,
+			dst_date = datetime.TZ_Transition_Date{
+				type = .Month_Week_Day,
+				month = u8(tzi.std_date.month),
+				week = u8(tzi.std_date.day),
+				day = tzi.std_date.day_of_week,
+				time = (i64(tzi.std_date.hour) * 60 * 60) + (i64(tzi.std_date.minute) * 60) + i64(tzi.std_date.second),
+			}
+		}, true
+	}
+
 	dst_name: string
 	dst_name: string
 	dst_name, err = strings.clone(abbrevs.dst, allocator)
 	dst_name, err = strings.clone(abbrevs.dst, allocator)
 	if err != nil { return }
 	if err != nil { return }

+ 2 - 0
core/time/timezone/tzdate.odin

@@ -93,6 +93,8 @@ trans_date_to_seconds :: proc(year: i64, td: datetime.TZ_Transition_Date) -> (se
 
 
 	switch td.type {
 	switch td.type {
 	case .Month_Week_Day:
 	case .Month_Week_Day:
+		if td.month < 1 { return }
+
 		t += month_to_seconds(int(td.month) - 1, is_leap)
 		t += month_to_seconds(int(td.month) - 1, is_leap)
 
 
 		weekday := ((t + (4 * DAY_SEC)) %% (7 * DAY_SEC)) / DAY_SEC
 		weekday := ((t + (4 * DAY_SEC)) %% (7 * DAY_SEC)) / DAY_SEC

+ 14 - 0
tests/core/time/test_core_time.odin

@@ -561,3 +561,17 @@ test_check_timezone_posix_tz :: proc(t: ^testing.T) {
 	defer tz.rrule_destroy(wgt_rrule)
 	defer tz.rrule_destroy(wgt_rrule)
 	testing.expectf(t, rrule_eq(wgt_rrule, correct_wgt_rrule), "POSIX TZ parsed incorrectly")
 	testing.expectf(t, rrule_eq(wgt_rrule, correct_wgt_rrule), "POSIX TZ parsed incorrectly")
 }
 }
+
+@test
+test_check_timezone_edgecases :: proc(t: ^testing.T) {
+	utc_dt, _ := dt.components_to_datetime(2024, 10, 4, 0, 47, 0)
+
+	tok_tz, tok_load_ok := tz.region_load("Asia/Tokyo")
+	testing.expectf(t, tok_load_ok, "Failed to load Asia/Tokyo timezone")
+	defer tz.region_destroy(tok_tz)
+
+	ret_dt := tz.datetime_to_tz(utc_dt, tok_tz)
+	expected_tok_dt, _ := dt.components_to_datetime(2024, 10, 4, 9, 47, 0)
+
+	testing.expectf(t, datetime_eq(ret_dt, expected_tok_dt), "Failed to convert to Tokyo time")
+}