Skip to content

Commit

Permalink
fix(android): localized date/time format should default to numeric
Browse files Browse the repository at this point in the history
Fixes TIMOB-28278
  • Loading branch information
jquick-axway authored and sgtcoolguy committed Dec 18, 2020
1 parent ab9997b commit 6323c69
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,10 @@ public void handleCreationDict(KrollDict properties)
millisecondDigits = 3;
}

// Fetch date/time styles. These are only used if above options are not provided.
String dateStyleStringId = TiConvert.toString(options.get("dateStyle"));
String timeStyleStringId = TiConvert.toString(options.get("timeStyle"));

// Determine if at least 1 "date" componoent has been configured.
boolean hasCustomDateSettings
= (weekdayFormatId != null)
Expand All @@ -118,6 +122,15 @@ public void handleCreationDict(KrollDict properties)
|| (timeZoneFormatId != null)
|| (millisecondDigits > 0);

// If no date/time components or styles were assigned, then default to "numeric" month/day/year.
if (!hasCustomDateSettings && !hasCustomTimeSettings
&& (dateStyleStringId == null) && (timeStyleStringId == null)) {
monthFormatId = NUMERIC_STRING_ID;
dayFormatId = NUMERIC_STRING_ID;
yearFormatId = NUMERIC_STRING_ID;
hasCustomDateSettings = true;
}

// Create a custom date/time formatter using a string pattern.
this.dateFormat = null;
if (hasCustomDateSettings || hasCustomTimeSettings) {
Expand Down Expand Up @@ -149,7 +162,7 @@ public void handleCreationDict(KrollDict properties)
}

// Create a basic date/time formatter if no custom components were configured
// or if we failed to create the customer formatter above.
// or if we failed to create the custom formatter above.
if (this.dateFormat == null) {
if (hasCustomDateSettings && hasCustomTimeSettings) {
this.dateFormat = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, locale);
Expand All @@ -159,8 +172,6 @@ public void handleCreationDict(KrollDict properties)
this.dateFormat = DateFormat.getDateInstance(DateFormat.SHORT, locale);
} else {
// We only use "dateStyle" and "timeStyle" if no other options are defined.
String dateStyleStringId = TiConvert.toString(options.get("dateStyle"));
String timeStyleStringId = TiConvert.toString(options.get("timeStyle"));
int dateStyleIntId = getIntIdForStyleId(dateStyleStringId);
int timeStyleIntId = getIntIdForStyleId(timeStyleStringId);
if ((dateStyleStringId != null) && (timeStyleStringId != null)) {
Expand Down
24 changes: 20 additions & 4 deletions common/Resources/ti.internal/extensions/js/Date.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,31 @@
if (OS_ANDROID) {
Date.prototype.toLocaleDateString = function () {
const properties = Intl.DateTimeFormat._makeTiCreationPropertiesFrom(arguments);
const mergedOptions = Object.assign({ dateStyle: 'short' }, properties.options);
const formatter = new Intl.DateTimeFormat(properties.locale, mergedOptions);
const oldOptions = properties.options;
if (!oldOptions || (!oldOptions.dateStyle && !oldOptions.month && !oldOptions.day && !oldOptions.year)) {
const defaultOptions = {
month: 'numeric',
day: 'numeric',
year: 'numeric'
};
properties.options = Object.assign(defaultOptions, oldOptions);
}
const formatter = new Intl.DateTimeFormat(properties.locale, properties.options);
return formatter.format(this);
};

Date.prototype.toLocaleTimeString = function () {
const properties = Intl.DateTimeFormat._makeTiCreationPropertiesFrom(arguments);
const mergedOptions = Object.assign({ timeStyle: 'short' }, properties.options);
const formatter = new Intl.DateTimeFormat(properties.locale, mergedOptions);
const oldOptions = properties.options;
if (!oldOptions || (!oldOptions.timeStyle && !oldOptions.hour && !oldOptions.minute && !oldOptions.second)) {
const defaultOptions = {
hour: 'numeric',
minute: 'numeric',
second: 'numeric'
};
properties.options = Object.assign(defaultOptions, oldOptions);
}
const formatter = new Intl.DateTimeFormat(properties.locale, properties.options);
return formatter.format(this);
};

Expand Down
30 changes: 21 additions & 9 deletions tests/Resources/date.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,11 @@ const should = require('./utilities/assertions');
describe('Date', function () {
it('#toLocaleString()', () => {
// 2020-March-1st
const date = new Date(Date.UTC(2020, 2, 1));
const date = new Date(2020, 2, 1);
const options = {
year: 'numeric',
month: 'numeric',
day: 'numeric',
timeZone: 'UTC'
day: 'numeric'
};

should(date.toLocaleString).not.be.undefined();
Expand All @@ -35,16 +34,20 @@ describe('Date', function () {
should(date.toLocaleString('en-US', options)).be.eql('3/1/2020');
should(date.toLocaleString('de-DE', options)).be.eql('1.3.2020');
should(date.toLocaleString('ja-JP', options)).be.eql('2020/3/1');

should(date.toLocaleDateString('en-US')).be.eql('3/1/2020');
should(date.toLocaleDateString('en-US', { year: 'numeric' })).be.eql('2020');
should(date.toLocaleDateString('en-US', { year: '2-digit' })).be.eql('20');
should(date.toLocaleDateString('en-US', { hour: 'numeric', hour12: true })).be.eql('3/1/2020, 12 AM');
});

it('#toLocaleDateString()', () => {
// 2020-March-1st
const date = new Date(Date.UTC(2020, 2, 1));
const date = new Date(2020, 2, 1);
const options = {
year: 'numeric',
month: 'numeric',
day: 'numeric',
timeZone: 'UTC'
day: 'numeric'
};

should(date.toLocaleDateString).not.be.undefined();
Expand All @@ -61,18 +64,22 @@ describe('Date', function () {
should(date.toLocaleDateString('en-US', options)).be.eql('3/1/2020');
should(date.toLocaleDateString('de-DE', options)).be.eql('1.3.2020');
should(date.toLocaleDateString('ja-JP', options)).be.eql('2020/3/1');

should(date.toLocaleDateString('en-US')).be.eql('3/1/2020');
should(date.toLocaleDateString('en-US', { year: 'numeric' })).be.eql('2020');
should(date.toLocaleDateString('en-US', { year: '2-digit' })).be.eql('20');
should(date.toLocaleDateString('en-US', { hour: 'numeric', hour12: true })).be.eql('3/1/2020, 12 AM');
});

it('#toLocaleTimeString()', () => {
// 2020-Jan-1st 08:02:05 PM
const date = new Date(Date.UTC(2020, 0, 1, 20, 2, 5));
const date = new Date(2020, 0, 1, 20, 2, 5);
const options = {
hour: 'numeric',
minute: '2-digit',
second: '2-digit',
hour12: true,
dayPeriod: 'narrow',
timeZone: 'UTC'
dayPeriod: 'narrow'
};

should(date.toLocaleTimeString).not.be.undefined();
Expand All @@ -88,5 +95,10 @@ describe('Date', function () {

should(date.toLocaleTimeString('en-US', options)).be.eql('8:02:05 PM');
should(date.toLocaleTimeString('de-DE', options)).be.equalOneOf([ '8:02:05 PM', '8:02:05 nachm.' ]);

should(date.toLocaleTimeString('en-US')).be.equalOneOf([ '8:02:05 PM', '20:02:05' ]);
should(date.toLocaleTimeString('en-US', { hour12: true })).be.eql('8:02:05 PM');
should(date.toLocaleTimeString('en-US', { hour12: false })).be.eql('20:02:05');
should(date.toLocaleTimeString('en-US', { hour: 'numeric', hour12: true })).be.eql('8 PM');
});
});
13 changes: 13 additions & 0 deletions tests/Resources/intl.datetimeformat.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,19 @@ describe('Intl.DateTimeFormat', () => {
should(formatter.format(new Date())).be.a.String();
});

it('default format', () => {
// 2020-March-1st 08:02:05 PM
const date = new Date(2020, 2, 1, 20, 2, 5);
let formatter = new Intl.DateTimeFormat('en-US');
should(formatter.format(date)).be.eql('3/1/2020');
formatter = new Intl.DateTimeFormat('en-US', {});
should(formatter.format(date)).be.eql('3/1/2020');
formatter = new Intl.DateTimeFormat('de-DE');
should(formatter.format(date)).be.eql('1.3.2020');
formatter = new Intl.DateTimeFormat('ja-JP');
should(formatter.format(date)).be.eql('2020/3/1');
});

it('numeric date', () => {
// 2020-March-1st
const date = new Date(Date.UTC(2020, 2, 1));
Expand Down

0 comments on commit 6323c69

Please sign in to comment.