@@ -72,54 +72,53 @@ define function parse-time-format (descriptor :: <string>) => (_ :: <sequence>)
72
72
end function ;
73
73
74
74
// Each value is a pair of #(time-component . formatter-function) where
75
- // time-component is the index into the return values list of the
76
- // time-components function. 0 = year, 1 = month, etc
75
+ // time-component is a keyword that matches the select statement used in
76
+ // format-time.
77
77
//
78
78
// TODO: BC/AD, BCE/CE (see ISO 8601)
79
- // TODO: make this extensible
80
79
define table $time-format-map :: <string-table>
81
- = { "yyyy" => pair (0 , curry (format-ndigit-int, 4 )),
82
- "yy" => pair (0 , curry (format-ndigit-int-mod, 2 , 100 )),
83
- "mm" => pair (1 , method (stream, month)
84
- format-ndigit-int(2 , stream, month.month-number)
85
- end ),
86
- "mon" => pair (1 , format-short-month-name),
87
- "month" => pair (1 , format-long-month-name),
88
- "dd" => pair (2 , curry (format-ndigit-int, 2 )),
89
- "HH" => pair (3 , curry (format-ndigit-int, 2 )),
90
- "hh" => pair (3 , format-hour-12 ),
91
- "am" => pair (3 , format-lowercase-am-pm),
92
- "pm" => pair (3 , format-lowercase-am-pm),
93
- "AM" => pair (3 , format-uppercase-am-pm),
94
- "PM" => pair (3 , format-uppercase-am-pm),
95
- "MM" => pair (4 , curry (format-ndigit-int, 2 )),
96
- "SS" => pair (5 , curry (format-ndigit-int, 2 )),
97
- "millis" => pair (6 , curry (format-ndigit-int-mod, 3 , 1000 )),
98
- "micros" => pair (6 , curry (format-ndigit-int-mod, 6 , 1_000_000)),
99
- "nanos" => pair (6 , curry (format-ndigit-int-mod, 9 , 1_000_000_000)),
80
+ = { "yyyy" => pair (# "year" , curry (format-ndigit-int, 4 )),
81
+ "yy" => pair (# "year" , curry (format-ndigit-int-mod, 2 , 100 )),
82
+ "mm" => pair (# "month" , method (stream, month)
83
+ format-ndigit-int(2 , stream, month.month-number)
84
+ end ),
85
+ "mon" => pair (# "month" , format-short-month-name),
86
+ "month" => pair (# "month" , format-long-month-name),
87
+ "dd" => pair (# "day-of-month" , curry (format-ndigit-int, 2 )),
88
+ "HH" => pair (# "hour" , curry (format-ndigit-int, 2 )),
89
+ "hh" => pair (# "hour" , format-hour-12 ),
90
+ "am" => pair (# "hour" , format-lowercase-am-pm),
91
+ "pm" => pair (# "hour" , format-lowercase-am-pm),
92
+ "AM" => pair (# "hour" , format-uppercase-am-pm),
93
+ "PM" => pair (# "hour" , format-uppercase-am-pm),
94
+ "MM" => pair (# "minute" , curry (format-ndigit-int, 2 )),
95
+ "SS" => pair (# "second" , curry (format-ndigit-int, 2 )),
96
+ "millis" => pair (# "nanosecond" , curry (format-ndigit-int-mod, 3 , 1000 )),
97
+ "micros" => pair (# "nanosecond" , curry (format-ndigit-int-mod, 6 , 1_000_000)),
98
+ "nanos" => pair (# "nanosecond" , curry (format-ndigit-int-mod, 9 , 1_000_000_000)),
100
99
// f = fractional seconds with minimum digits. fN outputs exactly N digits.
101
- "f" => pair (6 , format-nanos-with-minimum-digits),
100
+ "f" => pair (# "nanosecond" , format-nanos-with-minimum-digits),
102
101
// Not sure if some of these will be used, but might as well be complete.
103
- "f1" => pair (6 , curry (format-ndigit-int-mod, 1 , 10 )),
104
- "f2" => pair (6 , curry (format-ndigit-int-mod, 2 , 100 )),
105
- "f3" => pair (6 , curry (format-ndigit-int-mod, 3 , 1000 )),
106
- "f4" => pair (6 , curry (format-ndigit-int-mod, 4 , 10_000)),
107
- "f5" => pair (6 , curry (format-ndigit-int-mod, 5 , 100_000)),
108
- "f6" => pair (6 , curry (format-ndigit-int-mod, 6 , 1_000_000)),
109
- "f7" => pair (6 , curry (format-ndigit-int-mod, 7 , 10_000_000)),
110
- "f8" => pair (6 , curry (format-ndigit-int-mod, 8 , 100_000_000)),
111
- "f9" => pair (6 , curry (format-ndigit-int-mod, 9 , 1_000_000_000)),
112
-
113
- "zone" => pair (7 , format-zone-name), // UTC, PST, etc
102
+ "f1" => pair (# "nanosecond" , curry (format-ndigit-int-mod, 1 , 10 )),
103
+ "f2" => pair (# "nanosecond" , curry (format-ndigit-int-mod, 2 , 100 )),
104
+ "f3" => pair (# "nanosecond" , curry (format-ndigit-int-mod, 3 , 1000 )),
105
+ "f4" => pair (# "nanosecond" , curry (format-ndigit-int-mod, 4 , 10_000)),
106
+ "f5" => pair (# "nanosecond" , curry (format-ndigit-int-mod, 5 , 100_000)),
107
+ "f6" => pair (# "nanosecond" , curry (format-ndigit-int-mod, 6 , 1_000_000)),
108
+ "f7" => pair (# "nanosecond" , curry (format-ndigit-int-mod, 7 , 10_000_000)),
109
+ "f8" => pair (# "nanosecond" , curry (format-ndigit-int-mod, 8 , 100_000_000)),
110
+ "f9" => pair (# "nanosecond" , curry (format-ndigit-int-mod, 9 , 1_000_000_000)),
111
+
112
+ "zone" => pair (# "zone" , format-zone-name), // UTC, PST, etc
114
113
115
114
// TODO: these fail for <aware-zone>s. Need some refactoring to make sure the
116
115
// offset is found for the correct time.
117
- "offset" => pair (7 , rcurry (format-zone-offset, colon?: #f , utc-name: #f )), // +0000
118
- "offset:" => pair (7 , rcurry (format-zone-offset, colon?: #t , utc-name: #f )), // +00:00
119
- "offset:Z" => pair (7 , rcurry (format-zone-offset, colon?: #t , utc-name: "Z" )), // Z or +02:00
116
+ "offset" => pair (# "zone" , rcurry (format-zone-offset, colon?: #f , utc-name: #f )), // +0000
117
+ "offset:" => pair (# "zone" , rcurry (format-zone-offset, colon?: #t , utc-name: #f )), // +00:00
118
+ "offset:Z" => pair (# "zone" , rcurry (format-zone-offset, colon?: #t , utc-name: "Z" )), // Z or +02:00
120
119
121
- "day" => pair (8 , format-short-weekday),
122
- "weekday" => pair (8 , format-long-weekday),
120
+ "day" => pair (# "day-of-week" , format-short-weekday),
121
+ "weekday" => pair (# "day-of-wook" , format-long-weekday),
123
122
};
124
123
125
124
define function format-nanos-with-minimum-digits
@@ -256,23 +255,32 @@ define /* inline */ method format-time
256
255
format-time(stream, parse-time-format(fmt), time, zone: zone);
257
256
end method ;
258
257
259
- define /* inline */ method format-time
258
+ define method format-time
260
259
(stream :: <stream>, fmt :: <sequence> , time :: <time>, #key zone :: <zone>?)
261
260
=> ()
262
- // I'm assuming that v is stack allocated. Verify.
263
- let (#rest v) = time-components(time);
264
- if (zone)
265
- v[7 ] := zone;
266
- end ;
261
+ let zone :: <zone> = zone | $utc;
262
+ let (year, month, day-of-month, hour, minute, second , nanosecond, day-of-week)
263
+ = time-components(time, zone: zone);
267
264
for (item in fmt)
268
265
select (item by instance? )
269
266
<string>
270
267
=> write(stream, item);
271
268
<pair>
272
269
=> begin
273
- let index :: <integer> = item.head ;
270
+ let value
271
+ = select (item.head )
272
+ # "year" => year;
273
+ # "month" => month;
274
+ # "day-of-month" => day-of-month;
275
+ # "hour" => hour;
276
+ # "minute" => minute;
277
+ # "second" => second ;
278
+ # "nanosecond" => nanosecond;
279
+ # "day-of-week" => day-of-week;
280
+ # "zone" => zone;
281
+ end ;
274
282
let formatter :: <function> = item.tail ;
275
- formatter(stream, v[index] );
283
+ formatter(stream, value );
276
284
end ;
277
285
otherwise => time-error("invalid time format element: %=" , item);
278
286
end ;
0 commit comments