Skip to content

Date pipe time component extraction issues across locales #12632

@gary-b

Description

@gary-b

I'm submitting a ... (check one with "x")

[x] bug report => search github for a similar issue or PR before submitting
[ ] feature request
[ ] support request

Current behavior
The date pipe output is incorrect when custom formats are used with various locales. The current implementation will use Intl.DateTimeFormat to localize DateTime information, and then use string manipulation to extract individual components as the output is not granular enough. The bugs come mainly from assumptions about how the format looks across all locales.

I've provided unit tests as a repro- the expected results are valid on Chrome, but not necessarily IE - (different browsers format locales differently, including the order of components, number system and alphabets used.) See the full tests created while investigating the issue at https://gist.github.com/gary-b/bdc67fae4767c7da08ee93965a955fa5

assume date = new Date(2015, 5, 15, 9, 3, 1);
1.The day part ('a') output fails in various locales

// When Intl.DateTimeFormat puts the day part in front of the hour for the locale
pipe = new DatePipe('hu');
expect(pipe.transform(date, 'a')).toEqual('de.'); // outputs 9
// When Intl.DateTimeFormat has a space in the day part string itself for the locale
pipe = new DatePipe('sr');
expect(pipe.transform(date, 'a')).toEqual('пре подне'); // outputs npe

See the Intl.ts hourClockExtractor function.

2.The 2 digit formatting (eg "hh") outputs a mix of numbering systems

pipe = new DatePipe('mr');
expect(pipe.transform(date, 'hh')).toEqual('०९'); // outputs 0९

The '0' is hard coded into angular's Intl.js digitModifier function.

3.The timezone output fails with certain locales

// When the browser puts the hour after the timezone for the locale
pipe = new DatePipe('zh');
expect(pipe.transform(date, 'Z')).toEqual('GMT+1'); // outputs +19时
// When Intl.DateTimeFormat outputs an hour identifier between the hour and the timezone for the locale, eg for fr you get 09 h UTC+1
pipe = new DatePipe('fr');
expect(pipe.transform(date, 'Z')).toEqual('UTC+1'); // outputs h UTC+1

See the Intl.ts timeZoneGetter function.

4.The era output doesn't work on any locale I tried

expect(pipe.transform(date, 'G')).toEqual('A');//outputs 6 15, 2015 A

Angular's Intl.ts assumes the Intl.DateTimeFormat object will output the era on its own, it doesn't.

What is the motivation / use case for changing the behavior?
Broken.

Please tell us about your environment:
Windows 10

  • Angular version: 2.0.X
    Angular master

  • Browser: [all | Chrome XX | Firefox XX | IE XX | Safari XX | Mobile Chrome XX | Android X.X Web Browser | iOS XX Safari | iOS XX UIWebView | iOS XX WKWebView ]
    Chrome (also have details of IE output in the gist)

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: commonIssues related to APIs in the @angular/common packagearea: i18nIssues related to localization and internationalizationfreq2: mediumtype: bug/fix

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions