22
33// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat
44
5+ const debug = 0 ;
6+
7+ // Converting skeleton to options
8+ const skeleton_to_options_map = new Map (
9+ [
10+ [ 'G' , { era : 'short' } ] ,
11+ [ 'GG' , { era : 'short' } ] ,
12+ [ 'GGG' , { era : 'short' } ] ,
13+ [ 'GGGG' , { era : 'long' } ] ,
14+ [ 'GGGGG' , { era : 'narrow' } ] ,
15+
16+ [ 'y' , { 'year' : 'numeric' } ] ,
17+ [ 'yy' , { 'year' : '2-digit' } ] ,
18+ [ 'yyy' , { 'year' : 'numeric' } ] ,
19+ [ 'yyyy' , { 'year' : 'numeric' } ] ,
20+
21+ // Quarter not supported
22+
23+ [ 'M' , { 'month' : 'numeric' } ] ,
24+ [ 'MM' , { 'month' : '2-digit' } ] ,
25+ [ 'MMM' , { 'month' : 'short' } ] ,
26+ [ 'MMMM' , { 'month' : 'long' } ] ,
27+ [ 'MMMMM' , { 'month' : 'narrow' } ] ,
28+
29+ [ 'L' , { 'month' : 'numeric' } ] ,
30+ [ 'LL' , { 'month' : '2-digit' } ] ,
31+ [ 'LLL' , { 'month' : 'short' } ] ,
32+ [ 'LLLL' , { 'month' : 'long' } ] ,
33+ [ 'LLLLL' , { 'month' : 'narrow' } ] ,
34+
35+ // Week not supported
36+
37+ [ 'd' , { 'day' : 'numeric' } ] ,
38+ [ 'dd' , { 'day' : '2-digit' } ] ,
39+
40+ [ 'E' , { 'weekday' : 'short' } ] ,
41+ [ 'EE' , { 'weekday' : 'short' } ] ,
42+ [ 'EEE' , { 'weekday' : 'short' } ] ,
43+ [ 'EEEE' , { 'weekday' : 'long' } ] ,
44+ [ 'EEEEE' , { 'weekday' : 'narrow' } ] ,
45+
46+ [ 'h' , { 'hourCycle' : 'h12' , 'hour' : 'numeric' } ] ,
47+ [ 'hh' , { 'hourCycle' : 'h12' , 'hour' : '2-digit' } ] ,
48+ [ 'H' , { 'hourCycle' : 'h24' , 'hour' : 'numeric' } ] ,
49+ [ 'HH' , { 'hourCycle' : 'h24' , 'hour' : '2-digit' } ] ,
50+
51+ [ 'j' , { 'hour' : 'numeric' } ] ,
52+ [ 'jj' , { 'hour' : '2-digit' } ] ,
53+
54+ [ 'm' , { 'minute' : 'numeric' } ] ,
55+ [ 'mm' , { 'minute' : '2-digit' } ] ,
56+
57+ [ 's' , { 'second' : 'numeric' } ] ,
58+ [ 'ss' , { 'second' : '2-digit' } ] ,
59+
60+ [ 'z' , { 'timeZoneName' : 'short' } ] ,
61+ [ 'zzzz' , { 'timeZoneName' : 'long' } ] ,
62+
63+ [ 'O' , { 'timeZoneName' : 'shortOffset' } ] ,
64+ [ 'OOOO' , { 'timeZoneName' : 'longOffset' } ] ,
65+
66+ [ 'v' , { 'timeZoneName' : 'shortGeneric' } ] ,
67+ [ 'vvvv' , { 'timeZoneName' : 'longGeneric' } ] ,
68+
69+ [ 'V' , { 'timeZoneName' : 'shortGeneric' } ] ,
70+ [ 'VV' , { 'timeZoneName' : 'shortGeneric' } ] ,
71+ [ 'VVV' , { 'timeZoneName' : 'shortGeneric' } ] ,
72+ [ 'VVVV' , { 'timeZoneName' : 'longGeneric' } ] ,
73+ ]
74+ ) ;
75+
76+ // E.g., "yyDEEEE" --> ["yy", "D", "EEEE"]
77+ function split_skeleton_into_fields ( skeleton ) {
78+ return skeleton . match ( / ( .) \1* / g) || [ ] ;
79+ }
80+
81+ function fill_options_from_skeleton_parts ( skeleton_parts ) {
82+ let skeleton_options = { } ;
83+ if ( skeleton_parts === undefined || skeleton_parts == null ) {
84+ return skeleton_options ;
85+ }
86+ for ( const part of skeleton_parts ) {
87+ if ( skeleton_to_options_map . has ( part ) ) {
88+ let options = skeleton_to_options_map . get ( part ) ;
89+ Object . assign ( skeleton_options , options ) ;
90+ } else {
91+ console . log (
92+ '# NodeJS: DateTimeFormat: UNKNOWN MAPPING FOR PART = %s' ,
93+ part ) ;
94+ }
95+ }
96+ return skeleton_options ;
97+ }
98+
599
6100module . exports = {
7101 testDateTimeFmt : function ( json ) {
@@ -12,25 +106,38 @@ module.exports = {
12106 locale = 'und' ;
13107 }
14108
109+ let input_options = { } ;
15110 let test_options = { } ;
111+
16112 if ( json [ 'options' ] ) {
17- test_options = json [ 'options' ] ;
113+ input_options = json [ 'options' ] ;
18114 }
19115
20- let calendar ;
21- try {
22- calendar = test_options [ 'calendar' ] ;
23- } catch {
24- calendar = null ;
116+ // Handle skeleton specification.
117+ if ( input_options && 'skeleton' in input_options ) {
118+ let skeleton = input_options [ 'skeleton' ] ;
119+ let split = split_skeleton_into_fields ( skeleton ) ;
120+ if ( debug > 0 ) {
121+ console . log ( '# skeleton: %s, options %s' , skeleton , split ) ;
122+ }
123+
124+ test_options = fill_options_from_skeleton_parts ( split ) ;
125+ if ( debug > 0 ) {
126+ console . log ( '# TEST_OPTIONS: %s' , split , test_options ) ;
127+ }
25128 }
129+
26130 let return_json = { 'label' : label } ;
27131
28132 let timezone ;
29- try {
30- timezone = test_options [ 'time_zone' ] ;
31- } catch {
32- timezone = options [ 'timeZone' ] = 'UTC' ;
133+ if ( 'timeZone' in input_options ) {
134+ test_options [ 'timeZone' ] = input_options [ 'timeZone' ] ;
33135 }
136+
137+ if ( 'zoneStyle' in input_options ) {
138+ test_options [ 'zoneStyle' ] = input_options [ 'zoneStyle' ] ;
139+ }
140+
34141 // Get the date from input milliseconds.
35142 // Prefer milliseconds
36143 let iso_date ;
@@ -48,10 +155,27 @@ module.exports = {
48155 } else {
49156 test_date_string = iso_date ;
50157 }
51- console . log ( 'test_date_string %s' , test_date_string ) ;
52158 test_date = new Date ( test_date_string ) ;
53159 }
54160
161+ // Get date and time styles
162+ let dateStyle ;
163+ let timeStyle ;
164+
165+ if ( 'timeStyle' in input_options ) {
166+ test_options [ 'timeStyle' ] = input_options [ 'timeStyle' ] ;
167+ }
168+ if ( 'dateStyle' in input_options ) {
169+ test_options [ 'dateStyle' ] = input_options [ 'dateStyle' ] ;
170+ }
171+
172+ let calendar ;
173+ try {
174+ calendar = input_options [ 'calendar' ] ;
175+ test_options [ 'calendar' ] = calendar ;
176+ } catch {
177+ calendar = null ;
178+ }
55179 try {
56180 if ( calendar ) {
57181 const supported_calendars = intl_locale . calendars ;
0 commit comments