Giter Club home page Giter Club logo

elm-time's People

Contributors

allenap avatar bogdanp avatar gyzerok avatar mattcheely avatar oldfartdeveloper avatar rofrol avatar thintim avatar trotha01 avatar turbomack avatar waratuman avatar witoldsz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

elm-time's Issues

Confusing delta calculation

I believe the difference between

"2017-12-11T23:30:00+09:00" and
"2017-12-12T09:30:00+09:00"

is less than 1 day, but delta says it is not.

dates =
    { d1 = fromISO8601 "2017-12-11T23:30:00+09:00"
    , d2 = fromISO8601 "2017-12-12T08:30:00+09:00"
    , d3 = fromISO8601 "2017-12-12T09:30:00+09:00"
    }


fromISO8601 : String -> DateTime
fromISO8601 s =
    case DateTime.fromISO8601 s of
        Ok dt ->
            dt

        Err e ->
            Debug.crash e


suite : Test
suite =
    describe "DateTime"
        [ test "d2 - d1 should be less than 1 day" <|
            \_ ->
                DateTime.delta dates.d2 dates.d1
                    |> Debug.log "d2 - d1"
                    |> .days
                    |> Expect.equal 0
        , test "d3 - d1 should be still less than 1 day" <|
            \_ ->
                DateTime.delta dates.d3 dates.d1
                    |> Debug.log "d3 - d1"
                    |> .days
                    |> Expect.equal 0
        ]
Running 2 tests. To reproduce these results, run: elm-test --fuzz 100 --seed 773854204

d2 - d1: { years = 0, months = 0, days = 0, hours = 9, minutes = 540, seconds = 32400, milliseconds = 32400000 }
d3 - d1: { years = 0, months = 0, days = 1, hours = 10, minutes = 600, seconds = 36000, milliseconds = 36000000 }
↓ Example
↓ DateTime
✗ d3 - d1 should be still less than day

    1
    ╷
    │ Expect.equal
    ╵
    0

Is this a bug?

DateTime.fromISO8601 fails to parse valid formats

As I understand it, ISO 1601 considers the separators in dates (-) and times (:) optional. Negative offsets can also be indicated by minus '-' or a hyphen '−'.

elm-time's fromISO8601 will fail to parse a string without separators, or one using a hyphen to indicate a negative UTC offset.

I'd open a PR, but I'm unable to get elm-test to run. The best I can do right now is provide a few examples here: https://ellie-app.com/3t6yxCjFpbma1/1

As a point of reference, I discovered this attempting to parse dates from JIRA's API, which do not contain an offset separator (2017-04-28T14:37:51.887-0400), so there's at least one significant API in the wild that this causes issues for.

References:
https://www.cs.tut.fi/~jkorpela/iso8601.html#sep
https://en.wikipedia.org/wiki/ISO_8601#Time_offsets_from_UTC

Error parsing a valid ISO8601 date with a year less than 1000

When using the Time.Date.fromISO8601 an error is thrown for a correct date. The same is true in reverse as well. When generating an ISO8601 string from the date 0001-01-01 a non ISO8601 string is returned.

Example:

> import Time.Date
> Time.Date.fromISO8601 "0001-01-01"
Err "Errors encountered at position 1: expected \"-\""
    : Result.Result String Time.Date.Date
> Time.Date.date 1 1 1 |> Time.Date.toISO8601
"1-01-01" : String

Should clamping be the default behavior for a new Time object?

Referencing the README:


Constructing Dates

Use date to construct Date values. If given invalid values for
the month and day, they are both clamped and the nearest valid date is
returned.


This is wrong on the basis of the #create function is doing two things:

  1. Creating an instance of the data.
  2. Modifying it arbitrarily if any of the function's parameters are wrong.

This would be tolerable if there was any other way to create the object, but unfortunately there isn't. Hence, in my mind the #create function is broken, and if I want to use this module, I have to write a wrapper around this class. I will probably instead fork the module, modify it, and then publish it as a "better" competitor. As the maintainer, I say #ugh

Here's my suggested solution that still allows clamping:

  1. The default behavior needs to be that wrong inputs throw a Result. Now the api is providing me exactly what I need to know. It can tell me what value(s) are wrong and I can program a correction any way I want "the Elm way".
  2. If I want the admitted simplicity of "clamping", then the solution is to add a function, #create_clamped, that will do exactly that, AND the name of the function explains what it is doing.

Everybody wins.

DateTime.toISO8601 truncates to seconds

Hi, I have a problem with incorrect dates generated in my forms and I have found the problem is in toISO8601 function, it skips the milliseconds part of the date.
See this: https://runelm.io/c/3cr

Time.DateTime.fromISO8601 "2017-04-22T19:05:31.040Z"
    |> Result.map Time.DateTime.toISO8601
    |> Result.withDefault ""
 input: 2017-04-22T19:05:31.040Z

output: 2017-04-22T19:05:31Z

`fromISO8601` fails when date ends with `.000Z`

1970-01-01T00:00:00.000Z (this is how dateObj.toISOString() works)
Err "Errors encountered at position 19: expected \"Z\" or expected an integer"
1970-01-01T00:00:00Z
Ok (DateTime { date = Date { year = 1970, month = 1, day = 1 }, offset = 0 })

See: https://runelm.io/c/enq

Workaround:

DateTime.fromISO8601 <| Regex.replace Regex.All (regex "[.]000Z") (\_ -> "Z") str

Reference:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString

Feature request: Beginning of day in timezone

It would be great that elm-time could give me the beginning of a day in a particular timezone

This is what I'm doing now. based on a reference time and an offset

beginningOfDay : Int -> Time -> DT.DateTime
beginningOfDay offset referenceTime =
    referenceTime
        |> DT.fromTimestamp
        |> DT.addMilliseconds -offset
        |> DT.setHour 0
        |> DT.setMinute 0
        |> DT.setSecond 0
        |> DT.addMilliseconds offset

dayDiff or dayDelta

This is a request to implement a dayDiff or dayDelta function that would return the number of days between 2 dates.

cannot convert if there are decimal fractions of a second

This fails because it's expecting the "Z" to be after "03:56:12"

DT.fromISO8601 "2016-11-14T03:56:12.123Z"
Err "Errors encountered at position 19: expected "Z" or expected an integer"
: Result.Result String Time.DateTime.DateTime

How to be with DateTimeData alias being internal?

Hello!

Currently documentation for DateTime.zero mention record updates for the DateTimeData.

This is a bit weird since DateTimeData is not part of a public interface. So to figure out what you can update there, you need to check source code for it. By reading the code I assume you want to keep it internal.

What about removing DateTime.dateTime function and making DateTime.zero return DateTime? This way nothing gets exposed and the previous behavior is still possible with functions like setYear or setMonth.

Examples from the readme will then change like this:

-- OLD
dateTime { zero | year = 2016 }

-- NEW
zero |> setYear 2016

I think that this will follow Elm idea of "one way to do thing" (now you can actually use both ways) pretty nicely. Also with current compiler behavior it is inconvenient to use DateTime.zero if you use qualified imports - { DateTime.zero | year = 2016 } won't work.

Would be happy to make a PR with the change if it makes sense.

What do you think?

update for 0.19?

Hello!

thanks for the awesome package! any update for elm 0.19?

Range function to generate a list of dates between two dates

Sometimes, I find myself writing a function to generate a list of dates between two given dates, like this:

dateRange : Date -> Date -> List Date
dateRange firstDate lastDate =
  case Date.compare firstDate lastDate of
    GT ->
      []
    _ ->
      firstDate :: dateRange (Date.addDays 1 firstDate) lastDate

With the available library functions addMonths, addHours, addMinutes, etc.., the range function can be generalised to create ranges for different intervals (months, hours, minutes, etc...).

Would you consider adding such a function to the elm-time library?

"add" functions don't need to clamp

In the README, there's this section:


Manipulating Dates

...

addDays can be used to add an exact number of days to a Date.

addYears and addMonths add a relative number of years and months
to a date. If the target date is invalid, these functions continually
subtract one day until a valid date is found.


There is no need to clamp. Other packages I use (in Ruby for example), simply add into the following month or subtract from the previous month(s) as necessary.

Hence, here's how they would work:

--- Spill over into following month
> date 1992 1 31
|   |> Date.addDays 1
|   |> Date.toISO8601
"1993-02-01" : String

-- Back up to previous month
> date 1992 2 1
|   |> Date.addDays -1
|   |> Date.toISO8601
"1993-01-31" : String

-- Use length of spilled-into month as length for each month
> date 1992 1 31
|   |> Date.addMonths 3
|   |> Date.toISO8601
"1992-04-30" : String

--- Use average of 30 days per month:
> date 1992 1 1
|   |> Date.addDays (3 * 30)
|   |> Date.toISO8601
"1992-03-31" : String

Support end-of-day (hour 24) like ISO8601

This library supports converting to/from ISO 8601, but does not support one of the features I need, which is indicated in the Wikipedia article describing the standard.
I should be able to set the time to either 00:00 or 24:00, depending on whether the time is meant to indicate the beginning or the end of a day. Currently the library clamps to 23 hours. It would be nice for this limit to be increased to 24. Note that the time would still be equivalent to 00:00 of the next day.

It is a pain to inspect a model with ZonedDateTime.

Hello,
the toString representation of ZonedDateTime is a huge amount of text. It looks like each and every instance keeps the time zone data. It's getting painful when debugging.

It would be great if the instances of ZonedDateTime (or TimeZone?) did not hold everything within.


Suggesion:
Maybe ZoneId could be created to replace TimeZone embedded in ZonedDateTime?


A sample of

zonedDateTime
    (europe_warsaw ())
    { zero | year = 2017, month = 2, day = 27, hour = 23 }
    |> toString

ZonedDateTime { timeZone = TimeZone { name = "Europe/Warsaw", spans = [{ from = -Infinity, until = -1717032240000, abbreviation = "WMT", offset = -5040000 },{ from = -1717032240000, until = -1693706400000, abbreviation = "CET", offset = -3600000 },{ from = -1693706400000, until = -1680483600000, abbreviation = "CEST", offset = -7200000 },{ from = -1680483600000, until = -1663455600000, abbreviation = "CET", offset = -3600000 },{ from = -1663455600000, until = -1650150000000, abbreviation = "CEST", offset = -7200000 },{ from = -1650150000000, until = -1632006000000, abbreviation = "CET", offset = -3600000 },{ from = -1632006000000, until = -1618700400000, abbreviation = "CEST", offset = -7200000 },{ from = -1618700400000, until = -1600473600000, abbreviation = "EET", offset = -7200000 },{ from = -1600473600000, until = -1587168000000, abbreviation = "EEST", offset = -10800000 },{ from = -1587168000000, until = -1501725600000, abbreviation = "EET", offset = -7200000 },{ from = -1501725600000, until = -931734000000, abbreviation = "CET", offset = -3600000 },{ from = -931734000000, until = -857257200000, abbreviation = "CEST", offset = -7200000 },{ from = -857257200000, until = -844556400000, abbreviation = "CET", offset = -3600000 },{ from = -844556400000, until = -828226800000, abbreviation = "CEST", offset = -7200000 },{ from = -828226800000, until = -812502000000, abbreviation = "CET", offset = -3600000 },{ from = -812502000000, until = -796608000000, abbreviation = "CEST", offset = -7200000 },{ from = -796608000000, until = -778726800000, abbreviation = "CET", offset = -3600000 },{ from = -778726800000, until = -762660000000, abbreviation = "CEST", offset = -7200000 },{ from = -762660000000, until = -748486800000, abbreviation = "CET", offset = -3600000 },{ from = -748486800000, until = -733273200000, abbreviation = "CEST", offset = -7200000 },{ from = -733273200000, until = -715215600000, abbreviation = "CET", offset = -3600000 },{ from = -715215600000, until = -701910000000, abbreviation = "CEST", offset = -7200000 },{ from = -701910000000, until = -684975600000, abbreviation = "CET", offset = -3600000 },{ from = -684975600000, until = -670460400000, abbreviation = "CEST", offset = -7200000 },{ from = -670460400000, until = -654130800000, abbreviation = "CET", offset = -3600000 },{ from = -654130800000, until = -639010800000, abbreviation = "CEST", offset = -7200000 },{ from = -639010800000, until = -397094400000, abbreviation = "CET", offset = -3600000 },{ from = -397094400000, until = -386812800000, abbreviation = "CEST", offset = -7200000 },{ from = -386812800000, until = -371088000000, abbreviation = "CET", offset = -3600000 },{ from = -371088000000, until = -355363200000, abbreviation = "CEST", offset = -7200000 },{ from = -355363200000, until = -334195200000, abbreviation = "CET", offset = -3600000 },{ from = -334195200000, until = -323308800000, abbreviation = "CEST", offset = -7200000 },{ from = -323308800000, until = -307584000000, abbreviation = "CET", offset = -3600000 },{ from = -307584000000, until = -291859200000, abbreviation = "CEST", offset = -7200000 },{ from = -291859200000, until = -271296000000, abbreviation = "CET", offset = -3600000 },{ from = -271296000000, until = -260409600000, abbreviation = "CEST", offset = -7200000 },{ from = -260409600000, until = -239846400000, abbreviation = "CET", offset = -3600000 },{ from = -239846400000, until = -228960000000, abbreviation = "CEST", offset = -7200000 },{ from = -228960000000, until = -208396800000, abbreviation = "CET", offset = -3600000 },{ from = -208396800000, until = -197510400000, abbreviation = "CEST", offset = -7200000 },{ from = -197510400000, until = -176342400000, abbreviation = "CET", offset = -3600000 },{ from = -176342400000, until = -166060800000, abbreviation = "CEST", offset = -7200000 },{ from = -166060800000, until = 228873600000, abbreviation = "CET", offset = -3600000 },{ from = 228873600000, until = 243993600000, abbreviation = "CEST", offset = -7200000 },{ from = 243993600000, until = 260323200000, abbreviation = "CET", offset = -3600000 },{ from = 260323200000, until = 276048000000, abbreviation = "CEST", offset = -7200000 },{ from = 276048000000, until = 291772800000, abbreviation = "CET", offset = -3600000 },{ from = 291772800000, until = 307497600000, abbreviation = "CEST", offset = -7200000 },{ from = 307497600000, until = 323827200000, abbreviation = "CET", offset = -3600000 },{ from = 323827200000, until = 338947200000, abbreviation = "CEST", offset = -7200000 },{ from = 338947200000, until = 354672000000, abbreviation = "CET", offset = -3600000 },{ from = 354672000000, until = 370396800000, abbreviation = "CEST", offset = -7200000 },{ from = 370396800000, until = 386121600000, abbreviation = "CET", offset = -3600000 },{ from = 386121600000, until = 401846400000, abbreviation = "CEST", offset = -7200000 },{ from = 401846400000, until = 417571200000, abbreviation = "CET", offset = -3600000 },{ from = 417571200000, until = 433296000000, abbreviation = "CEST", offset = -7200000 },{ from = 433296000000, until = 449020800000, abbreviation = "CET", offset = -3600000 },{ from = 449020800000, until = 465350400000, abbreviation = "CEST", offset = -7200000 },{ from = 465350400000, until = 481075200000, abbreviation = "CET", offset = -3600000 },{ from = 481075200000, until = 496800000000, abbreviation = "CEST", offset = -7200000 },{ from = 496800000000, until = 512524800000, abbreviation = "CET", offset = -3600000 },{ from = 512524800000, until = 528249600000, abbreviation = "CEST", offset = -7200000 },{ from = 528249600000, until = 543974400000, abbreviation = "CET", offset = -3600000 },{ from = 543974400000, until = 559699200000, abbreviation = "CEST", offset = -7200000 },{ from = 559699200000, until = 575427600000, abbreviation = "CET", offset = -3600000 },{ from = 575427600000, until = 591152400000, abbreviation = "CEST", offset = -7200000 },{ from = 591152400000, until = 606877200000, abbreviation = "CET", offset = -3600000 },{ from = 606877200000, until = 622602000000, abbreviation = "CEST", offset = -7200000 },{ from = 622602000000, until = 638326800000, abbreviation = "CET", offset = -3600000 },{ from = 638326800000, until = 654656400000, abbreviation = "CEST", offset = -7200000 },{ from = 654656400000, until = 670381200000, abbreviation = "CET", offset = -3600000 },{ from = 670381200000, until = 686106000000, abbreviation = "CEST", offset = -7200000 },{ from = 686106000000, until = 701830800000, abbreviation = "CET", offset = -3600000 },{ from = 701830800000, until = 717555600000, abbreviation = "CEST", offset = -7200000 },{ from = 717555600000, until = 733280400000, abbreviation = "CET", offset = -3600000 },{ from = 733280400000, until = 749005200000, abbreviation = "CEST", offset = -7200000 },{ from = 749005200000, until = 764730000000, abbreviation = "CET", offset = -3600000 },{ from = 764730000000, until = 780454800000, abbreviation = "CEST", offset = -7200000 },{ from = 780454800000, until = 796179600000, abbreviation = "CET", offset = -3600000 },{ from = 796179600000, until = 811904400000, abbreviation = "CEST", offset = -7200000 },{ from = 811904400000, until = 828234000000, abbreviation = "CET", offset = -3600000 },{ from = 828234000000, until = 846378000000, abbreviation = "CEST", offset = -7200000 },{ from = 846378000000, until = 859683600000, abbreviation = "CET", offset = -3600000 },{ from = 859683600000, until = 877827600000, abbreviation = "CEST", offset = -7200000 },{ from = 877827600000, until = 891133200000, abbreviation = "CET", offset = -3600000 },{ from = 891133200000, until = 909277200000, abbreviation = "CEST", offset = -7200000 },{ from = 909277200000, until = 922582800000, abbreviation = "CET", offset = -3600000 },{ from = 922582800000, until = 941331600000, abbreviation = "CEST", offset = -7200000 },{ from = 941331600000, until = 954032400000, abbreviation = "CET", offset = -3600000 },{ from = 954032400000, until = 972781200000, abbreviation = "CEST", offset = -7200000 },{ from = 972781200000, until = 985482000000, abbreviation = "CET", offset = -3600000 },{ from = 985482000000, until = 1004230800000, abbreviation = "CEST", offset = -7200000 },{ from = 1004230800000, until = 1017536400000, abbreviation = "CET", offset = -3600000 },{ from = 1017536400000, until = 1035680400000, abbreviation = "CEST", offset = -7200000 },{ from = 1035680400000, until = 1048986000000, abbreviation = "CET", offset = -3600000 },{ from = 1048986000000, until = 1067130000000, abbreviation = "CEST", offset = -7200000 },{ from = 1067130000000, until = 1080435600000, abbreviation = "CET", offset = -3600000 },{ from = 1080435600000, until = 1099184400000, abbreviation = "CEST", offset = -7200000 },{ from = 1099184400000, until = 1111885200000, abbreviation = "CET", offset = -3600000 },{ from = 1111885200000, until = 1130634000000, abbreviation = "CEST", offset = -7200000 },{ from = 1130634000000, until = 1143334800000, abbreviation = "CET", offset = -3600000 },{ from = 1143334800000, until = 1162083600000, abbreviation = "CEST", offset = -7200000 },{ from = 1162083600000, until = 1174784400000, abbreviation = "CET", offset = -3600000 },{ from = 1174784400000, until = 1193533200000, abbreviation = "CEST", offset = -7200000 },{ from = 1193533200000, until = 1206838800000, abbreviation = "CET", offset = -3600000 },{ from = 1206838800000, until = 1224982800000, abbreviation = "CEST", offset = -7200000 },{ from = 1224982800000, until = 1238288400000, abbreviation = "CET", offset = -3600000 },{ from = 1238288400000, until = 1256432400000, abbreviation = "CEST", offset = -7200000 },{ from = 1256432400000, until = 1269738000000, abbreviation = "CET", offset = -3600000 },{ from = 1269738000000, until = 1288486800000, abbreviation = "CEST", offset = -7200000 },{ from = 1288486800000, until = 1301187600000, abbreviation = "CET", offset = -3600000 },{ from = 1301187600000, until = 1319936400000, abbreviation = "CEST", offset = -7200000 },{ from = 1319936400000, until = 1332637200000, abbreviation = "CET", offset = -3600000 },{ from = 1332637200000, until = 1351386000000, abbreviation = "CEST", offset = -7200000 },{ from = 1351386000000, until = 1364691600000, abbreviation = "CET", offset = -3600000 },{ from = 1364691600000, until = 1382835600000, abbreviation = "CEST", offset = -7200000 },{ from = 1382835600000, until = 1396141200000, abbreviation = "CET", offset = -3600000 },{ from = 1396141200000, until = 1414285200000, abbreviation = "CEST", offset = -7200000 },{ from = 1414285200000, until = 1427590800000, abbreviation = "CET", offset = -3600000 },{ from = 1427590800000, until = 1445734800000, abbreviation = "CEST", offset = -7200000 },{ from = 1445734800000, until = 1459040400000, abbreviation = "CET", offset = -3600000 },{ from = 1459040400000, until = 1477789200000, abbreviation = "CEST", offset = -7200000 },{ from = 1477789200000, until = 1490490000000, abbreviation = "CET", offset = -3600000 },{ from = 1490490000000, until = 1509238800000, abbreviation = "CEST", offset = -7200000 },{ from = 1509238800000, until = 1521939600000, abbreviation = "CET", offset = -3600000 },{ from = 1521939600000, until = 1540688400000, abbreviation = "CEST", offset = -7200000 },{ from = 1540688400000, until = 1553994000000, abbreviation = "CET", offset = -3600000 },{ from = 1553994000000, until = 1572138000000, abbreviation = "CEST", offset = -7200000 },{ from = 1572138000000, until = 1585443600000, abbreviation = "CET", offset = -3600000 },{ from = 1585443600000, until = 1603587600000, abbreviation = "CEST", offset = -7200000 },{ from = 1603587600000, until = 1616893200000, abbreviation = "CET", offset = -3600000 },{ from = 1616893200000, until = 1635642000000, abbreviation = "CEST", offset = -7200000 },{ from = 1635642000000, until = 1648342800000, abbreviation = "CET", offset = -3600000 },{ from = 1648342800000, until = 1667091600000, abbreviation = "CEST", offset = -7200000 },{ from = 1667091600000, until = 1679792400000, abbreviation = "CET", offset = -3600000 },{ from = 1679792400000, until = 1698541200000, abbreviation = "CEST", offset = -7200000 },{ from = 1698541200000, until = 1711846800000, abbreviation = "CET", offset = -3600000 },{ from = 1711846800000, until = 1729990800000, abbreviation = "CEST", offset = -7200000 },{ from = 1729990800000, until = 1743296400000, abbreviation = "CET", offset = -3600000 },{ from = 1743296400000, until = 1761440400000, abbreviation = "CEST", offset = -7200000 },{ from = 1761440400000, until = 1774746000000, abbreviation = "CET", offset = -3600000 },{ from = 1774746000000, until = 1792890000000, abbreviation = "CEST", offset = -7200000 },{ from = 1792890000000, until = 1806195600000, abbreviation = "CET", offset = -3600000 },{ from = 1806195600000, until = 1824944400000, abbreviation = "CEST", offset = -7200000 },{ from = 1824944400000, until = 1837645200000, abbreviation = "CET", offset = -3600000 },{ from = 1837645200000, until = 1856394000000, abbreviation = "CEST", offset = -7200000 },{ from = 1856394000000, until = 1869094800000, abbreviation = "CET", offset = -3600000 },{ from = 1869094800000, until = 1887843600000, abbreviation = "CEST", offset = -7200000 },{ from = 1887843600000, until = 1901149200000, abbreviation = "CET", offset = -3600000 },{ from = 1901149200000, until = 1919293200000, abbreviation = "CEST", offset = -7200000 },{ from = 1919293200000, until = 1932598800000, abbreviation = "CET", offset = -3600000 },{ from = 1932598800000, until = 1950742800000, abbreviation = "CEST", offset = -7200000 },{ from = 1950742800000, until = 1964048400000, abbreviation = "CET", offset = -3600000 },{ from = 1964048400000, until = 1982797200000, abbreviation = "CEST", offset = -7200000 },{ from = 1982797200000, until = 1995498000000, abbreviation = "CET", offset = -3600000 },{ from = 1995498000000, until = 2014246800000, abbreviation = "CEST", offset = -7200000 },{ from = 2014246800000, until = 2026947600000, abbreviation = "CET", offset = -3600000 },{ from = 2026947600000, until = 2045696400000, abbreviation = "CEST", offset = -7200000 },{ from = 2045696400000, until = 2058397200000, abbreviation = "CET", offset = -3600000 },{ from = 2058397200000, until = 2077146000000, abbreviation = "CEST", offset = -7200000 },{ from = 2077146000000, until = 2090451600000, abbreviation = "CET", offset = -3600000 },{ from = 2090451600000, until = 2108595600000, abbreviation = "CEST", offset = -7200000 },{ from = 2108595600000, until = 2121901200000, abbreviation = "CET", offset = -3600000 },{ from = 2121901200000, until = 2140045200000, abbreviation = "CEST", offset = -7200000 },{ from = 2140045200000, until = Infinity, abbreviation = "CET", offset = -3600000 }] }, dateTime = DateTime { date = Date { year = 2017, month = 2, day = 27 }, offset = 82800000 } }

RFC - Proposal of different primitives

Having been struggling with numerous date libraries in JavaScript, I decided to think of what the best API in Elm for a date library would look like. You can find some ideas here. The main goal is to minimize the amount of mistakes developers make around timezones by separating concepts of a “moment in time” and time with timezone. Being a little bit more explicit can go a long way in solving this problem.

Seeing that your library is very new and has somewhat similar concepts, I decided first to try and see what can be improved here, instead of coming up with my own implementation.

The way I think about it, moment in time refers to a particular absolute point in time — but most of the user-friendly details we can learn about it (such as day and time, as well as manipulating, formatting it and parsing a string into it) only come into play when you put it in a context of a timezone (and potentially a calendar, e.g. non-Gregorian one — but let's leave them out).

One could say that a moment in time does in fact have date and time — it's described by UTC. But this is what I think would be nice to be explicit about: by treating UTC as just another timezone we can make users think of the nature of the date they are working with. Is this a UTC date? Do we need to work with browser's timezone? Or do we need to use timezone defined somewhere in the user's settings we need to go and fetch? Those were the problem I had to solve when I was going through countless dates we were parsing, displaying and manipulating in our application.

Note that TimezoneDate = (Moment, Timezone). The reason they are separate in my gist is that while in most cases you require both moment (which I call there Timestamp) and timezone as function arguments, the timezone is almost never returned — it's used just as a parameter to transform the moment. One would read add : Timezone -> Interval -> Timestamp -> Timestamp as “Add this interval to this moment by treating it (just for the purpose of this operation) in this timezone” (argument order is different for piping reasons); the interval (say, 5 days) only makes sense in the context of a timezone, even it it's just UTC.

The presence of no-timezone-to-timezone conversion (e.g. zonedDateTime function) always makes me think: does this mean we are treating the date passed as if it was in the specified timezone, or we treat it in UTC (or any other original timezone, in case of moment.js) and simply change its timezone field? I was actually confused as I was typing this. I still am. I'm pretty sure I'm not alone.

In the current implementation, you have most operations defined on a timezone-less DateTime. While operations such as addHours can be performed on a bare date if it's treated as UTC, it's nevertheless very useful (I'd argue it's more useful) to perform those operations on a date with the potentially non-UTC timezone. Duplicating the API is probably not the best idea, this is where this separation helps as well.

Because ZonedDateTime internally stores local time rather than UTC time, it's incapable of correctly storing time during the daylight saving switch.

Would my approach fit into this library? Should I try it out in a fork or a separate codebase? Let me know what you think!

Support ISO 8601 extended by time zone name

Many libraries support an extended form of the ISO 8601 standard which includes time zone information in addition to the offset.

2017-01-02T06:12:38+01:00 [Europe/Berlin]

This fills a hole in the standard, as there is no official way to include time zone information.

I have already implemented a parsing function to read the time zone name. It's just a simple regex. Additionally I would propose to modify the existing parser to ignore time zone names if found.

Depending on your feedback, I'd open a pull request and get started.

EDIT: After reading the parser code and checking back with the documentation, I think there should be a clarification.

fromISO8601 parses an ISO8601-formatted date time string into a DateTime object, adjusting for its offset.

The later actually means "converts the date and time to UTC", which is not clear, at least for me. The type DateTime also does not talk about time zones. Seeing how the parser works, it is supposed to be used for UTC values only?

Feature request: TimeZones all

It is a common pattern to present a dropdown to a user where they can select their timezone.
In order to do this I need a list of all timezones.

Time.TimeZones doesn't expose a function for getting them all at once. It would be great to have

all : List TimeZone

Epoch and Millisencond

I used

chave =
            DateTime.epoch |> DateTime.millisecond |> toString

So, I expected return one number like 1505400959516 but the return is 0.

I using wrong or its a error?

Calculate age in years

I think I am similarly confused to what has been reported in #46.

Let's assume I have two Dates (or DateTimes for that matter). I want to know how many years have past from one point in time to another. Mainly for showing the age in years. It seems impossible to do with the current library.

How would I find out the correct age without resorting to weird hacks like dividing the days passed by 365.25 to filter out the leap years correctly?

> Time.Date.delta (Time.Date.date 2018 4 1) (Time.Date.date 1932 4 2) |> .days |> toFloat |> flip (/) 365.25
85.99589322381931 : Float
> Time.Date.delta (Time.Date.date 2018 4 2) (Time.Date.date 1932 4 2) |> .days |> toFloat |> flip (/) 365.25
85.99863107460644 : Float
> Time.Date.delta (Time.Date.date 2018 4 3) (Time.Date.date 1932 4 2) |> .days |> toFloat |> flip (/) 365.25
86.00136892539356 : Float
> 

Time.TimeZones import unusable from elm-reactor v0.18.0

Hi,
I'm running into an issue with importing Time.TimeZones within any elm module after the upgrade from elm v0.17.1 to v0.18.0. Basically if I import the module and not even use it, the elm project will compile. But if I try to run the project in elm-reactor and access the page from Chrome, I will see the following error:
"Uncaught RangeError: Maximum call stack size exceeded"

I have a minimal repro for this issue:
`
import Html exposing (..)

import Time.TimeZones

type alias Model = {}
type Msg = Msg2

main : Program Never Model Msg
main = beginnerProgram
{ model = {}
, update = \a b -> b
, view = _ -> div [] [h1 [] [text "Hello World"]]
}
`

Package imports are:

  • "Bogdanp/elm-time": "1.4.0 <= v < 2.0.0",
  • "elm-lang/core": "5.0.0 <= v < 6.0.0",
  • "elm-lang/html": "2.0.0 <= v < 3.0.0"

This is not an issue in 0.17.1.

Thanks!

Date and DateTime are often named LocalDate and LocalDateTime

Hi,
I think it could be confusing for some users that Date and DateTime are not the equivalent of things represented by Date elsewhere, like in JavaScript. Even the elm-lang/core has a Date which represents a timestamp and Date and DateTime from this lib represent something else.

My proposition would be to rename Date to LocalDate and DateTime to LocalDateTime. Also, we could introduce Timestamp and converters from Timestamp to ZonedDateTime (and vice-versa) and to LocalDate and LocalDateTime (assuming the user would provide a time-zone).

What is your opinion?

1.0.11 & 1.0.12 versions produce compilation error

My elm-package.json contains,

        "elm-community/elm-time": "1.0.8 <= v < 2.0.0",

dependency.

I needed to run elm-package install on new machine and after installation is done, elm-make failed with,

ERROR in ./static/elm/Main.elm
Module build failed: Error: Compiler process exited with error Compilation failed
Problem in dependency elm-community/parser-combinators 1.1.0

The elm-package.json constraints of 'elm-community/parser-combinators' are probably
letting too much stuff through. Definitely open an issue on the relevant github
repo to get this fixed and save other people from this pain.

In the meantime, take a look through the direct dependencies of the broken
package and see if any of them have had releases recently. If you find the new
thing that is causing problems, you can artificially constrain things by adding
some extra constraints to your elm-package.json as a stopgap measure.


Detected errors in 1 module.

After quick investigation I fixed my build by setting dependency as,

        "elm-community/elm-time": "1.0.8 <= v < 1.0.11",

so after elm-package install run 1.0.10 version installed and elm-make runs OK.


ps. Adding elm-community/parser-combinators: "1.1.0 <= v < 2.0.0" to dependencies didn't fix my build.

Feature request: Get Timezone from TZ name

I'm not sure if this is possible currently, seems not.

Most of the time all I have a is a Timezone name coming from the database e.g. Australia/Melbourne

The function unpack wants a lot more information that I don't have.

Given that you already have functions for creating the timezone e.g. australia_melbourne (). I suppose that you can do the reverse and get a timezone by using the name.

It would be great to have a way to get aTimeZone just by using the name. e.g.
fromName "Australia/Melbourne". Is this possible already?

e.g.

fromName name
	case name of
		'Australia/Melbourne' ->
			Just (australia_melbourne ())
		...
		_ ->
			Nothing

Conversion functions to standards Date and Time ?

Hello,

I've been using your lib (and thank you for doing it by the way) and I think it's missing some helpers to deal with other libs.

For instance, I use rluiten/elm-date-extra to handle some light translations. I also use this lib that we made in my company elm-time-overlap.

Both (and others) use standard elm Date and/or Time types. It would be quite pleasant to have some functions to and from with your Date and DateTime. Or I am missing something?

These are not particularly complicated and I would gladly make a PR with them if you want. I don't know if they would fit in their modules or inside another Util module though.

As I see things, I would love for :

Time.Date.fromDate : Date.Date -> Time.Date.Date
Time.Date.toDate : Time.Date.Date -> Date.Date
Time.Date.toTime : Time.Date.Date -> Time.Time
Time.Date.toWeekday : Time.Date.Weekday -> Date.Day
Time.Date.toMonth : Int -> Date.Month

Time.DateTime.fromDate : Date.Date -> Time.DateTime.DateTime

The last one is debatable because you could just use Date.toTime |> Time.DateTime.fromTimestamp but it could just be that.

What do you think?

offset value

I read the API documentation an as result I have a question:
is there any reason to use offset from midnight. instead the offset of time zones? and why we should use this offset in dateTime in case we have ZonedDateTime.elm

Problem with Etc/UTC±n timezone definitions?

When I select one of the ETC/UTC + or - timezones, it looks as if they have the sign wrong.

Here's a sample from the elm-repl:

> import Time.DateTime as DateTime exposing (zero)
> import Time.ZonedDateTime as ZonedDateTime
> import Time.TimeZones exposing (etc_gmt_plus_8, etc_gmt_minus_8)
> dt = DateTime.dateTime { zero | year = 2018, month = 01, day = 09, hour = 0 }
DateTime { date = Date { year = 2018, month = 1, day = 9 }, offset = 0 }
    : Time.DateTime.DateTime
> dt |> ZonedDateTime.fromDateTime (etc_gmt_plus_8 ()) |> ZonedDateTime.toISO8601
"2018-01-08T16:00:00.000-08:00" : String
> dt |> ZonedDateTime.fromDateTime (etc_gmt_minus_8 ()) |> ZonedDateTime.toISO8601
"2018-01-09T08:00:00.000+08:00" : String

Note the -08:00 in the conversion using etc_gmt_plus_8 and the +08:00 in the conversion using etc_gmt_minus_8.

Looking at the source:

etc_gmt_plus_8_l = unpack "Etc/GMT+8|-08|80|0|"

it seems like this is maybe the -80 there rather than a +80? I didn't take the time to understand the data format there, so I might be totally off base, but it was my first thought as I was looking for a source of the bug.

Reviewing API before publishing to elm-community

For Discussion

Since the API should be solid in the elm-community, I want to review it to make sure that it makes sense for the long-term before publishing. I invite anyone else who is interested to add their comments/concerns/suggestions as well.

Timezone lost when reading from ISO 8601

ZonedDateTime.fromISO8601 takes a TimeZone as an argument and returns a ZonedDateTime representing the parsed date in the specified timezone. However, there is no way to learn the timezone that was written into the ISO 8601 string since ZonedDateTime.fromISO8601 calls DateTime.fromISO8601 and applies a timezone.

My proposal is that ZonedDateTime.fromISO8601 should take only one String argument and return a ZonedDateTime representing the encoded date with the encoded timezone. DateTime.fromISO8601 would then then be implemented as ZonedDateTime.fromISO8601 >> ZonedDateTime.toDateTime.

Parsing fails when milliseconds are explicitly zero

"2017-07-03T11:27:11.000-0400"
    |> Time.DateTime.fromISO8601
    |> toString

Err "Errors encountered at position 25: expected "Z" or expected "+" or expected "-" or expected "−""

"2017-07-03T11:27:11.001-0400"
    |> Time.DateTime.fromISO8601
    |> toString

Ok (DateTime { date = Date { year = 2017, month = 7, day = 3 }, offset = 55631001 })

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.