This package allows us to transfer time zone through the wire easily and tries to observe daylight saving time.
epoch : Time.Posix
Unix epoch
Keep track of each part of time. Use toParts
to create parts from posix time.
import Iso8601
import Time
epoch
|> toParts utc
|> withYear 2022
|> withMonth Time.Jul
|> withDay 22
|> withHour 14
|> withMinute 32
|> withSecond 17
|> withMillis 678
|> fromParts utc
|> Ok
--> Iso8601.toTime "2022-07-22T14:32:17.678Z"
toParts : Zone -> Time.Posix -> Parts
Convert posix time to Parts
.
fromParts : Zone -> Parts -> Time.Posix
Convert Parts
back to posix time.
import Iso8601
import Time
-- Extract several eras from America/New_York for testing
-- summer : 2022-03-13T02:00:00-05:00 -> 2022-03-13T03:00:00-04:00
-- winter : 2022-11-06T02:00:00-04:00 -> 2022-11-06T01:00:00-05:00
newYork : Zone
newYork =
customZone ""
[ { start = 27976740, offset = -240 } -- 2023-03-12T03:00:00-04:00
, { start = 27795240, offset = -300 } -- 2022-11-06T01:00:00-05:00
, { start = 27452580, offset = -240 } -- 2022-03-13T03:00:00-04:00
, { start = 27271080, offset = -300 } -- 2021-11-07T01:00:00-05:00
]
-300
-- Extract several eras from Europe/Paris for testing
-- summer : 2022-03-27T02:00:00+01:00 -> 2022-03-27T03:00:00+02:00
-- winter : 2022-10-30T03:00:00+02:00 -> 2022-10-30T02:00:00+01:00
paris : Time2.Zone
paris =
customZone ""
[ { start = 27996540, offset = 120 } -- 2023-03-26T03:00:00+02:00
, { start = 27784860, offset = 60 } -- 2022-10-30T02:00:00+01:00
, { start = 27472380, offset = 120 } -- 2022-03-27T03:00:00+02:00
, { start = 27260700, offset = 60 } -- 2021-10-31T02:00:00+01:00
]
60
epoch
|> toParts newYork
|> withYear 2022
|> withMonth Time.Mar
|> withDay 13
|> withHour 1
|> withMinute 59
|> withSecond 59
|> fromParts newYork
|> Ok
--> Iso8601.toTime "2022-03-13T01:59:59-05:00"
epoch
|> toParts newYork
|> withYear 2022
|> withMonth Time.Mar
|> withDay 13
|> withHour 2
|> fromParts newYork
|> Ok
--> Iso8601.toTime "2022-03-13T03:00:00-04:00"
epoch
|> toParts newYork
|> withYear 2022
|> withMonth Time.Mar
|> withDay 13
|> withHour 3
|> fromParts newYork
|> Ok
--> Iso8601.toTime "2022-03-13T03:00:00-04:00"
-- `fromParts` gives the second 01:59:59
epoch
|> toParts newYork
|> withYear 2022
|> withMonth Time.Nov
|> withDay 6
|> withHour 1
|> withMinute 59
|> withSecond 59
|> fromParts newYork
|> Ok
--> Iso8601.toTime "2022-11-06T01:59:59-05:00"
-- `fromParts` gives the second 2022-11-06T02:00:00
epoch
|> toParts newYork
|> withYear 2022
|> withMonth Time.Nov
|> withDay 6
|> withHour 2
|> fromParts newYork
|> Ok
--> Iso8601.toTime "2022-11-06T02:00:00-05:00"
epoch
|> toParts paris
|> withYear 2022
|> withMonth Time.Mar
|> withDay 27
|> withHour 1
|> withMinute 59
|> withSecond 59
|> fromParts paris
|> Ok
--> Iso8601.toTime "2022-03-27T01:59:59+01:00"
epoch
|> toParts paris
|> withYear 2022
|> withMonth Time.Mar
|> withDay 27
|> withHour 2
|> fromParts paris
|> Ok
--> Iso8601.toTime "2022-03-27T03:00:00+02:00"
epoch
|> toParts paris
|> withYear 2022
|> withMonth Time.Mar
|> withDay 27
|> withHour 3
|> fromParts paris
|> Ok
--> Iso8601.toTime "2022-03-27T03:00:00+02:00"
-- `fromParts` gives the second 2022-10-30T02:59:59
epoch
|> toParts paris
|> withYear 2022
|> withMonth Time.Oct
|> withDay 30
|> withHour 2
|> withMinute 59
|> withSecond 59
|> fromParts paris
|> Ok
--> Iso8601.toTime "2022-10-30T02:59:59+01:00"
-- `fromParts` gives the second 2022-10-30T03:00:00
epoch
|> toParts paris
|> withYear 2022
|> withMonth Time.Oct
|> withDay 30
|> withHour 3
|> fromParts paris
|> Ok
--> Iso8601.toTime "2022-10-30T03:00:00+01:00"
withYear : Basics.Int -> Parts -> Parts
Set year of Parts
.
withMonth : Time.Month -> Parts -> Parts
Set month of Parts
.
withDay : Basics.Int -> Parts -> Parts
Set day of Parts
.
withHour : Basics.Int -> Parts -> Parts
Set hour of Parts
.
withMinute : Basics.Int -> Parts -> Parts
Set minute of Parts
.
withSecond : Basics.Int -> Parts -> Parts
Set second of Parts
.
withMillis : Basics.Int -> Parts -> Parts
Set millis of Parts
.
A zone is a list of eras sorted by descending order of the starting point of each era.
Note that we don't expose the variants because we don't want to bump major version of the package too often. Use
customZone
if we want to create a zone manually. Or create a decoder to decode the value encoded by
encodeZone
if we want to get the raw data, we'll try to keep encodeZone
backward
compatible.
getZoneName : Zone -> String
Get the name of a zone.
getZoneName utc
--> "Etc/UTC"
customZone : String -> List { start : Basics.Int, offset : Basics.Int } -> Basics.Int -> Zone
Create a zone with name
, eras
and offsetOfEarliestEra
.
utc : Zone
utc
encodeZone : Zone -> Json.Encode.Value
Encode Zone
so we can send it through wire.
import Json.Decode
zone : Zone
zone =
customZone "Zone/Name"
[ { start = 20, offset = 60 }
, { start = 10, offset = -120 }
]
30
zone
|> encodeZone
|> Json.Decode.decodeValue decoderOfZone
--> Ok zone
decoderOfZone : Json.Decode.Decoder Zone
Decode Json.Encode.Value
back to Zone
.
elm/time
toElmTimeZone : Zone -> Time.Zone
This function converts Time2.Zone
to Time.Zone
.
import Time
start : Int
start =
61
zone : Time.Zone
zone =
customZone "" [ { start = start, offset = 120 } ] 0
|> toElmTimeZone
Time.millisToPosix (start * 60 * 1000)
|> Time.toHour zone
--> 3 -- This will be 1 once https://github.com/elm/time/issues/7 is fixed, we then need to fix our implementation
toStandardZone : Zone -> Time.Zone
Deprecated, please use toElmTimeZone
as that name is less misleading.