Skip to content
heff

std.offset

Offsets from UTC: how far a clock on the wall is ahead of UTC, or behind it, fixed — +08:00 in Taipei all year round, -05:00 in New York in winter — in whole seconds, within 18 hours either way. NodaTime’s Offset is the model. An offset is no time zone: a zone has rules for which offset it is at when, and an offset has none. A std.localdatetime at an offset is an instant, a std.offsetdatetime. Import it by a name, import std.offset as Offset, as its names are short.

import std.offset as Offset
-- | the offset of India
-- | >>> maybe "" show india
-- | "+05:30"
india : Maybe Offset.Offset
india = Offset.fromHoursAndMinutes 5 30

Offset

data Offset

An offset: its seconds ahead of UTC, -64800 to 64800, fewer than none for one behind it.

utc

utc : Offset

UTC’s own: none.

fromSeconds

fromSeconds : Int -> Maybe Offset

The offset n seconds ahead of UTC, behind it for fewer than none, if it is within 18 hours (64800 seconds) either way; nothing if not.

>>> List.map fromSeconds [0, 64800, -64800, 64801, -64801]
[Just (MkOffset 0), Just (MkOffset 64800), Just (MkOffset (-64800)), Nothing, Nothing]

fromHours

fromHours : Int -> Maybe Offset

The offset n hours ahead of UTC, behind it for fewer than none, if it is within 18 either way; nothing if not.

>>> List.map fromHours [8, -5, 18, -18, 19]
[Just (MkOffset 28800), Just (MkOffset (-18000)), Just (MkOffset 64800), Just (MkOffset (-64800)), Nothing]

fromHoursAndMinutes

fromHoursAndMinutes : Int -> Int -> Maybe Offset

The offset the hours and minutes ahead of UTC, the minutes 0 to 59 taking the hours’ sign: fromHoursAndMinutes (-3) 30 is -03:30, 3 hours and 30 minutes behind. Of the minutes, their size is taken and their own sign is not, but where the hours are 0: so fromHoursAndMinutes (-3) (-30) is -03:30 too, as NodaTime has it, fromHoursAndMinutes 3 (-30) is +03:30, and fromHoursAndMinutes 0 (-30) is -00:30. Nothing for minutes beyond 59 either way, or an offset beyond 18 hours.

>>> List.map (\p -> fromHoursAndMinutes (fst p) (snd p)) [(5, 30), (-3, 30), (-3, -30), (3, -30), (0, -30), (0, 45)]
[Just (MkOffset 19800), Just (MkOffset (-12600)), Just (MkOffset (-12600)), Just (MkOffset 12600), Just (MkOffset (-1800)), Just (MkOffset 2700)]
>>> List.map (\p -> fromHoursAndMinutes (fst p) (snd p)) [(18, 0), (-18, 0), (18, 1), (-17, 60), (1, -60)]
[Just (MkOffset 64800), Just (MkOffset (-64800)), Nothing, Nothing, Nothing]

totalSeconds

totalSeconds : Offset -> Int

Its seconds ahead of UTC, fewer than none for one behind it.

toDuration

toDuration : Offset -> Duration.Duration

How far ahead of UTC it is, as a duration.

>>> maybe "" (\o -> show (toDuration o)) (fromHoursAndMinutes (-9) 30)
"-9h30m0s"

instanceEqualityOffset

instance instanceEqualityOffset : Equality Offset

The same offset.

instanceOrderOffset

instance instanceOrderOffset : Order Offset

The one farther behind UTC first, as NodaTime orders them: -05:00 before Z before +08:00.

>>> fromHours (-5) < Just utc && Just utc < fromHours 8
True

instanceDebugOffset

instance instanceDebugOffset : Debug Offset

As show writes it, +08:00.

>>> debug utc
"Z"

instanceShowOffset

instance instanceShowOffset : Show Offset

As ISO 8601 writes it: Z for none, else its sign, hours and minutes, +08:00, -09:30, and the seconds of one that is not whole minutes after them, +05:30:15.

>>> List.map (\n -> maybe "" show (fromSeconds n)) [0, 28800, -34200, 19815, -64800, -1]
["Z", "+08:00", "-09:30", "+05:30:15", "-18:00", "-00:00:01"]

parse

parse : String -> Maybe Offset

The offset RFC 3339 writes as s: Z (or z) for UTC, or a sign, the hours 00 to 18 and the minutes 00 to 59, +08:00, -09:30, within 18 hours either way; -00:00 is UTC. Nothing if it writes none, or one beyond 18 hours.

>>> List.map (\s -> maybe "" show (parse s)) ["Z", "z", "+08:00", "-09:30", "+18:00", "-18:00", "-00:00"]
["Z", "Z", "+08:00", "-09:30", "+18:00", "-18:00", "Z"]
>>> (List.map (\s -> maybe True (\_ -> False) (parse s)) ["+18:01", "-19:00", "+08:60", "+0800", "08:00", "+8:00", "+08:00:00", "UTC", ""] : List Bool)
[True, True, True, True, True, True, True, True, True]
>>> List.all (\n -> maybe False (\o -> parse (show o) == Just o) (fromSeconds n)) [0, 28800, -34200, 64800, -64800]
True