elixir-cldr / cldr_dates_times

Date & times formatting functions for the Common Locale Data Repository (CLDR) package https://github.com/elixir-cldr/cldr
Other
69 stars 13 forks source link

Date Intervals and 00:00 vs 24:00 #2

Open LostKobrakai opened 6 years ago

LostKobrakai commented 6 years ago

I'm currently working on the scheduling part of my application and I'm trying to use ranges like this: [from, to). This works fine besides for the dreaded 01.01.… 00:00 – 02.01.… 00:00 case. I'm not sure if there's anything specific in cldr, but I'd really like the option of having the option to format that as 01.01.… 00:00 – 01.01.… 24:00 instead. Even though it's technically the same the latter is seems more intuitive to read. Is that something you see you package to support?

Also I've seen cldr does have information about formatting intervals as well. I don't need it, but that might be a nice addition possibly after 1.0.

kipcole9 commented 6 years ago

Hmmm, do any of the format symbols at https://hexdocs.pm/ex_cldr_dates_times/readme.html#formatting-symbols-for-hour-of-day https://hexdocs.pm/ex_cldr_dates_times/readme.html#formatting-symbols-for-hour-of-day achieve what you want for a given time?

Yes, formatting intervals is supported in CLDR, its on my list for a 1.1 release - along with multi-calendar support and support for different weekend and start of week definitions.

On 20 Nov 2017, at 9:17 am, Benjamin Milde notifications@github.com wrote:

I'm currently working on the scheduling part of my application and I'm trying to use ranges like this: [from, to). This works fine besides for the dreaded 01.01.… 00:00 – 02.01.… 00:00 case. I'm not sure if there's anything specific in cldr, but I'd really like the option of having the option to format that as 01.01.… 00:00 – 01.01.… 24:00 instead. Even though it's technically the same the latter is seems more intuitive to read. Is that something you see you package to support?

Also I've seen cldr does have information about formatting intervals as well. I don't need it, but that might be a nice addition possibly after 1.0.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/kipcole9/cldr_dates_times/issues/2, or mute the thread https://github.com/notifications/unsubscribe-auth/AAA-F_kwVg6Nnod4MBzaaL-iHosbyZADks5s4MUqgaJpZM4Qjm3V.

LostKobrakai commented 6 years ago

Yeah it does, but the 24:00 format works differently to what I expected. Maybe I'll just leave of the time for the cases where it's midnight. Thanks for the input.

kipcole9 commented 6 years ago

I'm happy to continue the conversation. Its a notoriously tricky area as you know but I'd like to find a way to improve it if thats possible.

I didn't really understand the specifics of what you're after so if you're prepared to help me understand the need, I'm good to work on a solution.

LostKobrakai commented 6 years ago

It's not really a issue with cldr per se, but rather a UI issue.

I've jobs, which need to be advertised to people and some jobs are only timed to days, where I simply store a timestamp with 00:00. Now if a job is supposed to happen either on the 1. or 2. of january it's going to be an interval of [1.1. 00:00 – 3.1. 00:00), which is fine from a computational standpoint, but formatting it as 1.1. 00:00 – 3.1. 00:00 might lead to confusion about the 3.1..

From what I've read 3.1. 00:00 == 3.1. 24:00, so this one would be even more confusing. I thought I could show it as 1.1. 00:00 – 2.1. 24:00, but that is simply incorrect. So I either need to go with 1.1. 00:00 – 2.1. 23:59, which is ugly to scan over in a table or not showing the time for those jobs, which does mean there are jobs in tables with times and ones without, which is also not too nice to scan over.

kipcole9 commented 6 years ago

Would a format like:

iex> Cldr.DateTime.to_string %{year: 2018, month: 1, 
...>  day: 1, hour: 0, minute: 1, second: 1, calendar: Calendar.ISO}, 
...>  format: "YYYY-MMM-dd KK:mm"
{:ok, "2019-Jan-01 00:01"}

Remove some of the ambiguity?

LostKobrakai commented 6 years ago

Ok, it seems my research in the middle of the night was a bit lacking. It's ok to use 24:00 of a specific day for the same time(stamp) as 00:00 of the following day (e.g. ISO 8601). This doesn't even seem ambiguous (and wikipedia seems to support that).

This is what i was talking about:

iex> Cldr.DateTime.to_string ~N[2018-01-02 00:00:00], 
...> format: "YYYY-MMM-dd HH:mm", prefer_end_of_day_notation: true
{:ok, "2018-Jan-01 24:00"}
iex>Cldr.DateTime.to_string ~N[2018-01-02 00:00:00], 
...> format: "YYYY-MMM-dd HH:mm", prefer_end_of_day_notation: false #default
{:ok, "2018-Jan-02 00:00"}

iex> Cldr.DateTime.to_string ~N[2018-01-02 00:00:01], 
...> format: "YYYY-MMM-dd HH:mm", prefer_end_of_day_notation: true
{:ok, "2018-Jan-02 00:00"}
iex>Cldr.DateTime.to_string ~N[2018-01-02 00:00:01], 
...> format: "YYYY-MMM-dd HH:mm", prefer_end_of_day_notation: false #default
{:ok, "2018-Jan-02 00:00"}

I'm just not sure about the rounding (e.g. having a single millisecond tilt the used notation, while the format might not even show seconds).

kipcole9 commented 6 years ago

Or with the "bb" format:

iex>  Cldr.DateTime.to_string(%{year: 2018, month: 1, day: 1, hour: 0, minute: 0, 
...>  second: 0, calendar: Calendar.ISO}, 
...>  format: "yyyy-MMM-dd KK:mm bb")
{:ok, "2018-Jan-01 00:00 midnight"}

iex>  Cldr.DateTime.to_string(%{year: 2018, month: 1, day: 1, hour: 0, minute: 1, 
...>  second: 0, calendar: Calendar.ISO}, 
...>  format: "yyyy-MMM-dd KK:mm bb")
{:ok, "2018-Jan-01 00:01 AM"}
LostKobrakai commented 6 years ago

I'm using tables, which are already packed with information, so having a whole additional word there is one issue for me, but the other essential distinction for me is the different date as a result of using 24:00 instead of 00:00.

LostKobrakai commented 6 years ago

To quote the wiki text of ISO 8601:

The notation "00:00" is used at the beginning of a calendar day and is the more frequently used. At the end of a day use "24:00". "2007-04-05T24:00" is the same instant as "2007-04-06T00:00"

source

LostKobrakai commented 6 years ago

Regarding to which unit to "round": I'd consider it being configurable and defaulting to seconds to the the sane option, so if it's one second of of midnight it's always going to use the following day and 00:…

kipcole9 commented 6 years ago

My current thinking for your comments:

  1. Add Cldr.Time.round/2 and Cldr.DateTime.round/2 that round the timing to a specified time increment. Increment can be any of year, month, day, hour, minute, second with the default being second and. The :rounding_mode can be specified with the default being :half_even.

    • Is there a requirement to round to other than whole minutes, seconds, etc? I see some reference in HR-related used that rounding to the nearest 15 minutes (or other number) is useful.
  2. Then you can use the k format to represent the end of day as 24:00 without any additional formatting changes. I've checked the provided intervals in CLDR and they don't do that in the defined formats - so I'll make sure user-defined internal formats are possible for 1.1.

I'll work on Time.round/2 for 1.0.0-rc.1 this weekend.

LostKobrakai commented 6 years ago

That sounds useful. Rounding is certainly a nice feature to have and will be necessary for such a feature. The only issue I see is k/kk doesn't seem to be what I'm talking about – and I'm still not sure if what I'm looking for should be supported by this package. It's usecase is only shortly noted in the cldr docs here.

Formatting 2017-01-02T00:00:00+00:00 we'll get this: yyyy-MMM-dd HH:mm => 2017-Jan-02 00:00 yyyy-MMM-dd kk:mm => 2017-Jan-02 24:00 yyyy-MMM-dd ~~:mm + end-of-day context => 2017-Jan-01 24:00

(by the way: yay for the ambiguity between kk and a potential ~~.)

It's even more apparent for 2017-01-02T00:05:00+00:00 yyyy-MMM-dd HH:mm => 2017-Jan-02 00:05 yyyy-MMM-dd kk:mm => 2017-Jan-02 24:05 yyyy-MMM-dd ~~:mm + end-of-day context only for midnight => 2017-Jan-02 00:05 (my use-case)

And while we're at it this is also used in some locales: 2017-01-02T01:05:00+00:00 yyyy-MMM-dd HH:mm => 2017-Jan-02 01:05 yyyy-MMM-dd kk:mm => 2017-Jan-02 01:05 yyyy-MMM-dd ~~:mm + general end-of-day context => 2017-Jan-01 25:05

Cldr does note this as well

To account for customary usage in some countries, APIs should allow for formatting times that go beyond 23:59:59. For example, in some countries it would be customary to indicate that opening hours extending from Friday at 7pm to Saturday at 2am in a format like the following:

Friday: 19:00 – 26:00

source

There just doesn't seem to be a symbol in the symbols-table, which would support such a notation; Probably because it would mean a lot of work for implementations, because it does not only impact the symbol's replacement itself, but also potentially all date (and date related) symbols as well, like: 2017-01-01 00:00 vs. 2016-12-31 24:00