serokell / tzbot

Timezone bot for Slack
Mozilla Public License 2.0
7 stars 2 forks source link

Convert time references to UTC #2

Closed dcastro closed 1 year ago

dcastro commented 2 years ago

Clarification and motivation

Implement the timeReferenceToUTC function.

Given a TimeReference (see #1 for examples), we want to convert it to a moment in time expressed in UTC.

For example, if:

The result of timeReferenceToUTC should be 2022-05-01 23:00 UTC.

import Data.Time.Format.ISO8601
import Data.Time.LocalTime
import qualified Data.Time.Zones as TZ
import qualified Data.Time.Zones.All as TZ

λ> iso8601ParseM @_ @LocalTime "2022-05-02T08:00:00" <&> TZ.localTimeToUTCFull (TZ.tzByLabel TZ.Asia__Tokyo)
LTUUnique {_ltuResult = 2022-05-01 23:00:00 UTC, _ltuZone = JST}

When there is no LocationReference (as in the example above), we should assume the time reference is relative to the sender's timezone.

When there is no DateReference, TimeReference (TimeOfDay 10 0 0) Nothing Nothing should be interpreted as "10:00 in the current day in the given timezone". If it's already past 10:00 in the given timezone, it should be interpreted as "10:00 the next day in the given timezone".

When DateReference is DaysFromToday n, we should interpret that as n days from the current date in the given timezone.

When DateReference is a day of the week, e.g. Tuesday, it should be interpreted as the next tuesday (or today, if today is tuesday in the given timezone).


Be aware that:

  1. Some date/times are ambiguous (see Edge cases & pitfalls for more details). When this happens, timeReferenceToUTC should return TRTUAmbiguous
  2. Some date/times are invalid. When this happens, it should return TRTUInvalid
  3. If the sender uses a timezone abbreviation that we don't support / doesn't exist (e.g. "10am in XYZ"), it should return TRTUInvalidTimeZoneAbbrev.

Acceptance criteria

YuriRomanowski commented 1 year ago

When there is no DateReference, TimeReference (TimeOfDay 10 0 0) Nothing Nothing should be interpreted as "10:00 in the current day in the given timezone". If it's already past 10:00 in the given timezone, it should be interpreted as "10:00 the next day in the given timezone".

Often when there is no DateReference, we can't know it for sure what day is meant, so in the ephemeral messages we shouldn't mention the concrete day, I think. But still, we need to recalculate the time, and we need to use some day for this, in this case using this/next day for recalculating implicitly is OK, I think. But we need to distinguish between the day clearly specified by the sender and the day assumed implicitly.