diff --git a/lib/std/time/datetime.c3 b/lib/std/time/datetime.c3 index 247242137..585b9b17b 100644 --- a/lib/std/time/datetime.c3 +++ b/lib/std/time/datetime.c3 @@ -105,7 +105,8 @@ fn TzDateTime DateTime.to_gmt_offset(self, int gmt_offset) * @ensure self.time == return.time **/ fn TzDateTime TzDateTime.to_gmt_offset(self, int gmt_offset) { - Time time = self.time + (Time)(gmt_offset - self.gmt_offset) * (Time)time::SEC; + if (self.gmt_offset == gmt_offset) return self; + Time time = self.time + (Time)gmt_offset * (Time)time::SEC; DateTime dt = from_time(time); dt.time = self.time; return { dt, gmt_offset }; diff --git a/test/unit/stdlib/time/datetime.c3 b/test/unit/stdlib/time/datetime.c3 index 315e1b5ea..81770a83e 100644 --- a/test/unit/stdlib/time/datetime.c3 +++ b/test/unit/stdlib/time/datetime.c3 @@ -49,6 +49,9 @@ fn void test_timezone() int offset_hours = 7; int offset = offset_hours * 3600; + int target_offset_hours = -4; + int target_offset = target_offset_hours * 3600; + DateTime d1 = datetime::from_date(2022, OCTOBER, 15); TzDateTime d2 = datetime::from_date_tz(2022, OCTOBER, 15, gmt_offset: offset); @@ -127,4 +130,22 @@ fn void test_timezone() assert(tz.day == 15); assert(tz.hour == 0); assert(tz.gmt_offset == offset); + + // Conversion from GMT+7 to GMT-4 + tz = d2.to_gmt_offset(target_offset); + assert(tz.year == d2.year); + assert(tz.month == d2.month); + assert(tz.day == d2.day - 1); + assert(tz.hour == 24 - (offset_hours - target_offset_hours)); + assert(tz.time == t2); + assert(tz.gmt_offset == target_offset); + + // Conversion with the same offset + tz = d2.to_gmt_offset(offset); + assert(tz.year == d2.year); + assert(tz.month == d2.month); + assert(tz.day == d2.day); + assert(tz.hour == d2.hour); + assert(tz.time == t2); + assert(tz.gmt_offset == offset); }