Where can I find the reference for defining dates of the dd/mm/yyyy format?

Asked

Viewed 292 times

3

I’m doing the documentation of an API, but I don’t know where I can find what defines the date in the Brazilian, Italian, etc., formatting styles dd/mm/yyyy.

Dates in format yyyy-mm-dd are defined by ISO 8601 of 1988. There are all the explanations about formatting, usage etc.

I would like to know what defines the date in the format dd/mm/yyyy, which is used in countries like Algeria, Brazil, Italy among others, to leave reference in my API.

I’m getting references like this response of stackoverflow , and also to avoid problems like this , in which it is not known what the formatting of the type fields date.

Where can I put the reference that the date is to be used in the format dd/mm/yyyy?

  • ABNT NBR 5892:2019 http://www.abnt.org.br/noticias/6691-representacao-e-formatos-tempo-datas-horas-presentationApplication

1 answer

3


Use ISO 8601 format

It depends a lot on what you want to do with your API, but in general, a specific date format for each location is a problem of presentation. Internally your(s) system(s) should(m) work with some single, locality-independent format, and only when displaying to the user would you care about formatting (assuming you have the information about the user’s location, to use the respective format).

Generally, the idea of an API is to be consumed by other programs/systems, so don’t invent: use the format ISO 8601, which is standardized, unambiguous, created precisely for the exchange of information relating to dates and times, and has support for most languages and Apis (in addition to having the endorsement of W3C, of IETF and last but not least, the XKCD).

If someone is going to send data to your API, simply have them convert it to ISO 8601 format (remembering that regardless of the format chosen, they will have to convert anyway). If someone is going to consume your API, let it be documented that they are returned in ISO 8601 format, and they turn to display the date to their users (it is no longer your responsibility how each consumer of the API will display the data, the important thing is you leave documented the format returned and each manipulates in the way you think best).


But if you want to use dd/mm/yyyy...

The context has not been explained, but you may very much need the format to be "dd/mm/yyyy". If so, I am sorry to inform you that it is quite difficult to have a single official source to support or justify this - and any other - choice, and even more difficult to find adequate (and consistent) support of languages and API’s for such sources (some have more, others less, varies greatly).

Us comments the standard was quoted ABNT NBR 5892:2019, specific to the Brazilian date format. The official document is paid so I will not put it in full here (yes, I bought it), but the only excerpt that mentions a date format next what you need is:

Date, for day, month and year

They shall be written in the following order: day, month and year. When elements are represented only by Arabic numerals, they must be separated by a point and without space between them.

That is, according to ABNT, today’s date should be written as "27.05.2020" (including in the document itself has an example: "04.04.2018"). Disappointing that in practice nobody follows an official standard, no? After all, in Brazil’s day to day, we usually use "05/27/2020" (or the formats in full, such as "May 27, 2020", which are also mentioned in the standard). In any case, the ABNT standard would not serve as a basis for your decision to use "dd/mm/yyyy".

CLDR

So let’s go to the other source: the Unicode Common Locale Data Repository (CLDR). It is basically a large repository of location-related information, including different date formats, units of measurement, number format, etc.

All these definitions are scattered in multiple files, and in them you can find the different date formats by locale. But I’m telling you, it’s not that simple.

For example, in the archive referring to the Portuguese of Portugal, we have:

<dateFormatLength type="medium">
    <dateFormat>
        <pattern>dd/MM/y</pattern>
    </dateFormat>
</dateFormatLength>
<dateFormatLength type="short">
    <dateFormat>
        <pattern draft="contributed">dd/MM/yy</pattern>
    </dateFormat>
</dateFormatLength>

Already in the file referring to the Portuguese of Brazil, there are no such definitions, so he should use the definition of generic file of the Portuguese language, which has the following:

<dateFormatLength type="medium">
    <dateFormat>
        <pattern>d 'de' MMM 'de' y</pattern>
    </dateFormat>
</dateFormatLength>
<dateFormatLength type="short">
    <dateFormat>
        <pattern>dd/MM/y</pattern>
    </dateFormat>
</dateFormatLength>

The files cited above were consulted on May 27, 2020.

In the same repository you will find files for several locales different, such as the italian and the algerian.

So, what is the actual "Brazilian" format? What about the "Portuguese", "Italian" or "Algerian" formats? Well, it depends on the language used. For example, in Javascript:

let d = new Date('2020-05-27T00:00');
[
 'pt-BR', // Brasil
 'pt-PT', // Portugal
 'it-IT', // Itália
 'ar-DZ'  // Argélia
].forEach(locale => console.log(locale, d.toLocaleDateString(locale)));

Testing on Chrome, the output was:

pt-BR 27/05/2020
pt-PT 27/05/2020
it-IT 27/5/2020
ar-DZ 272020/5/

I also tested locally running on Node (without having the locales installed) and all returned "2020-5-27".

Already using Java (API java.time, available for JDK >= 8):

static void printDate(Locale locale) {
    System.out.println("Locale: " + locale);
    for (FormatStyle style : Arrays.asList(FormatStyle.MEDIUM, FormatStyle.SHORT)) {
        DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDate(style).withLocale(locale);
        System.out.printf("%7s %s\n", style, formatter.format(LocalDate.now()));
    }
}

printDate(new Locale("pt", "BR"));
printDate(new Locale("pt", "PT"));
printDate(new Locale("ar", "DZ"));
printDate(new Locale("it", "IT"));

The output varies depending on the version. In Java 8 was:

Locale: pt_BR
 MEDIUM 27/05/2020
  SHORT 27/05/20
Locale: pt_PT
 MEDIUM 27/mai/2020
  SHORT 27-05-2020
Locale: ar_DZ
 MEDIUM 27/05/2020
  SHORT 27/05/20
Locale: it_IT
 MEDIUM 27-mag-2020
  SHORT 27/05/20

In Java 9:

Locale: pt_BR
 MEDIUM 27 de mai de 2020
  SHORT 27/05/20
Locale: pt_PT
 MEDIUM 27/05/2020
  SHORT 27/05/20
Locale: ar_DZ
 MEDIUM 27?/05?/2020
  SHORT 27?/5?/2020
Locale: it_IT
 MEDIUM 27 mag 2020
  SHORT 27/05/20

And in Java 13:

Locale: pt_BR
 MEDIUM 27 de mai de 2020
  SHORT 27/05/2020
Locale: pt_PT
 MEDIUM 27/05/2020
  SHORT 27/05/20
Locale: ar_DZ
 MEDIUM 27?/05?/2020
  SHORT 27?/5?/2020
Locale: it_IT
 MEDIUM 27 mag 2020
  SHORT 27/05/20

That is, if I wanted the date as "27/05/2020" and was using the locale pt_BR, in Java 8 should use the "MEDIUM" format, in Java 13 the "SHORT" format and in Java 9 I would have to change the locale to pt_PT (or I simply give up using the locale and use the fixed format "dd/MM/yyyy"). This inconsistency is mainly due to the fact that from JDK 8 onwards Java started to follow CLDR, but this only became the option default from JDK 9 onwards. And each version has more updates (which can also follow any changes in the CLDR definitions themselves), causing these differences (example).

The queries that appear to the locale ar_DZ (Algeria) correspond to character "RIGHT-TO-LEFT MARK", which basically serves to indicate that the text in question is written from right to left. That’s why in Javascript I got "272020/5/" (the browser rendered correctly, already in Java I used a terminal that does not support rendering from right to left). But note that this character was only included from Java 9.

If you want, see this code running on Ideone.com (Java 12), and notice that the browser correctly renders the RIGHT-TO-LEFT MARK.

Just to quote one more example, I did a test in Python 3.7 (remembering that the locales shall be installed in the system as explained here):

import locale
from datetime import datetime

d = datetime(2020, 5, 27)
for loc in ['pt_BR', 'pt_PT', 'it_IT', 'ar_DZ']:
    locale.setlocale(locale.LC_ALL, f'{loc}.utf8')
    print(loc, d.strftime('%x'))

The exit was:

pt_BR 27/05/2020
pt_PT 27/05/2020
it_IT 27/05/2020
ar_DZ 27-05-2020

Completion

Even if there is an "official" source like CLDR, the support of the different languages and API’s varies greatly: they can follow either totally or partially, or they can use their own implementations that may or may not match the CLDR definition (and CLDR itself has its own release schedule of new versions, which may change these definitions). If your API depends on these settings, it will be difficult to justify any format choice that is (and if you do not want to have the problem of inconsistency between languages, you will have to implement these rules, which in my opinion is too much work to be worth - it would be worth if it were a specific internationalization/localization API, because then the core would be the implementation of such rules).

And even if you decide not to use the CLDR and check if there is a standard for each country, there is still the cultural question, which may not be compatible with the norms, as we saw in the case of ABNT.

So I would go with the initial suggestion, to use the ISO 8601 format, which is already an "international" and more comprehensive standard, instead of looking for local standards for each place. And leave the conversion to other formats for presentation purposes only, if relevant.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.