ISO 8601 ordinal dates

212 views
Skip to first unread message

Christopher Keele

unread,
Feb 3, 2021, 2:54:14 PM2/3/21
to elixir-lang-core
As observed by @ryanbigg on Twitter, "2021-034" is a valid ISO 8601 date.

Specifically, it is an ordinal date descriptor of the format YYYY-DDD. Unlike some of the more exotic ISO 8601 formats, like naming a week of the year or a day+month without a year; it does fully describe a single date in time.

As Ryan observes, Ruby supports parsing ordinal date strings but Elixir does not. Is this something we'd want to add? Honestly the correct behaviour here is almost more surprising to me than our lack of support for it, but I wanted to field a discussion about it.

Paul Schoenfelder

unread,
Feb 3, 2021, 4:48:25 PM2/3/21
to 'Justin Wood' via elixir-lang-core
I think the gotcha here is that there are various "profiles" of ISO-8601, and the one we typically think of as ISO-8601 in practice is the W3C profile used on the web (see https://www.w3.org/TR/NOTE-datetime for a description of what that profile includes). The other common profile is RFC-3339 which also excludes some of the more esoteric formats, like ordinal dates, but also makes at least one modification of its own to the extended time format.

I think we should probably consider this a bug, and fix functions which parse ISO-8601 dates so that they support what's allowed in the ISO-8601 spec, unless we want to explicitly document that Elixir is using one of the common, more restrictive, profiles. Off the top of my head I don't see any reason why extending the parser would be a backwards incompatible change though, and more likely it may fix some bugs where consuming code was assuming that any valid ISO-8601 date was accepted.

Paul
--
You received this message because you are subscribed to the Google Groups "elixir-lang-core" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-co...@googlegroups.com.

Bruce Tate

unread,
Feb 3, 2021, 5:53:23 PM2/3/21
to elixir-l...@googlegroups.com
+1

--
You received this message because you are subscribed to the Google Groups "elixir-lang-core" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-co...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-core/51e44339-31aa-4ec6-93c8-3ca0f7901926n%40googlegroups.com.


--

Regards,
Bruce Tate
CEO

Christopher Keele

unread,
Feb 3, 2021, 8:30:32 PM2/3/21
to elixir-lang-core
WIP PR available here: https://github.com/elixir-lang/elixir/pull/10687

I've proved the concept, but want to step back and solicit feedback, get some discussion going on explicit points I call out in the PR, and think of ways to clean the implementation up a little.

Kip

unread,
Feb 3, 2021, 8:45:22 PM2/3/21
to elixir-lang-core
I think its important to be careful on the scope.  The ISO8601 spec is vast (I am implementing a new lib that implements the whole thing and its a huge task) .

> "I think we should probably consider this a bug, and fix functions which parse ISO-8601 dates so that they support what's allowed in the ISO-8601 spec". This is not a realistic goal for Elixir core I think.

Ordinal dates, explicit and implicit forms of dates, century dates, decade dates, ..... thats a lot of surface area for maintenance that in the spirit of Elixir probably lies better in an external library if required.

Christopher Keele

unread,
Feb 3, 2021, 8:58:01 PM2/3/21
to elixir-lang-core
> I think it's important to be careful on the scope.  The ISO8601 spec is vast (I am implementing a new lib that implements the whole thing and its a huge task).

This is a good point. I'm carefully pulling this particular thread, trying not to unweave the whole tapestry, because it does seem inline with what the stdlib tries to accommodate today:

- We do not handle century dates, decade dates, etc
- We do not handle implicit or "relative" dates
- We do not handle week references

Generally, we only handle explicit year/month/day references to precise calendar dates in string parsing. Ordinal dates are an edge case here: they can be trivially converted to such with the current calendar protocol.

My cursory reading of the ISO8601 spec suggests that this is possibly the only "advanced" date descriptor that is trivial to implement against the calendar protocol today, but I'd appreciate your insight into that! I could have easily overlooked some features; and by implementing ordinal dates, I may be opening a can of worms definitely better left to a library.

José Valim

unread,
Feb 4, 2021, 2:55:54 AM2/4/21
to elixir-l...@googlegroups.com
To complement what Kip says, the ISO standard also focuses a lot on what is agreed between parties. For example, ISO says you can submit a date as 2021-01, as long as both parties agree on that. Does it mean we should support 2021-01 on Elixir out of the box?

There is also the argument in that, if we parse 2021-034 by default, what happens when the user explicitly does not want to support this format? For example, my invoices follow precisely the YYYY-NNN format, and if someone wrote a code that detects between invoice numbers and dates, you may now accidentally parse invoices as dates.

So if we want to support this, maybe we should tag it accordingly:

Date.from_iso8601("2020-323", :ordinal)

That can also be the way to support the :basic format, which we currently do not support.

Paul Schoenfelder

unread,
Feb 4, 2021, 3:59:31 PM2/4/21
to 'Justin Wood' via elixir-lang-core
I think in the case of someone who explicitly wants to omit support for some specific part of the standard, they should use a custom date/time parsing library to handle that, allowing them precise control over what is a valid parse. If you choose to use `DateTime.from_iso8601/`, presumably you are happy to allow any valid ISO-8601 date/time supported by the standard. If you want a subset of ISO-8601, such as RFC-3339, then you'd necessarily want something like `DateTime.from_rfc3339/1`, but rather than add a proliferation of such APIs to Elixir, I'd propose supporting a wide breadth of ISO-8601, and providing support for parsing based on stftime format strings, or going a step further and adding support for some kind of extensible parsing primitives.

Just to illustrate what I mean: Timex took the approach of supporting two format syntaxes out of the box - stftime and the default syntax which aims to be a more readable form of stftime. In addition to the primitive directives common to both syntaxes, the default syntax added directives to parse ISO-8601, RFC-3339, and a variety of other common date/time formats, without having to know the correct format string for those standards.

This was all supported via the `Timex.parse/2` and `Timex.parse/3` API, where the latter allows one to provide a custom tokenizer for the format string. The tokenizer then parses the format string and produces a list of directives. A directive here is the primitive that Timex parsing builds on, and is either one of the built-in directive types, such as `:year4` , or can be a custom parser function. The date/time input string is parsed by applying the directives to the input, feeding the unparsed input from the previous parser as the input to the next parser, until either all parsers were successfully applied, an parsing error occurs, or the input is fully consumed. Internally, both stftime and the default format syntax are implemented as custom tokenizers on top of the same primitives provided to third-party libraries.

In my opinion, I think it was probably a mistake to have named the `from_iso8601` function as such, since it sounds like the intent is to support more or less RFC-3339. Not much that can be done about that now though, which is why it seems to me that the best path forward is to provide some kind of support for parsing based on format strings. Obviously one doesn't need to go all the way to making it fully extensible like I did with Timex, that's just one extreme, but supporting at least stftime seems like a good compromise, since that is very common across languages, and provides an escape hatch when the behavior of `from_iso8601` isn't enough.

Of course we could just rely on the community to provide libraries that support varying degrees of parsing functionality, but I think its a solved-enough problem that providing the core primitives in the standard library and having the community build libraries around those primitives will result in a better ecosystem. The alternative is that every app has like three different custom date/time libraries somewhere in their dependency tree, with potentially varying degrees of support for standards like ISO-8601.

I don't have a strong feeling one way or the other on how best to resolve the original issue here, but I think if we're going to go down the road of saying a function that parses ISO-8601 doesn't _really_ parse ISO-8601, then the standard library should probably provide facilities for parsing based on format strings as an escape hatch. Honestly, after I saw the original email to the list, I realized that I at some point made the same assumption that was made in the standard library, and I'm planning to fix the Timex parser to properly support the spec.

Paul

José Valim

unread,
Feb 4, 2021, 4:58:00 PM2/4/21
to elixir-l...@googlegroups.com
If you choose to use `DateTime.from_iso8601/`, presumably you are happy to allow any valid ISO-8601 date/time supported by the standard.

I disagree with this premise because 2020-04 and 2020 are also valid dates according to ISO8601. Negotiation between parties is also explicitly mentioned in multiple occasions, so to me it is clear not all formats are meant to be supported on all exchanges. Supporting everything ISO lists is going to lead to confusion.

Furthermore RFC3339 contains at least one extension that is incompatible with ISO - so it is not precisely a ISO subset. I would prefer for users to explicitly opt-in to formats where our default is the most common one.

Christopher Keele

unread,
Feb 4, 2021, 5:16:27 PM2/4/21
to elixir-lang-core
José, I am this second composing a slightly more detailed breakdown of this I will post shortly, but wanted to respond directly:

> Supporting everything ISO lists is going to lead to confusion.

Agreed!

>> Presumably you are happy to allow any valid ISO-8601 date/time supported by the standard
> I disagree with this premise because 2020-04 and 2020 are also valid dates according to ISO8601

2020-04 and 2020 are valid dates according to ISO-8601, but not according to the structs we are parsing them into: the standard library makes it clear that Elixir dates are what the spec calls "calendar dates", with a fully-qualified year, month, and day-of-month. I do think we should accept any fully qualified calendar date specified by the standard, but not other dates.

Ordinal dates are interesting because while they are not calendar dates, they are trivially convertible into them.

Kip Cole

unread,
Feb 4, 2021, 5:24:23 PM2/4/21
to elixir-l...@googlegroups.com
Ordinal dates are interesting because while they are not calendar dates, they are trivially convertible into them.

True for the proleptic Gregorian calendar, not necessarily so for other calendars. Since ISO8601 is explicitly only concerned with that calendar I expect this isn’t an issue.

However given ordinal days of the year do exist for all calendars (that I’m aware of since they all have the concept of a day) perhaps adding a callback to `Calendar` of something like `month_and_day_from_ordinal(year, ordinal)` would be something to consider? Then of course implement that for `Calendar.ISO`.

José Valim

unread,
Feb 4, 2021, 5:30:31 PM2/4/21
to elixir-l...@googlegroups.com
If we are adding this conversion only from within from_iso8601 then we probably don't need a new callback because we always need to create a complete isoday reference first.

On Thu, Feb 4, 2021 at 11:24 PM Kip Cole <kipc...@gmail.com> wrote:
Ordinal dates are interesting because while they are not calendar dates, they are trivially convertible into them.

True for the proleptic Gregorian calendar, not necessarily so for other calendars. Since ISO8601 is explicitly only concerned with that calendar I expect this isn’t an issue.

However given ordinal days of the year do exist for all calendars (that I’m aware of since they all have the concept of a day) perhaps adding a callback to `Calendar` of something like `month_and_day_from_ordinal(year, ordinal)` would be something to consider? Then of course implement that for `Calendar.ISO`.



On 5 Feb 2021, at 6:16 am, Christopher Keele <christ...@gmail.com> wrote:

Ordinal dates are interesting because while they are not calendar dates, they are trivially convertible into them.

--
You received this message because you are subscribed to the Google Groups "elixir-lang-core" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-co...@googlegroups.com.

Christopher Keele

unread,
Feb 4, 2021, 5:33:43 PM2/4/21
to elixir-lang-core
> However given ordinal days of the year do exist for all calendars (that I’m aware of since they all have the concept of a day) perhaps adding a callback to `Calendar` of something like `month_and_day_from_ordinal(year, ordinal)` would be something to consider? Then of course implement that for `Calendar.ISO`.

If you look at some of the discussion on my PR, you can see me wondering that exact thing.

It adds `calendar_day_of_year(year, ordinal_day)` and `days_in_year(year)` as private functions to just the `Calendar.ISO`. module, but I suspect they are extrapolatable to any calendar, since they can be computed from the `days_in_month` and `months_in_year` already required by the protocol.

Christopher Keele

unread,
Feb 4, 2021, 5:39:27 PM2/4/21
to elixir-lang-core
Here is an executive summary of my thoughts on the discussion so far:

How much of ISO-8601 should the Elixir standard library support?
 
Of course everyone would love full support out of the box, but as Kip describes this is a massive surface area in terms of development and maintenance, so I also feel as if an external library is the best home for comprehensive approaches, at least for now. We should support the bare minimum to handle common cases.

What is the bare minimum? What are the common cases?

Arguably, ordinal dates are not super common. However, as Paul points out, the `{Date, DateTime, Time, NaiveDatetime}.from_iso8601` class of functions set certain expectations here, and they defer to `Calendar.ISO`, which is why the PR makes changes to `Calendar.ISO.{parse_date, parse_naive_datetime, parse_utc_datetime}` functions. More importantly, the `from_iso8601` functions power the date, time, and datetime sigils that are wildly common and useful, so it is important we get them right.

To me this suggests that we are committed to supporting at a minimum the explicit fully-qualified date, time, and datetime parts of the ISO-8601 spec that do not require "prior agreement" between parties. This takes the following components of the spec off the table:

- The by-agreement expanded year references via `±YYYY` to represent years outside the 0000-9999 range
- References to things that cannot become fully-qualified dates, times, or datetimes: like year, month, week, hour, or minute -resolution references (via the "week" and "reduced precision" notations)
- Things that are not dates, times, or datetimes like durations and intervals
- The by-agreement truncated references like `--MMDD`, which was also removed from the spec

By my reading of the spec, this just leaves support for the extended format (which we already have), and also ordinal date formats (this PR) and the basic formats (as José brings up).

How to indicate desired formats?

I like José's suggesting of supporting a flag, but it gets kind of complicated as there are several dimensions here even in our reduced case. Dates, times, and datetimes support either basic or extended notations; dates and datetimes support calendar dates or ordinal dates; both are applicable to any parsing.

If we went with this approach I'd lean towards always accepting either form for one of the dimensions, and using flags to the sigil and parsing functions to indicate intent for the other.

On the other hand, we are claiming to support ISO-8601 here (with a reduced surface area of only supporting calendar dates), so I'm more inclined to say we should accept any permutation of these options.

Someone may only want to support some of these permutations, though the feedback of "invalid date" from a `from_iso8601` function for something supported by ISO-8601 would be kind of strange. But if there's strong support for that, I'd compromise by saying we should accept everything by default, and then support optional flags to restrict the what the parser views as valid.

José Valim

unread,
Feb 4, 2021, 5:45:27 PM2/4/21
to elixir-l...@googlegroups.com
 
I like José's suggesting of supporting a flag, but it gets kind of complicated as there are several dimensions here even in our reduced case. Dates, times, and datetimes support either basic or extended notations; dates and datetimes support calendar dates or ordinal dates; both are applicable to any parsing.

Are we 100% sure that ordinal datetimes are part of ISO8601? Kip, can you please confirm?
 
If we went with this approach I'd lean towards always accepting either form for one of the dimensions, and using flags to the sigil and parsing functions to indicate intent for the other.

I am not necessarily worried about sigils because sigils are always compile-time literals. It is probably fine to enforce a given format there rather than multiple ones.

Christopher Keele

unread,
Feb 4, 2021, 5:47:59 PM2/4/21
to elixir-lang-core
> I am not necessarily worried about sigils because sigils are always compile-time literals. It is probably fine to enforce a given format there rather than multiple ones.

Agreed! What I am wondering here is if the sigils -- and other parsing functions -- should probably be universally accepting; ie not require specifying a format and letting any valid date through by default. Does that seem reasonable to you?

José Valim

unread,
Feb 4, 2021, 5:50:41 PM2/4/21
to elixir-l...@googlegroups.com
I think sigils should only ever accept the extended format. Imagine reading ~D[2020-01-03] and then two lines below ~D[20200103]. :) My mind is not yet made on the parsing one but I was thinking about an explicit flag :basic | :extended | :ordinal.

--
You received this message because you are subscribed to the Google Groups "elixir-lang-core" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-co...@googlegroups.com.

Kip Cole

unread,
Feb 4, 2021, 5:50:49 PM2/4/21
to elixir-l...@googlegroups.com
From ISO 8601-1:2019(E):

5.2.3 Ordinal date


5.2.3.1 Complete representations

A complete representation of an ordinal date shall be as follows.

a) Basic format: [year][dayo] EXAMPLE 1 1985102

b) Extended format: [year][“-”][dayo] EXAMPLE 2 1985-102

If by agreement, expanded representations are used, the formats shall be as specified below. The interchange parties shall agree on the additional number of digits in the time scale component year.

5.2.3.2 Expanded representations

In the examples below it has been agreed to expand the time scale component year with two digits.

a) Basic format: [±][year(6)][dayo] EXAMPLE 1 +001985102

b) Extended format: [±][year(6)][“-”][dayo] EXAMPLE 2 +001985-102 


--
You received this message because you are subscribed to a topic in the Google Groups "elixir-lang-core" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/elixir-lang-core/CcXpeMQhsmU/unsubscribe.
To unsubscribe from this group and all its topics, send an email to elixir-lang-co...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-core/CAGnRm4JNeGkCNW_6ic2XkxTkFV3uyMT%2B3EZYJuguhzzZfpOnpQ%40mail.gmail.com.

Christopher Keele

unread,
Feb 4, 2021, 5:58:01 PM2/4/21
to elixir-lang-core

> I think sigils should only ever accept the extended format. Imagine reading ~D[2020-01-03] and then two lines below ~D[20200103]. :)

Sold! Also, technically the sigils support any calendar (ISO and its parser are just used by default), so upon reflection ISO flags don't belong here. And since they are literals, we should approach them from an Elixir-ish code philosophy where explicitness and uniformity are valued. Extended all the way.

> My mind is not yet made on the parsing one but I was thinking about an explicit flag :basic | :extended | :ordinal.

Basic vs extended is a separate concern from ordinal dates vs calendar dates. Brainstorming some options here, but what about a keyword list? `format: :basic | :extended | :any` with `:any` as default; and `date: :calendar | :ordinal | :any` with `:any` as default?


José Valim

unread,
Feb 4, 2021, 6:08:00 PM2/4/21
to elixir-l...@googlegroups.com
Ah, thanks Kip. Ordinal also has both extended and basic forms too.

Here is another question: if we are going to parse ordinals by default, how am I going to format to the ordinal format? Use strftime exclusively?

The other annoyance is while an extended ordinal is distinct enough from a regular extended DateTime, the distinction between basic ordinal and basic DateTime is a single character: “2020012134523”. There will also be ambiguity if we ever decide to support more than four digits on the year. This is enough to say that:

* it is not possible to parse all formats within a single function without additional user instructions 

* if the basic format supports both regular and ordinal, there can be ambiguity if 5 year digits are ever supported in the future

This is enough information to me that ordinal should be its own thing, with possibly basic_ordinal and extended_ordinal, but at this point I wonder why add it to the stdlib.

You received this message because you are subscribed to the Google Groups "elixir-lang-core" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-co...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-core/15198E56-9D02-4A0E-8E6D-AB905531112A%40gmail.com.

Christopher Keele

unread,
Feb 4, 2021, 6:20:21 PM2/4/21
to elixir-lang-core
> Ordinal also has both extended and basic forms too.

Yup, basic/extended can apply to the entire date/time/datetime string (but must be universally applied to it, saving at least some headache).

> The distinction between basic ordinal and basic DateTime is a single character

I agree that basic ordinals is possibly the worst way to format a date, for the reasons you describe. But it is technically unambiguous, and

> There will also be ambiguity if we ever decide to support more than four digits on the year.

This is technically not true for 5-digit years, so long as we choose to use ISO-8601: it has a provision for this by prefixing the year with a plus or minus. This is described as being 'by agreement only' though so omitted from my envisioned scope.

In fact now that I think about it we are probably violating the spec today: we support negative signs to indicate BC for 4-digit years. By my reading of the spec we should be requiring that negative years supply 5 digits.

> At this point I wonder why add [ordinal dates] to the stdlib.

My motive here really is just to be spec-compliant. There may be a point where we decide we are going off-spec to avoid many of the complexities raised in this discussion, happy to have that conversation too (though probably should be its own thread?)

Christopher Keele

unread,
Feb 4, 2021, 6:22:41 PM2/4/21
to elixir-lang-core
> Here is another question: if we are going to parse ordinals by default, how am I going to format to the ordinal format? Use strftime exclusively?

I'm fine with that, to me this is a case of following the parsing spec and being liberal in what we accept, conservative in what we emit (by default).

José Valim

unread,
Feb 4, 2021, 6:46:04 PM2/4/21
to elixir-l...@googlegroups.com
In fact now that I think about it we are probably violating the spec today: we support negative signs to indicate BC for 4-digit years. By my reading of the spec we should be requiring that negative years supply 5 digits.

My understanding is that the number of extra digit years is adjustable. So it could be  0 extra digits or even 2. To quote Wikipedia:

The "basic" format for year 0 is the four-digit form 0000, which equals the historical year 1 BC. Several "expanded" formats are possible: −0000 and +0000, as well as five- and six-digit versions.


I am not sure if this means the basic format does not support extra digits nor negative years. If they do, then there may be ambiguity.

Kip Cole

unread,
Feb 4, 2021, 6:49:56 PM2/4/21
to elixir-l...@googlegroups.com
Per the standard:

The Gregorian calendar defines a calendar year to be either 365 or 366 days, which begins on January 1 and ends on December 31. Each Gregorian calendar year can be identified by a 4-digit ordinal number beginning with ‘0000’ for year zero, through ‘9999’.

4.3.2 Calendar year and years duration

The calendar year and years duration are represented as follows:

a) Implied: [YYYY]
EXAMPLE 1 ‘1985’ (calendar year 1985)

b) Explicit: [i][“Y”]
EXAMPLE 2 ‘12Y’ (twelve years)

The number of digits may exceed 4 in the case of expanded representation, in which case the year number may be preceded by a minus sign to indicate a year preceding year zero.

 

Only the Expanded (by agreement) year allows more than 4 digits and allows a sign (+ or -)



Christopher Keele

unread,
Feb 4, 2021, 6:53:20 PM2/4/21
to elixir-lang-core
The most straight-forward source I've been referencing is the wikipedia page on ISO-8601, augmented by the spec itself and some explanatory articles for confusing cases. But the wiki does a good job with this one:

> It therefore represents years from 0000 to 9999, year 0000 being equal to 1 BC and all others AD.

> To represent years before 0000 or after 9999, the standard also permits... [A]n expanded year representation ±YYYYY [that] must have an agreed-upon number of extra year digits beyond the four-digit minimum, and it must be prefixed with a + or − sign.

Additionally:

> The expansion of the year representation[must be used] only by prior agreement between the sender and the receiver.

Also concerning:

> Values in the range [0000] through [1582] shall only be used by mutual agreement of the partners in information interchange.

José Valim

unread,
Feb 4, 2021, 6:53:57 PM2/4/21
to elixir-l...@googlegroups.com
Thank you Kip, so there is no ambiguity in the basic format on regular basis ordinal due to no support for extra digits.

Christopher Keele

unread,
Feb 4, 2021, 6:55:24 PM2/4/21
to elixir-lang-core
So by my read, the leading minus is part of the expanded year spec, and the expanded year spec is by agreement only, because all parties have to agree on how much the year is being expanded, to avoid ambiguity with basic ordinal notation.

What a tangled web we weave!

Christopher Keele

unread,
Feb 4, 2021, 7:02:03 PM2/4/21
to elixir-lang-core
I don't think we can (trivially without deprecation cycles) remove support for the leading minus to move back into spec, so for this reason alone we are committed for a while to not being spec compliant.

Probably a good juncture to ask: should we just commit to not being spec compliant, shore up the docs around how we handle date parsing?

In an ideal world that also kinda implies a deprecation cycle where we try to move away from "ISO" related terminology in module and function names, which is probably even a bigger pain though...

José Valim

unread,
Feb 4, 2021, 7:03:01 PM2/4/21
to elixir-l...@googlegroups.com
Correct, the number of extra digits can be zero. And since we do support negative years, it is a representation we need to support.

This conversation makes me think that the simplest is to not support ordinal dates. We will simply support what is required to represent our own data. So if we ever support 5 digit years internally, then we change the formatting/parsing functions too, but not before.

That is supported by the spec because everything on ISO is per agreement. unless it explicitly says that supporting the regular format also requires supporting the ordinal one.

Kip Cole

unread,
Feb 4, 2021, 7:17:10 PM2/4/21
to elixir-l...@googlegroups.com
ISO 8601 defines the idea of a profile to identify feature compatibility. My observation is that its not worth it - too complex for the std lib. Nevertheless, perfectly ok to implement a subset of features.

If you’d like I can write a PR that is just an ISO8601 conformance statement for Calendar.ISO (given that I have purchased the standard docs and have a reasonable chance of stating it more-or-less correctly.



15 Profiles 15.1 General

The ISO 8601 series includes many features and in many cases allows several different formats to represent a single feature or multiple interpretations for a single format. Vendors implementing the ISO 8601 series may implement only a subset of its features, or different representations of a given feature, causing interoperability issues with other implementations.

An ISO 8601 profile is a specification of how the ISO 8601 series is to be used for a particular context (application, discipline or community), specifying the necessary features and representations to implement and providing interpretations applicable to the particular context.

This document provides one such profile in Annex A.
NOTE This document supports the creation of a registration agency for ISO 8601 profiles, which registers

 


Christopher Keele

unread,
Feb 4, 2021, 7:17:58 PM2/4/21
to elixir-lang-core
> That is supported by the spec because everything on ISO is per agreement. unless it explicitly says that supporting the regular format also requires supporting the ordinal one.

Hmm, would love Kip's take on this, but based on my reading:

- The minus sign comes with the year extension. Extension support is optional, with mutual agreement on how much they are extended, and as you point out, extending it by 0 digits is valid.
  So we could just document how we've chosen to support this. But we'd need to add support for a leading plus as well.

- Neither basic and extended support, nor calendar vs ordinal date support, mentions mutual agreement or extensions.
  But each section leads off with the ambiguous phrase "When the application identifies the need for a complete representation of a calendar|ordinal date"...
  So we could just say that Elixir has identified the need for representing calendar dates, but not ordinal ones?

Christopher Keele

unread,
Feb 4, 2021, 7:23:23 PM2/4/21
to elixir-lang-core
It also goes on to say "When the application identifies the need for a complete representation of a calendar date, it shall be one of the numeric expressions as follows". So we can in fact ditch the ordinal support!

So my takeaway is that if we add some docs around our choices here, and our use of the year extension for the minus, and support leading plusses, we are in spec without adding ordinal date or basic format support.

Kip Cole

unread,
Feb 4, 2021, 7:27:28 PM2/4/21
to elixir-l...@googlegroups.com
So my takeaway is that if we add some docs around our choices here, and our use of the year extension for the minus, and support leading plusses, we are in spec without adding ordinal date or basic format support.

Yes, I think for the std lib, being clear on the implementation scope is a good idea. If we think about this pragmatically, the common use cases are parsing machine generated dates like in HTTP headers. Less about parsing human readable UI content. So restricting conformance and documenting clearly seems sound.



Christopher Keele

unread,
Feb 4, 2021, 7:30:43 PM2/4/21
to elixir-lang-core
Sounds great to me, I'll start a PR.

Christopher Keele

unread,
Feb 4, 2021, 8:20:32 PM2/4/21
to elixir-lang-core
WIP PR here. Wanted to solicit feedback on some of the language early, specifically these bits. Will resume work on it a little later!

José Valim

unread,
Feb 5, 2021, 2:44:10 AM2/5/21
to elixir-l...@googlegroups.com
I like the direction of the PR a lot.

My only remaining question is if we should do anything about the fact to_iso8601 supports basic but we don't support basic on parsing. Our options are:

1. Keep as is
2. Parse basic
3. Deprecate basic to_iso8601

I have already fixed master to raise if someone is trying to convert a date with a negative year to basic.

Christopher Keele

unread,
Feb 5, 2021, 8:02:56 PM2/5/21
to elixir-l...@googlegroups.com
I think the fact that we support emitting basic is very useful for things like files with timestamps in names; to me the most harmonious thing would be supporting in the parser as well via the flag mechanism you've proposed. I may take a stab at it but I think a separate PR is the best way to go in implementing it, so any surprising considerations can be discussed separately.

Reply all
Reply to author
Forward
0 new messages