Skip to content

Commit e4234a7

Browse files
committed
Date: Add formatDateToParts (2/2)
Fixes globalizejs#678 Closes globalizejs#697 Closes globalizejs#700
1 parent 6919f43 commit e4234a7

27 files changed

+1009
-724
lines changed

README.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,24 @@ Read more details about locale at [UTS#35 locale][].
446446

447447
[Read more...](doc/api/date/date-formatter.md)
448448

449+
- **.dateToPartsFormatter( [options] )`**
450+
451+
Return a function that formats a date into parts tokens according to the given `options`. The
452+
default formatting is numeric year, month, and day (i.e., `{ skeleton: "yMd" }`.
453+
454+
```javascript
455+
.dateToPartsFormatter()( new Date() )
456+
// > [
457+
// { "type": "month", "value": "3" },
458+
// { "type": "literal", "value": "/" },
459+
// { "type": "day", "value": "17" },
460+
// { "type": "literal", "value": "/" },
461+
// { "type": "year", "value": "2017" }
462+
// ]
463+
```
464+
465+
[Read more...](doc/api/date/date-to-parts-formatter.md)
466+
449467
- **`.dateParser( [options] )`**
450468

451469
Return a function that parses a string representing a date into a JavaScript Date object according
@@ -475,6 +493,10 @@ Read more details about locale at [UTS#35 locale][].
475493

476494
Alias for `.dateFormatter( [options] )( value )`.
477495

496+
- **`.formatDateToParts( value [, options] )`**
497+
498+
Alias for `.dateToPartsFormatter( [options] )( value )`.
499+
478500
- **`.parseDate( value [, options] )`**
479501

480502
Alias for `.dateParser( [options] )( value )`.

doc/api/date/date-formatter.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ var enFormatter = Globalize( "en" ).dateFormatter(),
8989
deFormatter = Globalize( "de" ).dateFormatter();
9090

9191
enFormatter( new Date( 2010, 10, 30, 17, 55 ) );
92-
// > "11/30/2010, 5:55 PM"
92+
// > "11/30/2010"
9393

9494
deFormatter( new Date( 2010, 10, 30, 17, 55 ) );
9595
// > "30.11.2010"
Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
## .dateToPartsFormatter( [options] ) ➜ function( value )
2+
3+
Return a function that formats a date into parts tokens according to the given
4+
`options`. The default formatting is numeric year, month, and day (i.e., `{
5+
skeleton: "yMd" }`.
6+
7+
The returned function is invoked with one argument: the Date instance `value` to
8+
be formatted.
9+
10+
### Parameters
11+
12+
**options**
13+
14+
Please, see [.dateFormatter() options](./date-formatter.md#parameters).
15+
16+
**value**
17+
18+
Date instance to be formatted, eg. `new Date()`;
19+
20+
### Returns
21+
22+
An Array of objects containing the formatted date in parts. The returned structure looks like this:
23+
24+
```js
25+
[
26+
{ type: "day", value: "17" },
27+
{ type: "weekday", value "Monday" }
28+
]
29+
```
30+
31+
Possible types are the following:
32+
33+
- `day`
34+
35+
The string used for the day, e.g., `"17"`, `"١٦"`.
36+
37+
- `dayPeriod`
38+
39+
The string used for the day period, e.g., `"AM"`, `"PM"`.
40+
41+
- `era`
42+
43+
The string used for the era, e.g., `"AD"`, `"d. C."`.
44+
45+
- `hour`
46+
47+
The string used for the hour, e.g., `"3"`, `"03"`.
48+
49+
- `literal`
50+
51+
The string used for separating date and time values, e.g., `"/"`, `", "`,
52+
`"o'clock"`, `" de "`.
53+
54+
- `minute`
55+
56+
The string used for the minute, e.g., `"00"`.
57+
58+
- `month`
59+
60+
The string used for the month, e.g., `"12"`.
61+
62+
- `second`
63+
64+
The string used for the second, e.g., `"07"` or `"42"`.
65+
66+
- `timeZoneName`
67+
68+
The string used for the name of the time zone, e.g., `"EST".`
69+
70+
- `weekday`
71+
72+
The string used for the weekday, e.g., `"M"`, `"Monday"`, `"Montag".`
73+
74+
- `year`
75+
76+
The string used for the year, e.g., `"2012"`, `"96".`
77+
78+
79+
### Example
80+
81+
Prior to using any date methods, you must load
82+
`cldr/main/{locale}/ca-gregorian.json`, `cldr/main/{locale}/timeZoneNames.json`,
83+
`cldr/supplemental/timeData.json`, `cldr/supplemental/weekData.json`, and the
84+
CLDR content required by the number module. Read [CLDR content][] if you need
85+
more information.
86+
87+
[CLDR content]: ../../../README.md#2-cldr-content
88+
89+
You can use the static method `Globalize.dateToPartsFormatter()`, which uses the
90+
default locale.
91+
92+
```javascript
93+
var formatter;
94+
95+
Globalize.locale( "en" );
96+
formatter = Globalize.dateToPartsFormatter();
97+
98+
formatter( new Date( 2010, 10, 30 ) );
99+
// > [
100+
// { "type": "month", "value": "11" },
101+
// { "type": "literal", "value": "/" },
102+
// { "type": "day", "value": "30" },
103+
// { "type": "literal", "value": "/" },
104+
// { "type": "year", "value": "2010" }
105+
// ]
106+
```
107+
108+
You can use the instance method `.dateToPartsFormatter()`, which uses the instance locale.
109+
110+
```javascript
111+
var enFormatter = Globalize( "en" ).dateToPartsFormatter(),
112+
deFormatter = Globalize( "de" ).dateToPartsFormatter();
113+
114+
enFormatter( new Date( 2010, 10, 30 ) );
115+
// > [
116+
// { "type": "month", "value": "11" },
117+
// { "type": "literal", "value": "/" },
118+
// { "type": "day", "value": "30" },
119+
// { "type": "literal", "value": "/" },
120+
// { "type": "year", "value": "2010" }
121+
// ]
122+
123+
deFormatter( new Date( 2010, 10, 30 ) );
124+
// > [
125+
// { type: 'day', value: '30' },
126+
// { type: 'literal', value: '.' },
127+
// { type: 'month', value: '11' },
128+
// { type: 'literal', value: '.' },
129+
// { type: 'year', value: '2010' }
130+
// ]
131+
```
132+
133+
The information is available separately and it can be formatted and concatenated
134+
again in a customized way. For example by using [`Array.prototype.map()`][],
135+
[arrow functions][], a [switch statement][], [template literals][], and
136+
[`Array.prototype.reduce()`][].
137+
138+
[`Array.prototype.map()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map
139+
[arrow functions]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions
140+
[switch statement]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/switch
141+
[template literals]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals
142+
[`Array.prototype.reduce()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce
143+
144+
```javascript
145+
var formatter;
146+
147+
Globalize.locale( "en" );
148+
formatter = Globalize.dateToPartsFormatter({datetime: "short"});
149+
150+
formatter( new Date( 2010, 10, 30, 17, 55 ) ).map(({type, value}) => {
151+
switch ( type ) {
152+
case "year": return `<strong>${value}</strong>`;
153+
default: return value;
154+
}
155+
}).join( "" );
156+
// > "11/30/<strong>10</strong>, 5:55 PM"
157+
```
158+
159+
Please, see [.dateFormatter() example](./date-formatter.md#example) for
160+
additional examples such as using `date`, `time`, `datetime`, and `skeleton`
161+
options.
162+
163+
For improved performance on iterations, first create the formatter. Then, reuse
164+
it on each loop.
165+
166+
```javascript
167+
// In an application, this array could have a few hundred entries
168+
var dates = [ new Date( 2010, 10, 30, 17, 55 ), new Date( 2015, 3, 18, 4, 25 ) ];
169+
var formatter = Globalize( "en" ).dateToPartsFormatter({ time: "short" });
170+
171+
var formattedDates = dates.map(function( date ) {
172+
return formatter( date );
173+
});
174+
// > [
175+
// [
176+
// { "type": "hour", "value": "5" },
177+
// { "type": "literal", "value": ":" },
178+
// { "type": "minute", "value": "55" },
179+
// { "type": "literal", "value": " " },
180+
// { "type": "dayperiod", "value": "PM" }
181+
// ],
182+
// [
183+
// { "type": "hour", "value": "4" },
184+
// { "type": "literal", "value": ":" },
185+
// { "type": "minute", "value": "25" },
186+
// { "type": "literal", "value": " " },
187+
// { "type": "dayperiod", "value": "AM" }
188+
// ]
189+
// ]
190+
```

examples/amd-bower/bower.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "globalize-hello-world-amd-bower",
33
"dependencies": {
44
"cldr-data": "*",
5-
"globalize": ">=1.2.0-a <2.0.0"
5+
"globalize": ">=1.3.0-a <2.0.0"
66
},
77
"devDependencies": {
88
"requirejs": "2.1.14",

examples/amd-bower/index.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ <h2>Requirements</h2>
2020
<div id="demo" style="display: none">
2121
<h2>Demo output</h2>
2222
<p>Now: <span id="date"></span></p>
23+
<p>Now: <span id="dateToParts"></span> (note the highlighted month, the markup was added using formatDateToParts)</p>
2324
<p>A number: <span id="number"></span></p>
2425
<p>A currency: <span id="currency"></span></p>
2526
<p>Plural form of <span id="plural-number"></span> is <span id="plural-form"></span></p>

examples/amd-bower/main.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,18 @@ require([
7676
datetime: "medium"
7777
});
7878

79+
// Use Globalize to format dates to parts.
80+
document.getElementById( "dateToParts" ).innerHTML = en.formatDateToParts( new Date(), {
81+
datetime: "medium"
82+
}).map(function( part ) {
83+
switch(part.type) {
84+
case "month": return "<strong>" + part.value + "</strong>";
85+
default: return part.value;
86+
}
87+
}).reduce(function( memo, value ) {
88+
return memo + value;
89+
});
90+
7991
// Use Globalize to format numbers.
8092
number = en.numberFormatter();
8193
document.getElementById( "number" ).textContent = number( 12345.6789 );

examples/app-npm-webpack/app/index.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,21 @@ document.getElementById( "currency" ).textContent = currencyFormatter( 69900 );
1111
var dateFormatter = Globalize.dateFormatter({ datetime: "medium" });
1212
document.getElementById( "date" ).textContent = dateFormatter( new Date() );
1313

14+
var _dateToPartsFormatter = Globalize.dateToPartsFormatter({ datetime: "medium" });
15+
var dateToPartsFormatter = function( value ) {
16+
return _dateToPartsFormatter( value, {
17+
datetime: "medium"
18+
}).map(function( part ) {
19+
switch(part.type) {
20+
case "month": return "<strong>" + part.value + "</strong>";
21+
default: return part.value;
22+
}
23+
}).reduce(function( memo, value ) {
24+
return memo + value;
25+
});
26+
};
27+
document.getElementById( "date-to-parts" ).innerHTML = dateToPartsFormatter( new Date() );
28+
1429
var relativeTimeFormatter = Globalize.relativeTimeFormatter( "second" );
1530
document.getElementById( "relative-time" ).textContent = relativeTimeFormatter( 0 );
1631

@@ -22,6 +37,7 @@ document.getElementById( "intro-1" ).textContent = Globalize.formatMessage( "int
2237
document.getElementById( "number-label" ).textContent = Globalize.formatMessage( "number-label" );
2338
document.getElementById( "currency-label" ).textContent = Globalize.formatMessage( "currency-label" );
2439
document.getElementById( "date-label" ).textContent = Globalize.formatMessage( "date-label" );
40+
document.getElementById( "date-to-parts-label" ).textContent = Globalize.formatMessage( "date-to-parts-label" );
2541
document.getElementById( "relative-time-label" ).textContent = Globalize.formatMessage( "relative-time-label" );
2642
document.getElementById( "unit-label" ).textContent = Globalize.formatMessage( "unit-label" );
2743
document.getElementById( "message-1" ).textContent = Globalize.formatMessage( "message-1", {
@@ -44,6 +60,7 @@ document.getElementById( "demo" ).style.display = "block";
4460
setInterval(function() {
4561
var elapsedTime = +( ( startTime - new Date() ) / 1000 ).toFixed( 0 );
4662
document.getElementById( "date" ).textContent = dateFormatter( new Date() );
63+
document.getElementById( "date-to-parts" ).innerHTML = dateToPartsFormatter( new Date() );
4764
document.getElementById( "relative-time" ).textContent = relativeTimeFormatter( elapsedTime );
4865
document.getElementById( "message-1" ).textContent = Globalize.formatMessage( "message-1", {
4966
currency: currencyFormatter( 69900 ),

examples/app-npm-webpack/index-template.html

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ <h2>Requirements</h2>
3333
<td><span id="date-label">Standalone Date</span></td>
3434
<td>"<span id="date"></span>"</td>
3535
</tr>
36+
<tr>
37+
<td><span id="date-to-parts-label">Standalone Date (note the highlighted month, the markup was added using formatDateToParts)</span></td>
38+
<td>"<span id="date-to-parts"></span>"</td>
39+
</tr>
3640
<tr>
3741
<td><span id="relative-time-label">Standalone Relative Time</span></td>
3842
<td>"<span id="relative-time"></span>"</td>

examples/app-npm-webpack/messages/de.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
"number-label": "Zahl",
55
"currency-label": "Währung",
66
"date-label": "Datum",
7+
"date-to-parts-label": "Datum (beachten Sie den hervorgehobenen Monat, das Markup wurde mit dateToPartsFormatter hinzugefügt)",
78
"relative-time-label": "Relative Zeit",
89
"unit-label": "Einheit",
910
"message-1": "Ein Beispiel mit Zahl \"{number}\", Währung \"{currency}\", Datum \"{date}\", relative Zeit \"{relativeTime}\", und Einheit \"{unit}\".",

examples/app-npm-webpack/messages/en.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
"number-label": "Number",
55
"currency-label": "Currency",
66
"date-label": "Date",
7+
"date-to-parts-label": "Date (note the highlighted month, the markup was added using formatDateToParts)",
78
"relative-time-label": "Relative Time",
89
"unit-label": "Unit",
910
"message-1": "An example of a message using mixed number \"{number}\", currency \"{currency}\", date \"{date}\", relative time \"{relativeTime}\", and unit \"{unit}\".",

0 commit comments

Comments
 (0)