Open jungshik opened 7 years ago
Yeah, I think that the main concern here is that pattern
, even when named raw
is not a n internationalizable bit of an internationalizable system.
In other words, DateTimeFormat selects the right pattern and then localizes it.
If you provide a pattern to Intl, you just removed half of the operation, and for that reason, it may better belong to Date
object than Intl
?
Brainstorming here, but:
let d = new Date();
d.toLocalePatternString('fr', "dd/YY/MMMM HH:ii");
Also, good idea on separating it out of the conversation about skeletons and styles.
I thought formatToParts
was also designed to be the building block for some of these use cases, like for example:
js> Intl.DateTimeFormat("en-US", {timeZoneName:"long"})
.formatToParts()
.filter(e => e.type === "timeZoneName")
.map(e => e.value)[0]
"Western European Summer Time"
On our development teams, we encourage them to use i18n-aware apis, which gets them stuck sometimes when they need to output ISO UTC date patterns for REST services or other APIs. We kept telling them to use the Date object, but eventually relented and added fixed UTC date formats as an option so we can support teams in a minimum number of date APIs.
Perhaps a similar argument holds here for Intl.DateTimeFormat?
@mimckenna are you saying that the only format that you needed was ISO8601 outside of what i18n has to offer? That's very different than letting people output anything.
In general, I'm not a huge fan of ad-hoc patterns because people will only ever get things that don't make sense in some locale. That said, if you only need to support a limited subset of locales, and you know exactly which format you want, we probably shouldn't stop you from creating that pattern.
I would love to pick up patterns in the temporal proposal, but my fear is that it will be difficult to spec that without accidentally forcing people to carry CLDR data around to be 262 compliant - which we don't want.
No - we offer short, medium, long, full, the skeletons offered through CLDR, and added a UTC format for completeness. We have a method to allow developers to override the skeletons and create their own fixed format, but we get more support issues over that than than the canned (and very complete) list of CLDR skeletons.
Example of where the override was needed by some teams: to match a proprietary date format needed for connectivity to a legacy service. Our advice back to them (because we wanted to deprecate the overrides) was to cobble it together themselves since it was a proprietary, non-standard, static, fixed-format that they needed.
In most cases, you can get away with transforming a pattern/skeleton into a DateTimeFormat options, specially if you're flexible with the output. E.g.:
var f = {
weekday: 'long',
month: 'long',
day: 'numeric',
year: 'numeric',
hour: 'numeric',
minute: '2-digit',
second: '2-digit',
hour12: true,
timeZoneName: 'long'
};
new Intl.DateTimeFormat('en-US', f).format(Date.now())
"Friday, October 27, 2017, 4:14:53 PM Eastern Daylight Time"
Most browsers, today, will add a comma after the year (IE11 does something slightly different) for that set of options. But if you look at the latest ICU library, we see this pattern: "EEEE, MMMM d, y 'at' h:mm:ss a zzzz"
, which does have an at
in between and no coma for en-US
.
I wrote some experimental library to try to see if we can help people who want to use patterns/skeleton for convenience, but still preserving the invariants of Intl
to do the right thing depending of the locale.
https://github.com/caridy/intl-datetimeformat-pattern
With a library like this, you can get from that pattern/skeleton to the most likely option object that will produce something very similar, but in some cases slightly different due to the those weird differences.
I wonder if someone can actually explain the difference between ICU and browsers for something like the example above?
I wonder if someone can actually explain the difference between ICU and browsers for something like the example above?
For that specific case, using at
is the correct behavior according to UTS#35 2.6.2.2 Missing Skeleton Fields, explanation below.
- Divide the request into a date fields part and a time fields part.
- For each part, find the matching dateFormatItem, and expand the pattern as above.
Since no datetime pattern is found given that skeleton (i.e., yMMMMEEEEdhmmsszzzz), the implementation should find a date pattern (for yMMMMEEEEd skeleton) and a time pattern (for hmmsszzzz skeleton) individually.
- Combine the patterns for the two dateFormatItems using the appropriate dateTimeFormat pattern, determined as follows from the requested date fields:
- If the requested date fields include wide month (MMMM, LLLL) and weekday name of any length (e.g. E, EEEE, c, cccc), use
Then combine them using the full "glue-pattern": https://github.com/unicode-cldr/cldr-dates-full/blob/32.0.0/main/en/ca-gregorian.json#L335 (which has the "at"
for en-US).
- Otherwise, if the requested date fields include wide month, use
- Otherwise, if the requested date fields include abbreviated month (MMM, LLL), use
- Otherwise use
Very nice project.
@rxaviers is right on 'at' for en-US and CLDR 'glue pattern'. The fact that v8 does not do that is a bug. I thought I had filed a bug on that against v8, but I couldn't find it. Filed https://bugs.chromium.org/p/v8/issues/detail?id=7116 .
BTW, this issue is not about 'skeleton' (#189) but about 'pattern'. The former (skeleton) will take a list of fields and field lengths and produce locale-dependent output (order can be shuffled, for instance).
If we add a "data-driven API", then that could be a way to inject your own custom patterns.
https://github.com/tc39/ecma402/issues/210
It seems like this (whether to provide users a way to inject patterns) is a decision that should be made at the Intl level, not at a formatter level.
https://github.com/unicode-cldr/cldr-dates-full/blob/32.0.0/main/en/ca-gregorian.json#L335 show me "dateTimeFormats": { "full": "{1} 'at' {0}", "long": "{1} 'at' {0}", "medium": "{1}, {0}", "short": "{1}, {0}",
It is not clear to me which part of the specification determine WHICH glue pattern it should use? Why should it use the "full" one but not the "short" one?
@FrankYFTang Is this a question that came up during dateStyle/timeStyle implementation? Maybe open an issue over in that repo and we can follow up there.
@FrankYFTang Is this a question that came up during dateStyle/timeStyle implementation? Maybe open an issue over in that repo and we can follow up there.
It is an issue general for DateTimeFormat, not specific to the "dateStyle/timeStyle" proposal. As you see, I try to address the point mentioned by "caridy commented on Oct 27, 2017" and in caridy's example, it is not using dateStyle nor timeStyle at all. I wonder why caridy believe it should use the long glue pattern from his/her example. I will spun off in ecma402 instead.
so the "glue pattern" issue is spin off to https://github.com/tc39/ecma402/issues/338 . I am really against to provide API for "pattern" because it push the responsibility of how to put the order of different field to the caller which destroy the encapsulation of locale independent code.
I also am against providing API for "pattern", primarily because if you provide your own pattern, you're not doing Internationalization. Pattern may be an interesting option for Date
or Temporal
, but not Intl
.
This is spun off from #108 and #119.
In #108, one argument against adding 'pattern' is that API users would be confused between 'pattern' and 'skeleton'. I learned that Globalize.js uses 'raw' to mean 'pattern'. 'raw' is much less likely to be confused with 'skeleton' than 'pattern' is.
Another argument against it is that it gives API users the freedom to do "bad things" (piecing components together in such a way that does not make sense or is confusing in some locales ).
Use cases for 'raw'.
Locale-agnostic date time format (month names, weekday names, tz names etc would be still localized if they're used in a requested format) such as ISO 8601 .
Formats not supported by available forms. The following attempt to retrieve the timezone display name does not work because it's expanded to include "date".
Globalize.js supports this case with
raw("<timezone format specifier in LDML>"
.To emulate the timezone portion of the current output of 'Date.prototype.toString()', one would use
raw("ZZZZ (zzzz)"
(assuming that the format is locale-agnostic, which may not be true).I realize that I didn't put up a very strong case for 'raw' ('pattern') and regard this issue as a forum for input from others. I also want to separate this issue from #108, which gets too long with multiple issues discussed and #189 (options.skeleton).