Учитывая часовой пояс IANA и местное время, проанализируйте его в Maybe Posix? - PullRequest
4 голосов
/ 21 марта 2019

Есть ли способ в Elm взять местное время (например, строку 2019-03-18T09:10:12.4; без указания смещения ) и часовой пояс (например, Australia/Sydney) для возможного Posix значение (т. Е. Время, преобразованное в UTC), без использования портов?


Есть waratuman / time-extra , но, похоже, он работает только с частью Date. И, к сожалению, rtfeldman / elm-iso8601-date-strings не принимает часовых поясов .

В JS есть такие опции, как moment-tz и date-fns-timezone , но было бы намного проще избежать JS-взаимодействия для частого анализа даты.

Ответы [ 2 ]

2 голосов
/ 23 марта 2019

Объединив justinmimbs / time-extra и justinmimbs / timezone-data , вы сможете получить действительный посикс полностью в Elm.

Демо: 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 с соответствующим 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"
2 голосов
/ 22 марта 2019

Если мы можем предположить, что все ваши даты идут без часового пояса, и что вы всегда хотите привести их к Australia/Sydney перед преобразованием их в Posix, вы можете просто объединить смещение для создания 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"

...