fix(time): midnight timezone conversion bug eliminated

This commit is contained in:
Steffen Jost 2023-09-20 11:14:47 +00:00
parent 520e649fc8
commit dfa07a95eb
5 changed files with 10 additions and 9 deletions

View File

@ -62,7 +62,7 @@ localTimeToUTC = TZ.localTimeToUTCFull appTZ
localTimeToUTCSimple :: LocalTime -> UTCTime localTimeToUTCSimple :: LocalTime -> UTCTime
localTimeToUTCSimple = TZ.localTimeToUTCTZ appTZ localTimeToUTCSimple = TZ.localTimeToUTCTZ appTZ
-- | Local midnight of given day -- | Local midnight of given day; use Utils.DateTime.utctDayMidnight :: Day -> UTCTime instead to avoid Timezone conversion!
toMidnight :: Day -> UTCTime toMidnight :: Day -> UTCTime
toMidnight = toTimeOfDay 0 0 0 toMidnight = toTimeOfDay 0 0 0

View File

@ -17,7 +17,6 @@ import qualified Data.Text as Text
import qualified Database.Esqueleto.Experimental as E -- might need TypeApplications Lang-Pragma import qualified Database.Esqueleto.Experimental as E -- might need TypeApplications Lang-Pragma
import qualified Database.Esqueleto.Utils as E import qualified Database.Esqueleto.Utils as E
import Handler.Utils.DateTime (toMidnight)
import Handler.Utils.Widgets (statusHtml) import Handler.Utils.Widgets (statusHtml)
statusQualificationBlock :: Bool -> Html statusQualificationBlock :: Bool -> Html
@ -152,7 +151,7 @@ upsertQualificationUser qualificationUserQualification qualificationUserLastRef
QualificationUser QualificationUser
{ qualificationUserFirstHeld = qualificationUserLastRefresh { qualificationUserFirstHeld = qualificationUserLastRefresh
, qualificationUserScheduleRenewal = fromMaybe True mbScheduleRenewal , qualificationUserScheduleRenewal = fromMaybe True mbScheduleRenewal
, qualificationUserLastNotified = toMidnight qualificationUserLastRefresh , qualificationUserLastNotified = utctDayMidnight qualificationUserLastRefresh
, .. , ..
} }
( (

View File

@ -410,7 +410,7 @@ dispatchJobLmsResults qid = JobHandlerAtomic act
update luid update luid
[ LmsUserStatus =. Just LmsSuccess [ LmsUserStatus =. Just LmsSuccess
, LmsUserStatusDay =. Just (toMidnight lmsResultSuccess) , LmsUserStatusDay =. Just (utctDayMidnight lmsResultSuccess)
, LmsUserReceived =. Just lmsResultTimestamp , LmsUserReceived =. Just lmsResultTimestamp
] ]
return Nothing return Nothing
@ -422,7 +422,7 @@ dispatchJobLmsResults qid = JobHandlerAtomic act
audit TransactionLmsSuccess -- always log success, since this is only transmitted once audit TransactionLmsSuccess -- always log success, since this is only transmitted once
{ transactionQualification = qid { transactionQualification = qid
, transactionLmsIdent = lmsUserIdent , transactionLmsIdent = lmsUserIdent
, transactionLmsDay = toMidnight lmsResultSuccess , transactionLmsDay = utctDayMidnight lmsResultSuccess
, transactionLmsUser = lmsUserUser , transactionLmsUser = lmsUserUser
, transactionNote = note , transactionNote = note
, transactionReceived = lmsResultTimestamp , transactionReceived = lmsResultTimestamp

View File

@ -159,9 +159,6 @@ instance Csv.FromField LmsTimestamp where
parseField i = do parseField i = do
s <- Csv.parseField i s <- Csv.parseField i
d <- Time.parseTimeM True Time.defaultTimeLocale lmsTimestampFormat s d <- Time.parseTimeM True Time.defaultTimeLocale lmsTimestampFormat s
<|> (toMidnight <$> Time.parseTimeM True Time.defaultTimeLocale lmsDayFormat s) <|> (utctDayMidnight <$> Time.parseTimeM True Time.defaultTimeLocale lmsDayFormat s)
<|> iso8601ParseM s -- Know-How AG considers supplying iso8601 dates in the future <|> iso8601ParseM s -- Know-How AG considers supplying iso8601 dates in the future
return $ LmsTimestamp d return $ LmsTimestamp d
where
toMidnight :: Day -> UTCTime
toMidnight d = UTCTime { utctDay = d, utctDayTime = toEnum 0 }

View File

@ -19,6 +19,7 @@ module Utils.DateTime
, diffMinute, diffHour, diffDay , diffMinute, diffHour, diffDay
, module Zones , module Zones
, day , day
, utctDayMidnight
) where ) where
import ClassyPrelude.Yesod hiding (lift, Proxy(..)) import ClassyPrelude.Yesod hiding (lift, Proxy(..))
@ -181,3 +182,7 @@ day = QuasiQuoter{..}
quoteType = error "day used as type" quoteType = error "day used as type"
quoteDec = error "day used as declaration" quoteDec = error "day used as declaration"
quoteExp dStr = maybe (fail $ "Could not parse ISO8601 day: “" <> dStr <> "") (lift :: Day -> Q Exp) $ Time.iso8601ParseM dStr quoteExp dStr = maybe (fail $ "Could not parse ISO8601 day: “" <> dStr <> "") (lift :: Day -> Q Exp) $ Time.iso8601ParseM dStr
-- | use Handler.Utils.DateTime.toMidnight instead, if the local timezone is to be accounted for
utctDayMidnight :: Day -> UTCTime
utctDayMidnight d = UTCTime { utctDayTime = 0, utctDay = d }