Closed jueberschlag closed 1 year ago
Thanks for raising this issue, it's been on the "to do" list too long.
As of a3edd42 I've added the function MyApp.Cldr.DateTime.date_time_at_formats/2
so that the formats are now included in the backend. I've also added Cldr.DateTime.date_time_at_formats/2
.
As for the formatting part, I'm thinking to add style: :at
as an option to Cldr.DateTime.to_string/2
. This is a little different to TR35 which suggests the default should be the "at" format. However that would be a breaking change I'd prefer to avoid.
I'm on a long flight today so I should be able to wrap this up by end of Saturday my time (UTC+8 when I land).
Would this approach work for you?
I managed to get an implementation done before my flight. Here are some examples:
iex> date_time = ~U[2023-09-08 15:50:00Z]
iex> Cldr.DateTime.to_string(date_time, format: :full, style: :at)
{:ok, "Friday, September 8, 2023 at 3:50:00 PM GMT"}
iex> Cldr.DateTime.to_string(date_time, format: :long, style: :at)
{:ok, "September 8, 2023 at 3:50:00 PM UTC"}
iex> Cldr.DateTime.to_string(date_time, format: :full, style: :at, locale: :fr)
{:ok, "vendredi 8 septembre 2023 à 15:50:00 UTC"}
iex> Cldr.DateTime.to_string(date_time, format: :long, style: :at, locale: :fr)
{:ok, "8 septembre 2023 à 15:50:00 UTC"}
The formats are, of course, based upon CLDR data. They can be introspected with:
iex> MyApp.Cldr.DateTime.Format.date_time_at_formats(:en)
{:ok,
%Cldr.DateTime.Formats{
short: "{1}, {0}",
medium: "{1}, {0}",
long: "{1} 'at' {0}",
full: "{1} 'at' {0}"
}}
iex> MyApp.Cldr.DateTime.Format.date_time_at_formats(:fr)
{:ok,
%Cldr.DateTime.Formats{
short: "{1} {0}",
medium: "{1}, {0}",
long: "{1} 'à' {0}",
full: "{1} 'à' {0}"
}}
Feedback most welcome.
One of the ideas I've been toying with for a while has been to separately specify the format of the date
part and the time
part.
Instead of format: :long
which means both the date
and the time
are formatted using their respective :long
format it would be possible to say format: [:long, :medium]
meaning :long
for the date
and :medium
for the time
.
WDYT?
Thanks for these changes ! I like the style: :at
option to avoid a breaking change.
Regarding your idea to separate the date and time formats, I don't have your experience with CLDR data but how would you handle the combination of a :full
date format with a :medium
time format?
From what I see in CLDR data for the :en
locale, the combination also differs based on the format: https://www.unicode.org/cldr/cldr-aux/charts/28/summary/en.html#1717
The way the formats are packaged in the data there are three ways to format a date (same approach is used for numbers and units of measures):
:short
, :medium
, :long
and :full
that can be used in a locale-independent fashion. That is what is returned for MyApp.Cldr.DateTime.Format.date_time_at_formats(:en)
.MyApp.Cldr.DateTime.date_time_available_formats/0
. These are kind of template formats. They could be used for parsing but I haven’t got close to trying to parse dates and times yet.Not surprisingly, the predefined formats are most often used because of the locale-independence.
Since the formats for date times are of the form "{1} 'at' {0}"
you can infer that the the date and time are formatted separately then combined. Which is why adding format: [:full, :short]
is a really east thing to implement - if it’s of any value.
Because of the new style: :at
option I would have no need of a format such as format: [:full, :short]
but I can see why others may need it.
Thanks for the explanation but in this case I still don't know how you would determine which date-time combination format: if you use the date format (:long
) the format is {1} 'at' {0}
and if you use te time format (:short
) then the format is {1}, {0}
. Or maybe you were thinking of always using {1} 'at' {0}
?
Because of the new style: :at option I would have no need of a format such as format: [:full, :short]
Understood, thanks for the feedback.
Just to close this out, your comment made me realise I didn't fully explain that date times are composed from separately formatted dates and formatted times. If we look at the :short
, :medium
, etc for dates and for times we see the following. Which I hope closes the loop on how date time formats are constructed.
iex> MyApp.Cldr.DateTime.Format.date_formats(:fr)
{:ok,
%Cldr.Date.Formats{
short: "dd/MM/y",
medium: "d MMM y",
long: "d MMMM y",
full: "EEEE d MMMM y"
}}
iex> MyApp.Cldr.DateTime.Format.time_formats(:fr)
{:ok,
%Cldr.Time.Formats{
short: "HH:mm",
medium: "HH:mm:ss",
long: "HH:mm:ss z",
full: "HH:mm:ss zzzz"
}}
I've published ex_cldr_dates_times version 2.15.0 with the following changelog entry:
:style
as a synonym for :format
with the functions Cldr.Time.to_string/2
, Cldr.Date.to_string/2
and Cldr.DateTime.to_string/2
is now removed. The :style
option is now used to influence the use of "at" formats in Cldr.DateTime.to_string/2
. :style
also remains a valid option for interval formatting.
Hi,
I was looking for a way to format a date in the following format in English and French :
By doing some tests and browsing the code and the CLDR specifications I found this chapter regarding date-time combine formats: https://cldr.unicode.org/translation/date-time/date-time-patterns#h.x7ca7qwzh4m
Especially a paragraph that says:
I am using
ex_cldr_dates_times
version 2.13.2 andex_cldr
version 2.37.2 which should be based upon CLDR version 43.In this case, should this library use the
-atTime
format if the date has a full month and weekday name?If needed I'll be more than happy to have a look and try to fix this in both the
Cldr.DateTime.Format.Backend
andCldr.DateTime.Formatter.Backend
modules.Thanks