Skip to content
This repository was archived by the owner on Apr 14, 2021. It is now read-only.

toLocaleString not respecting short format (numeric, numeric, numeric) #64

Closed
bthecorgi opened this issue Apr 17, 2014 · 9 comments
Closed
Labels

Comments

@bthecorgi
Copy link

(new Date(1)).toLocaleString('en-US', { year: 'numeric', month : 'numeric', day : 'numeric' });

"31 Dec 1969" instead of "12/31/1969"

@andyearnshaw
Copy link
Owner

Works for me in Chrome 34 and Firefox 28. What browser are you using? Are you using the NPM/Bower release or the latest commits from the master branch?

Note that recent commits changed the way Intl.js implements toLocaleString() methods. We don't override native implementations if they're already ECMA-402 compliant.

@andyearnshaw
Copy link
Owner

Closing as invalid due to no further information.

@bthecorgi
Copy link
Author

Sorry for the late reply. Try this in node. Let me know if you need more information. The expected value is all numeric, so: 31/12/1969.

node --version = v0.10.21. but I've also experienced it in an older version of Firefox

Intl = require('intl/Intl.js');
{}
require('intl/locale-data/jsonp/en-GB.js')
{}
(new Date(1)).toLocaleString('en-GB', { year: 'numeric', month : 'numeric', day : 'numeric' });
'31 Dec 1969'

@drewfish
Copy link
Contributor

If you want to localize for en-US you need to load that locale-data, I suspect.

@drewfish
Copy link
Contributor

Hmm... I changed the last line to use en-GB and I'm getting the same wrong results (31 Dec 1969).

@bthecorgi
Copy link
Author

That's right. Sorry for the typo. Even with en-GB, it is still incorrect.

Should this issue be re-opened or should I file a new issue?

@andyearnshaw andyearnshaw added bug and removed invalid labels May 15, 2014
@andyearnshaw
Copy link
Owner

Hmm... it looks like it's something to do with finding the closest matching pattern. Obviously it shouldn't be finding the pattern with month: 'long' a better match than the one with month:'2-digit'.

> (new Date(1)).toLocaleString('en-GB', { year: 'numeric', month : 'numeric', day : 'numeric' }); 
"1 January 1970"
> (new Date(1)).toLocaleString('en-GB', { year: 'numeric', month : 'numeric', day : '2-digit' });
"01/1/1970"

I'm using a newer compilation of the data with improved patterns that I'll be pushing shortly for #65 (so your results might vary). I'll take a look at the pattern matching algorithm while I'm at it.

@andyearnshaw andyearnshaw reopened this May 15, 2014
@andyearnshaw
Copy link
Owner

OK, I've had a look at the pattern matching algorithm. The specification defines 2 algorithms: "basic" and "best fit". "basic" is fully mapped out by the spec, whereas "best fit" should be implementation dependant. In the interests of focusing on more important stuff, I set BestFitFormatMatcher to call BasicFormatMatcher under the hood and pretty much forgot about it, thinking BasicFormatMatcher would be good enough for the time being.

It turns out that it's not really good enough. For this particular issue, the yMd pattern for en-GB is dd/MM/y, which maps to { year: 'numeric', month: '2-digit', day: '2-digit' }. So, because the pattern with the long month has only one property that is not an exact match to 'numeric', that is the format that's chosen by the "basic" format matcher.

TL;DR
I need to write a proper BestFitFormatMatcher algorithm. I'm thinking it can be virtually identical to BasicFormatMatcher, with the addition of a reduced score penalty where the requested format is of the same type as the matching format (ie '2-digit' isn't penalised as much when 'numeric' is requested).

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

4 participants
@drewfish @bthecorgi @andyearnshaw and others