-
Notifications
You must be signed in to change notification settings - Fork 602
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Date: Olson-timezone-support (real 'z', 'v', 'V') #687
Conversation
212e748
to
8e074bf
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@rajavelmani, thanks for your PR. I left some comments above and updated the description with some TODOs. Thanks so far!!
src/date.js
Outdated
@@ -51,7 +51,7 @@ function validateRequiredCldr( path, value ) { | |||
*/ | |||
Globalize.dateFormatter = | |||
Globalize.prototype.dateFormatter = function( options ) { | |||
var args, cldr, numberFormatters, pad, pattern, properties, returnFn; | |||
var args, cldr, numberFormatters, pad, pattern, properties, returnFn, tzId; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CLDR and IANA refers to them as timezone names. Let's rename tzId
into timezoneName
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i can use timeZone
as timezoneName
is locale dependent
src/date.js
Outdated
@@ -66,6 +66,7 @@ Globalize.prototype.dateFormatter = function( options ) { | |||
pattern = dateExpandPattern( options, cldr ); | |||
properties = dateFormatProperties( pattern, cldr ); | |||
cldr.off( "get", validateRequiredCldr ); | |||
properties.tzId = tzId;//TODO validate |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This variable is being declared and then set here (i.e., always undefined
). I believe this was here as a placeholder to accept a potential options.timeZone
value. Therefore, I think this can be safely removed for now.
test/unit/date/format.js
Outdated
); | ||
|
||
cldr = new Cldr( "en" ); | ||
|
||
QUnit.assert.dateFormat = function( date, pattern, cldr, expected ) { | ||
QUnit.assert.dateFormat = function( date, pattern, cldr, expected, tzId ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nitpick comment, let's leave cldr, expected
as the last arguments. We could place tzId (actually, timezoneName) after pattern.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just to confirm, I added the tzId to the end to avoid the changes to rest of the test cases. if your are ok to change all the test then, i can change all the tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have changed the order of the signature as you mentioned.
test/unit/date/format.js
Outdated
|
||
//fall through to 'O' format | ||
date = new FakeDate( 0 ); | ||
assert.dateFormat(date, "z", cldr, "GMT", "Etc/GMT"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where that is unavailable, falls back to the short localized GMT format ("O").
http://www.unicode.org/reports/tr35/tr35-dates.html#dfst-zone
According to the above, I expect a test where it's used an unavailable metaZone, not "Etc/GMT"
that actually exists and is equal to O format as a coincidence.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i used "America/Argentina/Buenos_Aires"
which is not supported in CLDR json yet
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice! Though, I'm wondering... Should we use an invalid stuff that will never be supported like "Foo/Bar"
?
src/date/format-properties.js
Outdated
); | ||
properties.regionFormatDaylight = cldr.main( | ||
"dates/timeZoneNames/regionFormat-type-daylight" | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing break
here, i.e., in the case where it's found.
src/date/timezone-region-format.js
Outdated
format = ( standardTzName ) ? standardTzName : | ||
( regionFormatStandard ) ? regionFormatStandard.replace( /\{0\}/, exemplarCity ) : | ||
undefined; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems to me that at this runtime point we could have done more processing on these properties... I mean, standardTzName (or exemplarCity) could have been incorporated into regionFormatStandard, and daylightTzName (or exemplarCity) could have been incorporated into regionFormatDaylight.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Other points:
- The parentheses on
( standardTzName ) ?
is unnecessary; - Why the
undefined
case?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems to me that at this runtime point we could have done more processing on these properties... I mean, standardTzName (or exemplarCity) could have been incorporated into regionFormatStandard, and daylightTzName (or exemplarCity) could have been incorporated into regionFormatDaylight.
I have optimized the properties
please take a look and let me know your thoughts
@@ -105,7 +105,8 @@ QUnit.test( "should allow for runtime compilation", function( assert ) { | |||
"pm-alt-variant": "pm" | |||
}, | |||
"pattern": "h:mm:ss a", | |||
"timeSeparator": ":" | |||
"timeSeparator": ":", | |||
"tzId": undefined |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If it's undefined
, let's simply not include it.
test/unit/date/format.js
Outdated
assert.dateFormat( date, "OO", cldr, "GMT+11" ); | ||
assert.dateFormat( date, "OOO", cldr, "GMT+11" ); | ||
assert.dateFormat( date, "OOOO", cldr, "GMT+11:00" ); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's already a "should format timezone (O)"
section above. Instead of duplicating it, let's simply incorporate the missing pieces there please.
src/date/format.js
Outdated
// z...zzz: "{shortRegion}", eg. "PST" or "PDT". | ||
// zzzz: "{regionName} {Standard Time}" or "{regionName} {Daylight Time}", | ||
// eg. "Pacific Standard Time" or "Pacific Daylight Time". | ||
if ( properties.tzId ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Checking for properties.tzId
isn't valid, because there's a case where properties.tzId
is truthy and metaZone is unavailable and therefore the properties below are invalid (by looking at your code at date/format-properties.js). I think you should check for something else, e.g., one of the set properties.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok let me change this to check properties.standardTzName
and properties.daylightTzName
src/date/format.js
Outdated
); | ||
if ( ret ) { | ||
break; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since the properties exist, this should always be truthy.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, this will not be required with check for properties.standardTzName
and properties.daylightTzName
a0f3c96
to
be210ba
Compare
src/date/format-properties.js
Outdated
length < 4 ? "short" : "long", | ||
"daylight" | ||
]); | ||
if ( !standardTzName && !daylightTzName ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What should happen for !standardTzName || !daylightTzName
? It won't fall either in here or in the next if
. Should we use examplarCity
if !standardTzName || !daylightTzName
. Probably, this would only happen in a corrupted CLDR data where there is one content, but not the other.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this will help on the scenario like https://github.com/globalizejs/globalize/pull/687/files#diff-df6075946ae91cbb093f63c7597cd746R460 where the timezone id is valid not supported in CLDR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note I'm referring to using ||
instead of &&
in here, so we also catch the additional case where part of the data exists.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some more changes please
src/date/format-properties.js
Outdated
]); | ||
if ( !standardTzName && !daylightTzName ) { | ||
var exemplarCity = cldr.main( | ||
"dates/timeZoneNames/zone/", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove trailing /
src/date/format-properties.js
Outdated
standardTzName = cldr.main( | ||
"dates/timeZoneNames/regionFormat-type-standard" | ||
) | ||
.replace( /\{0\}/, exemplarCity ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of replacing {0}
yourself, you can use src/common/format-message (example).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FWIW, it's an internal utility to help in cases like that. Note, it's not ICU message format :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i just followed from the format.js. but, i can use the format-message as you suggested. Do i change the format.js code too?
src/date/format-properties.js
Outdated
var properties = { | ||
numberFormatters: {}, | ||
pattern: pattern, | ||
timeSeparator: numberSymbol( "timeSeparator", cldr ) | ||
timeSeparator: numberSymbol( "timeSeparator", cldr ), | ||
timeZone: timeZone |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's skip adding timeZone
to the properties. We can add it later if required.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we don't add timeZone
from option.timeZone
to properties.timeZone
we may not be able to test time zone implementation. Can you clarify why we need to skip timeZone
from properties
?
test/unit/date/format.js
Outdated
assert.dateFormat(date, "zz", "America/Los_Angeles", cldr, "PST"); | ||
assert.dateFormat(date, "zzz", "America/Los_Angeles", cldr, "PST"); | ||
assert.dateFormat(date, "zzzz", "America/Los_Angeles", cldr, "Pacific Standard Time"); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to test the "exemplarCity" case.
5b0201e
to
028ae5f
Compare
9599fe1
to
b46372b
Compare
z
)801152a
to
3c8928c
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's looking great!! I have left some comments for your consideration please.
src/date/format-properties.js
Outdated
} | ||
|
||
//fall through "{0} {Time}"" | ||
//for VVVV format |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nitpick: space after //
, like // for ...
src/date/format-properties.js
Outdated
//fall through "{0} {Time}"" | ||
//for VVVV format | ||
if ( timeZone ) { | ||
var TzName; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nitpick: variable names should start with lowercase, i.e., tzName
. Preferably using full words, like timezoneName
.
src/date/format-properties.js
Outdated
]), | ||
exemplarCity = cldr.main([ | ||
"dates/timeZoneNames/zone", timeZone, "exemplarCity" | ||
]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If timeZone
is passed to format anything but VVVV
this is unnecessary, so let's move this assignment below in the only place where it's used.
src/date/format-properties.js
Outdated
metaZone = cldr.supplemental([ | ||
"metaZones/metazoneInfo/timezone", timeZone, 0, | ||
"usesMetazone/_mzone" | ||
]), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If timeZone
is passed to format anything but z*
or v*
this is unnecessary, so (considering we move exemplarCity below away) let's update the if condition:
- if ( timeZone ) {
+ if ( timeZone && ( chr === "v" || chr === "z" ) ) {
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok let me move this condition into https://github.com/globalizejs/globalize/pull/687/files#diff-a8a17cd910e21f0b9d3e8ffe4fcea2a8R50 to access chr
assert.equal( "Pacific Time", properties( pattern, cldr, timeZone ).genericTzName ); | ||
} | ||
}); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's add a test to assert vv
and vvv
throw.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In here, or where it's possible to test this...
test/unit/date/format-properties.js
Outdated
} | ||
}); | ||
}); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's add a test to assert V
throws.
@@ -208,6 +283,63 @@ return function( pattern, cldr ) { | |||
|
|||
// Zone | |||
case "z": | |||
properties.standardTzName = standardTzName; | |||
properties.daylightTzName = daylightTzName; | |||
break; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nitpick: let's add an empty line after break
and before the next case
.
src/date/format-properties.js
Outdated
), | ||
[ unKnownExemplarCity ] | ||
); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we simplify the the above as:
if ( length === 2 ) {
TzName = timeZone;
- }
-
- if ( exemplarCity ) {
- if ( length === 3 ) {
- TzName = exemplarCity;
- } else if ( length === 4 ) {
- TzName = formatMessage(
- cldr.main(
- "dates/timeZoneNames/regionFormat"
- ),
- [ exemplarCity ]
- );
+ } else if ( length === 3 ) {
+ TzName = exemplarCity;
+ } else if ( length === 4 ) {
+ if ( !exemplarCity ) {
+ exemplarCity = cldr.main([
+ "dates/timeZoneNames/zone/Etc/Unknown/exemplarCity"
+ ]);
}
- } else if ( !exemplarCity && length === 4 ) {
- var unKnownExemplarCity = cldr.main([
- "dates/timeZoneNames/zone/Etc/Unknown/exemplarCity"
- ]);
TzName = formatMessage(
cldr.main(
"dates/timeZoneNames/regionFormat"
),
- [ unKnownExemplarCity ]
+ [ exemplarCity ]
);
}
if ( TzName ) {
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
test/unit/date/format.js
Outdated
var date = new FakeDate( 0 ); | ||
assert.dateFormatWithTimezone( date, "VV", "America/Los_Angeles", cldr, "America/Los_Angeles" ); | ||
assert.dateFormatWithTimezone( date, "VVV", "America/Los_Angeles", cldr, "Los Angeles" ); | ||
assert.dateFormatWithTimezone( date, "VVVV", "America/Los_Angeles", cldr, "Los Angeles Time" ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we include VVV
and VVVV
tests that use unkown city? It could re-use the above America/Argentina/Buenos_Aires, but it's good to have it explicitly tested here (in addition to the above fallback-test). Thanks
ef85e52
to
8fd175f
Compare
* | ||
* Load IANA data. | ||
*/ | ||
Globalize.loadIANA = function( json ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pros:
- Letting users to load this data similarly to the way they do with CLDR is good. Therefore we don't embed such in the library.
Cons:
- Differently from CLDR, IANA doesn't provide with an official JSON binding. The one used here is non-official, it is using the JSON bindings from moment-timezone, and could be subject to changes. Ways to mitigate risks here could be 1) to get moment-timezone data put into a separate iana-json library; 2) check if IANA is interested in making it official? Ideas?
@@ -62,9 +80,12 @@ Globalize.prototype.dateFormatter = function( options ) { | |||
|
|||
validateDefaultLocale( cldr ); | |||
|
|||
timeZone = options.timeZone; | |||
validateParameterTypeString( options.timeZone, "options.timeZone" ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now that we the additional option options.timeZone
, we need to update the above options = options || { skeleton: "yMd" }
. For example, dateFormatter({timeZone: "something"})
should also set the default skeleton: "yMd"
. This default doesn't need to be set if either one is used: skeleton, date, or datetime.
src/date/format-properties.js
Outdated
@@ -3,9 +3,10 @@ define([ | |||
"./pattern-re", | |||
"../common/create-error/unsupported-feature", | |||
"../number/symbol", | |||
"../util/string/pad" | |||
"../util/string/pad", | |||
"../common/format-message" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nitpick: sort these filepaths alphabetically please, therefore common/format-message
should be included after the common/..
one above.
"zones": [ | ||
{ | ||
"name": "America/Los_Angeles", | ||
"abbrs": [ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we remove this?
420, | ||
480 | ||
], | ||
"population": 15058000 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we remove this?
}); | ||
|
||
QUnit.test( "should format timezone (v)", function( assert ) { | ||
try { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems like this was used for debug and was left?
Closed in favor of #701 |
#340
z
,v
,V
format with timezone namesAdded by @rxaviers:
TODO:
options.timeZone
options.timeZone
options.timeZone
Follow up items: