From 6cce0740ee09794d36e5a7e1ef1545e6447cd520 Mon Sep 17 00:00:00 2001 From: Bodigrim Date: Fri, 9 Jan 2026 21:27:58 +0000 Subject: [PATCH] Workaround DST issues in `toClockTime . toUTCTime`, at least in some cases To add months and years `addToClockTime` converts clock time to calendar time and then back. As reported at https://github.com/haskell/old-time/issues/18, there seems to be some issues with accounting for daylight saving time, which manifest themselves in `addToClockTime noTimeDiff` actually shifting the time by one hour. The implementation of `toClockTime` certainly takes shortcuts, but I'd rather not to touch it, there is not enough test coverage. Instead this patch implements a workaround, eliminating the issue in many practical scenarios: if months and years to be added are zero then just skip conversion to calendar time and back. --- System/Time.hsc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/System/Time.hsc b/System/Time.hsc index 0ea4338..f836349 100644 --- a/System/Time.hsc +++ b/System/Time.hsc @@ -280,7 +280,9 @@ addToClockTime (TimeDiff year mon day hour minute sec psec) 3600 * toInteger hour + 24 * 3600 * toInteger day (d_sec, d_psec) = (c_psec + psec) `quotRem` 1000000000000 - cal = toUTCTime (TOD (c_sec + sec_diff + d_sec) d_psec) + + beforeAddingMonthsAndYears = TOD (c_sec + sec_diff + d_sec) d_psec + cal = toUTCTime beforeAddingMonthsAndYears new_mon = fromEnum (ctMonth cal) + r_mon month' = fst tmp yr_diff = snd tmp @@ -293,7 +295,9 @@ addToClockTime (TimeDiff year mon day hour minute sec psec) year' = ctYear cal + year + r_yr + yr_diff in - toClockTime cal{ctMonth=month', ctYear=year'} + if year == 0 && mon == 0 + then beforeAddingMonthsAndYears + else toClockTime cal{ctMonth=month', ctYear=year'} -- | @'diffClockTimes' t1 t2@ returns the difference between two clock -- times @t1@ and @t2@ as a 'TimeDiff'.