Elixir: Allow Time in [hh]:[mm] format

Created on 7 Jul 2020  路  8Comments  路  Source: elixir-lang/elixir

In the Elixir docs, it is mentioned:

Time representations with reduced accuracy are not supported.

Applications often work with time without seconds. It would then be convenient for Elixir to be able to parse a time without seconds.

Libraires rely on Time.from_iso8601/2 for parsing user input. User input can come from different languages (e.g. JavaScript), which may format the time string without the seconds. We have to append + ':00' for Elixir in case seconds would be omitted.

For example, in JavaScript, the new Temporal API provides a toString() method that will return a ISO string:

Temporal.Time.from('03:24:00').toString()
"03:24"

Temporal.Time.from('03:24:01').toString()
"03:24:01"

We see that if the seconds are 0, the seconds are omitted. I can't send that value as-is for Absinthe that uses the Time.from_iso8601/2 function. I'd have to count the number of ":", and if only one present, append ":00". That makes me sad.

Most helpful comment

I have opened an issue on Temporal repo. There are many scenarios where reducing accuracy is problematic. Even if we supported it, it would be an opt-in flag because you should not discard information out of the box. The scenario described above is not an example or an use case for adding reduced accuracy to Elixir. It could even lead to incorrect times and wrong chronological order when writing to databases (which also make this important distinction).

All 8 comments

The reason why we don't support reduced accuracy is exactly because it is unclear "03:24" means "it is actually 03:24:00 but we are saving on the representation" or "it is actually 03:24 because we don't know about seconds". IIRC, the ISO standard clarified on later versions that it should be used for the latter, so JS is actually in the wrong here for removing precision from your data.

In Wikipedia it says:

Either the seconds, or the minutes and seconds, may be omitted from the basic or extended time formats for greater brevity but decreased accuracy

From the freely available ISO document at https://www.loc.gov/standards/datetime/iso-tc154-wg5_n0038_iso_wd_8601-1_2016-02-16.pdf it says:

4.2.2.3 Representations with reduced accuracy
If the degree of accuracy required permits, either two or four digits may be omitted from the
representation in 4.2.2.2.

So it rather seems, from this content, that it allows to save on the representation, if you can allow decreased accuracy.

Maybe you have an updated version, but I see that I'd have to pay hundreds of dollars to access the document of 2019 :-/

Nevertheless I don't see why we have to be such purists about that. Why not take a more pragmatic stance. Especially that in the case that I don't know the seconds, which seem to be the acceptable case for omitting seconds according to your research, Elixir still doesn't allow me to create a Time with omitted seconds.

I have opened an issue on Temporal repo. There are many scenarios where reducing accuracy is problematic. Even if we supported it, it would be an opt-in flag because you should not discard information out of the box. The scenario described above is not an example or an use case for adding reduced accuracy to Elixir. It could even lead to incorrect times and wrong chronological order when writing to databases (which also make this important distinction).

The current version of ISO 8601-1:2019(E) states:

5.3.1.3 Representations with reduced precision
The time scale component second, or the time scale components of both second and minute, may be omitted from the representation in 5.3.1.2.

For the record: this is the issue reported to Temporal: https://github.com/tc39/proposal-temporal/issues/734

Thanks @kipcole9! I remember a recommendation about the precision being omitted only with agreement from both parties on the meaning of the omission. Am I dreaming? :)

@josevalim there is indeed such a reference but only in section 5.5 Time Interval where it states:

NOTE By mutual agreement of the communicating partners, if the start or end of a time interval is supplied out of band, an expression of duration can be sufficient to express a time interval.

I do note however than in the introductory section there is the following "Fundamental Principles" which to my reading does create the expectation that precision should be representable. As you know well, this standard - both the basic Part 1 and the extensions in Part 2 are "comprehensive". I appreciate that Elixir has a clear an unambiguous position that allows for libraries to manifest other possibilities. But it may be that adding the idea of precision to the date and time structures would be a reasonable proposal for discussion. As I think you know, @wojtekmach has applied that in his calendar_interval library and the principle seems to hold up well.

Here is a screen shot of the relevant section which I believe is acceptable under fair use and which doesn't copy/paste well from the PDF (I have purchased licenses for both Part 1 and Part 2).

image

But it may be that adding the idea of precision to the date and time structures would be a reasonable proposal for discussion. As I think you know, @wojtekmach has applied that in his calendar_interval library and the principle seems to hold up well.

Thanks for the shout out about https://github.com/wojtekmach/calendar_interval :D As much as I'd personally like to see ideas explored in that library ported to core, I'm worried that adding precision to %Date{} and %Time{} (and others) might be too big of a change. We could have date = %Date{year: 2020, month: 7, precision: :month} (also see https://tc39.es/proposal-temporal/docs/yearmonth.html :)) but it is unclear to me what date.day is going to be: 1 or nil. If it's nil this might break peoples expectations about the value being an integer but if it's 1 it's not great either because _we don't know the day_.

Btw, and It's not like we can do anything about it anymore, but worth mentioning that:

iex> Time.compare(~T[09:00:00], ~T[09:00:00.000])
:eq

which while it is the only reasonable answer (given our return options are :lt, :eq, :gt) it isn't perfectly in line with what we said above that these two values are not the same.

To plug my calendar_interval library once more, in there everything is an interval, 09:00:00 is an interval from 09:00:00.0 to 09:00:00.9 (and .00 to .99, etc). And so, instead of asking the question is 09:00:00.000 the same as 09:00:00, we could ask a question is 09:00:00.000 _in_ 09:00:00, and the answer is a much more convincing yes. Anyhow, sorry for a digression!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

andrewcottage picture andrewcottage  路  3Comments

Irio picture Irio  路  3Comments

cmeiklejohn picture cmeiklejohn  路  3Comments

sashaafm picture sashaafm  路  3Comments

josevalim picture josevalim  路  3Comments