Skip to content
This repository was archived by the owner on Feb 22, 2018. It is now read-only.

feat(date): Use localized patterns for shorthand format #1030

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/formatter/currency.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ part of angular.formatter_internal;
*
* {{ 1234 | currency }} // output is $1,234.00
* {{ 1234 | currency:'CAD' }} // output is CAD1,234.00
* {{ 1234 | currency:'CAD':false }} // output is 1,234.00CAD
* {{ 1234 | currency:'CAD':false }} // output is 1,234.00CAD
*
*
*/
Expand Down
75 changes: 45 additions & 30 deletions lib/formatter/date.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,42 +3,45 @@ part of angular.formatter_internal;
/**
* Formats a date value to a string based on the requested format.
*
* Usage:
* # Usage
*
* date_expression | date[:format]
*
* Here `format` may be specified explicitly, or by using one of the following predefined
* localizable names:
*
* FORMAT NAME AS DEFINED FOR en_US OUTPUT
* ------------- ---------------------- ---------------------------
* medium MMM d, y h:mm:ss a Sep 3, 2010 12:05:08 pm
* short M/d/yy h:mm a 9/3/10 12:05 pm
* fullDate EEEE, MMMM d, y Friday, September 3, 2010
* longDate MMMM d, y September 3, 2010
* mediumDate MMM d, y Sep 3, 2010
* shortDate M/d/yy 9/3/10
* mediumTime h:mm:ss a 12:05:08 pm
* shortTime h:mm a 12:05 pm
* `format` may be specified explicitly, or by using one of the following predefined shorthand:
*
* FORMAT NAME OUTPUT for en_US
* ------------- ---------------------------
* medium Sep 3, 2010 12:05:08 PM
* short 9/3/10 12:05 PM
* fullDate Friday, September 3, 2010
* longDate September 3, 2010
* mediumDate Sep 3, 2010
* shortDate 9/3/10
* mediumTime 12:05:08 PM
* shortTime 12:05 PM
*
* For more on explicit formatting of dates and date syntax, see the documentation for the
* [DartFormat class](https://api.dartlang.org/apidocs/channels/stable/dartdoc-viewer/intl/intl.DateFormat).
*
* # Example
*
* '2014-05-22' | date:'fullDate' // "Thursday, May 22, 2014" for the en_US locale
*
*/
@Formatter(name:'date')
class Date implements Function {
static final _MAP = const <String, String> {
'medium': 'MMM d, y h:mm:ss a',
'short': 'M/d/yy h:mm a',
'fullDate': 'EEEE, MMMM d, y',
'longDate': 'MMMM d, y',
'mediumDate': 'MMM d, y',
'shortDate': 'M/d/yy',
'mediumTime': 'h:mm:ss a',
'shortTime': 'h:mm a',
static final _PATTERNS = const <String, dynamic> {
'medium': const [DateFormat.YEAR_ABBR_MONTH_DAY, DateFormat.HOUR_MINUTE_SECOND],
'short': const [DateFormat.YEAR_NUM_MONTH_DAY, DateFormat.HOUR_MINUTE],
'fullDate': DateFormat.YEAR_MONTH_WEEKDAY_DAY,
'longDate': DateFormat.YEAR_MONTH_DAY,
'mediumDate': DateFormat.YEAR_ABBR_MONTH_DAY,
'shortDate': DateFormat.YEAR_NUM_MONTH_DAY,
'mediumTime': DateFormat.HOUR_MINUTE_SECOND,
'shortTime': DateFormat.HOUR_MINUTE,
};

/// locale -> (format -> DateFormat)
var _dfs = new Map<String, Map<String, DateFormat>>();

/**
Expand All @@ -55,14 +58,26 @@ class Date implements Function {
if (date is String) date = DateTime.parse(date);
if (date is num) date = new DateTime.fromMillisecondsSinceEpoch(date);
if (date is! DateTime) return date;
if (_MAP.containsKey(format)) format = _MAP[format];
var verifiedLocale = Intl.verifiedLocale(Intl.getCurrentLocale(), DateFormat.localeExists);
_dfs.putIfAbsent(verifiedLocale, () => new Map<String, DateFormat>());
var df = _dfs[verifiedLocale][format];
if (df == null) {
df = new DateFormat(format);
_dfs[verifiedLocale][format] = df;
return _getDateFormat(verifiedLocale, format).format(date);
}

DateFormat _getDateFormat(String locale, String format) {
_dfs.putIfAbsent(locale, () => <String, DateFormat>{});

if (_dfs[locale][format] == null) {
var pattern = _PATTERNS.containsKey(format) ? _PATTERNS[format] : format;
if (pattern is !Iterable) pattern = [pattern];
var df = new DateFormat();
pattern.forEach((p) {
df.addPattern(p);
});
if (format == "short" || format == "shortDate") {
// "short" and "shortDate" formats use a 2-digit year
df = new DateFormat(df.pattern.replaceAll(new RegExp('y+'), 'yy'));
}
_dfs[locale][format] = df;
}
return df.format(date);
return _dfs[locale][format];
}
}
47 changes: 12 additions & 35 deletions test/formatter/date_spec.dart
Original file line number Diff line number Diff line change
Expand Up @@ -26,52 +26,29 @@ void main() {
});

it('should accept various format strings', () {
expect(date(morning, "yy-MM-dd HH:mm:ss")).
toEqual('10-09-03 07:05:08');

expect(date(morning, "yy-MM-dd HH:mm:ss.sss")).
toEqual('10-09-03 07:05:08.008');
expect(date(morning, "yy-MM-dd HH:mm:ss")).toEqual('10-09-03 07:05:08');
expect(date(morning, "yy-MM-dd HH:mm:ss.sss")).toEqual('10-09-03 07:05:08.008');
});

it('should accept default formats', () {

expect(date(noon, "medium")).
toEqual('Sep 3, 2010 12:05:08 PM');

expect(date(noon, "short")).
toEqual('9/3/10 12:05 PM');

expect(date(noon, "fullDate")).
toEqual('Friday, September 3, 2010');

expect(date(noon, "longDate")).
toEqual('September 3, 2010');

expect(date(noon, "mediumDate")).
toEqual('Sep 3, 2010');

expect(date(noon, "shortDate")).
toEqual('9/3/10');

expect(date(noon, "mediumTime")).
toEqual('12:05:08 PM');

expect(date(noon, "shortTime")).
toEqual('12:05 PM');
expect(date(noon, "medium")).toEqual('Sep 3, 2010 12:05:08 PM');
expect(date(noon, "short")).toEqual('9/3/10 12:05 PM');
expect(date(noon, "fullDate")).toEqual('Friday, September 3, 2010');
expect(date(noon, "longDate")).toEqual('September 3, 2010');
expect(date(noon, "mediumDate")).toEqual('Sep 3, 2010');
expect(date(noon, "shortDate")).toEqual('9/3/10');
expect(date(noon, "mediumTime")).toEqual('12:05:08 PM');
expect(date(noon, "shortTime")).toEqual('12:05 PM');
});

it('should use cache without any error', () {

date(noon, "shortTime");
date(noon, "shortTime");
});


it('should accept various locales', async(() {
expect(Intl.withLocale('de', () => date(noon, "medium"))).
toEqual('Sep 3, 2010 12:05:08 nachm.');
expect(Intl.withLocale('fr', () => date(noon, "medium"))).
toEqual('sept. 3, 2010 12:05:08 PM');
expect(Intl.withLocale('de', () => date(noon, "medium"))).toEqual('3. Sep 2010 12:05:08');
expect(Intl.withLocale('fr', () => date(noon, "medium"))).toEqual('3 sept. 2010 12:05:08');
}));
});
}