给定 IANA 时区和本地时间,将其解析为 Maybe Posix?
Given an IANA Timezone and a local time, parse it into a Maybe Posix?
Elm 中有没有办法获取本地时间(例如字符串 2019-03-18T09:10:12.4
;未指定偏移量)和时区(例如 Australia/Sydney
) 到可能的 Posix 值(即时间转换为 UTC),而不使用端口?
有 waratuman/time-extra, but it seems to only work on the Date portion. And sadly rtfeldman/elm-iso8601-date-strings doesn't take timezones.
在JS中,有moment-tz and date-fns-timezone等选项,但避免JS互操作进行频繁的日期解析会简单得多。
如果我们可以假设您的所有日期都没有时区,并且您总是希望在将它们转换为 Posix 之前将它们转换为 Australia/Sydney
,那么您应该能够将它们连接起来自己创建的偏移量 2019-03-18T09:10:12.4+11:00
:
toPosix : String -> String -> Maybe Posix
toPosix timezone timestampWithoutTimezone =
let
timestampWithTimezone = timestampWithoutTimezone ++ timezone
in
timestampWithTimezone |> toTime |> Result.toMaybe
{- If you always want to use Australia/Sydney -}
localPosix =
toPosix "+11:00"
posix =
localPosix "2019-03-18T09:10:12.4"
{- Custom timezone -}
posix =
toPosix "+11:00" "2019-03-18T09:10:12.4"
通过组合 justinmimbs/time-extra and justinmimbs/timezone-data,您应该能够完全在 Elm 中获得有效的 posix。
演示:https://ellie-app.com/54tyw9yvsQga1
首先,您需要将 timestampWithoutTimezone
转换为 Parts
:
toParts : String -> Maybe Parts
toParts timestampWithoutTimezone =
timestampWithoutTimezone
|> Regex.find regex
|> List.map .submatches
|> List.head
|> Maybe.andThen Maybe.Extra.combine
|> Maybe.andThen listToParts
regex : Regex
regex =
Maybe.withDefault Regex.never <|
Regex.fromString "^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})\.(\d)$"
monthLookup : Dict String Month
monthLookup =
Dict.fromList [ ( "01", Jan ), ( "02", Feb ), ( "03", Mar ), ( "04", Apr ), ( "05", May ), ( "06", Jun ), ( "07", Jul ), ( "08", Aug ), ( "09", Sep ), ( "10", Oct ), ( "11", Nov ), ( "12", Dec ) ]
listToParts : List String -> Maybe Parts
listToParts list =
let
toInt : Int -> Maybe Int
toInt index =
list |> List.Extra.getAt index |> Maybe.andThen String.toInt
in
Maybe.map2 Parts
(toInt 0)
(list |> List.Extra.getAt 1 |> Maybe.andThen (\month -> Dict.get month monthLookup))
|> Maybe.andThen (\parts -> Maybe.map5 parts (toInt 2) (toInt 3) (toInt 4) (toInt 5) (toInt 6))
然后,使用partsToPosix
with the appropriate Zone
你可以得到一个posix值:
toPosix : Time.Zone -> String -> Maybe Posix
toPosix zone timestampWithoutTimezone =
timestampWithoutTimezone
|> toParts
|> Maybe.map (Time.Extra.partsToPosix zone)
库作者建议您在模型中存储评估的区域值:
model = { zone = TimeZone.australia__sydney () }
toPosix model.zone "2019-03-18T09:10:12.4"
Elm 中有没有办法获取本地时间(例如字符串 2019-03-18T09:10:12.4
;未指定偏移量)和时区(例如 Australia/Sydney
) 到可能的 Posix 值(即时间转换为 UTC),而不使用端口?
有 waratuman/time-extra, but it seems to only work on the Date portion. And sadly rtfeldman/elm-iso8601-date-strings doesn't take timezones.
在JS中,有moment-tz and date-fns-timezone等选项,但避免JS互操作进行频繁的日期解析会简单得多。
如果我们可以假设您的所有日期都没有时区,并且您总是希望在将它们转换为 Posix 之前将它们转换为 Australia/Sydney
,那么您应该能够将它们连接起来自己创建的偏移量 2019-03-18T09:10:12.4+11:00
:
toPosix : String -> String -> Maybe Posix
toPosix timezone timestampWithoutTimezone =
let
timestampWithTimezone = timestampWithoutTimezone ++ timezone
in
timestampWithTimezone |> toTime |> Result.toMaybe
{- If you always want to use Australia/Sydney -}
localPosix =
toPosix "+11:00"
posix =
localPosix "2019-03-18T09:10:12.4"
{- Custom timezone -}
posix =
toPosix "+11:00" "2019-03-18T09:10:12.4"
通过组合 justinmimbs/time-extra and justinmimbs/timezone-data,您应该能够完全在 Elm 中获得有效的 posix。
演示:https://ellie-app.com/54tyw9yvsQga1
首先,您需要将 timestampWithoutTimezone
转换为 Parts
:
toParts : String -> Maybe Parts
toParts timestampWithoutTimezone =
timestampWithoutTimezone
|> Regex.find regex
|> List.map .submatches
|> List.head
|> Maybe.andThen Maybe.Extra.combine
|> Maybe.andThen listToParts
regex : Regex
regex =
Maybe.withDefault Regex.never <|
Regex.fromString "^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})\.(\d)$"
monthLookup : Dict String Month
monthLookup =
Dict.fromList [ ( "01", Jan ), ( "02", Feb ), ( "03", Mar ), ( "04", Apr ), ( "05", May ), ( "06", Jun ), ( "07", Jul ), ( "08", Aug ), ( "09", Sep ), ( "10", Oct ), ( "11", Nov ), ( "12", Dec ) ]
listToParts : List String -> Maybe Parts
listToParts list =
let
toInt : Int -> Maybe Int
toInt index =
list |> List.Extra.getAt index |> Maybe.andThen String.toInt
in
Maybe.map2 Parts
(toInt 0)
(list |> List.Extra.getAt 1 |> Maybe.andThen (\month -> Dict.get month monthLookup))
|> Maybe.andThen (\parts -> Maybe.map5 parts (toInt 2) (toInt 3) (toInt 4) (toInt 5) (toInt 6))
然后,使用partsToPosix
with the appropriate Zone
你可以得到一个posix值:
toPosix : Time.Zone -> String -> Maybe Posix
toPosix zone timestampWithoutTimezone =
timestampWithoutTimezone
|> toParts
|> Maybe.map (Time.Extra.partsToPosix zone)
库作者建议您在模型中存储评估的区域值:
model = { zone = TimeZone.australia__sydney () }
toPosix model.zone "2019-03-18T09:10:12.4"