@@ -116,6 +116,175 @@ fn now() -> tm {
116
116
at ( get_time ( ) )
117
117
}
118
118
119
+ fn strftime ( format : str , tm : tm ) -> str {
120
+ fn parse_type ( ch : char , tm : tm ) -> str {
121
+ //FIXME: Implement missing types.
122
+ alt check ch {
123
+ 'A' {
124
+ alt check tm. tm_wday as int {
125
+ 0 { "Sunday" }
126
+ 1 { "Monday" }
127
+ 2 { "Tuesday" }
128
+ 3 { "Wednesday" }
129
+ 4 { "Thursday" }
130
+ 5 { "Friday" }
131
+ 6 { "Saturday" }
132
+ }
133
+ }
134
+ 'a' {
135
+ alt check tm. tm_wday as int {
136
+ 0 { "Sun" }
137
+ 1 { "Mon" }
138
+ 2 { "Tue" }
139
+ 3 { "Wed" }
140
+ 4 { "Thu" }
141
+ 5 { "Fri" }
142
+ 6 { "Sat" }
143
+ }
144
+ }
145
+ 'B' {
146
+ alt check tm. tm_mon as int {
147
+ 0 { "January" }
148
+ 1 { "February" }
149
+ 2 { "March" }
150
+ 3 { "April" }
151
+ 4 { "May" }
152
+ 5 { "June" }
153
+ 6 { "July" }
154
+ 7 { "August" }
155
+ 8 { "September" }
156
+ 9 { "October" }
157
+ 10 { "November" }
158
+ 11 { "December" }
159
+ }
160
+ }
161
+ 'b' | 'h' {
162
+ alt check tm. tm_mon as int {
163
+ 0 { "Jan" }
164
+ 1 { "Feb" }
165
+ 2 { "Mar" }
166
+ 3 { "Apr" }
167
+ 4 { "May" }
168
+ 5 { "Jun" }
169
+ 6 { "Jul" }
170
+ 7 { "Aug" }
171
+ 8 { "Sep" }
172
+ 9 { "Oct" }
173
+ 10 { "Nov" }
174
+ 11 { "Dec" }
175
+ }
176
+ }
177
+ 'C' { #fmt ( "%02d" , ( tm. tm_year as int + 1900 ) / 100 ) }
178
+ 'c' {
179
+ #fmt ( "%s %s %s %s %s" ,
180
+ parse_type ( 'a' , tm) ,
181
+ parse_type ( 'b' , tm) ,
182
+ parse_type ( 'e' , tm) ,
183
+ parse_type ( 'T' , tm) ,
184
+ parse_type ( 'Y' , tm) )
185
+ }
186
+ 'D' | 'x' {
187
+ #fmt ( "%s/%s/%s" ,
188
+ parse_type ( 'm' , tm) ,
189
+ parse_type ( 'd' , tm) ,
190
+ parse_type ( 'y' , tm) )
191
+ }
192
+ 'd' { #fmt ( "%02d" , tm. tm_mday as int ) }
193
+ 'e' { #fmt ( "%2d" , tm. tm_mday as int ) }
194
+ 'F' {
195
+ #fmt ( "%s-%s-%s" ,
196
+ parse_type ( 'Y' , tm) ,
197
+ parse_type ( 'm' , tm) ,
198
+ parse_type ( 'd' , tm) )
199
+ }
200
+ //'G' {}
201
+ //'g' {}
202
+ 'H' { #fmt ( "%02d" , tm. tm_hour as int ) }
203
+ 'I' {
204
+ let mut h = tm. tm_hour as int ;
205
+ if h == 0 { h = 12 }
206
+ if h > 12 { h -= 12 }
207
+ #fmt ( "%02d" , h)
208
+ }
209
+ 'j' { #fmt ( "%03d" , tm. tm_yday as int + 1 ) }
210
+ 'k' { #fmt ( "%2d" , tm. tm_hour as int ) }
211
+ 'l' {
212
+ let mut h = tm. tm_hour as int ;
213
+ if h == 0 { h = 12 }
214
+ if h > 12 { h -= 12 }
215
+ #fmt ( "%2d" , h)
216
+ }
217
+ 'M' { #fmt ( "%02d" , tm. tm_min as int ) }
218
+ 'm' { #fmt ( "%02d" , tm. tm_mon as int + 1 ) }
219
+ 'n' { "\n " }
220
+ 'P' { if tm. tm_hour as int < 12 { "am" } else { "pm" } }
221
+ 'p' { if tm. tm_hour as int < 12 { "AM" } else { "PM" } }
222
+ 'R' {
223
+ #fmt ( "%s:%s" ,
224
+ parse_type ( 'H' , tm) ,
225
+ parse_type ( 'M' , tm) )
226
+ }
227
+ 'r' {
228
+ #fmt ( "%s:%s:%s %s" ,
229
+ parse_type ( 'I' , tm) ,
230
+ parse_type ( 'M' , tm) ,
231
+ parse_type ( 'S' , tm) ,
232
+ parse_type ( 'p' , tm) )
233
+ }
234
+ 'S' { #fmt ( "%02d" , tm. tm_sec as int ) }
235
+ 's' { #fmt ( "%d" , tm. to_timespec ( ) . sec as int ) }
236
+ 'T' | 'X' {
237
+ #fmt ( "%s:%s:%s" ,
238
+ parse_type ( 'H' , tm) ,
239
+ parse_type ( 'M' , tm) ,
240
+ parse_type ( 'S' , tm) )
241
+ }
242
+ 't' { "\t " }
243
+ //'U' {}
244
+ 'u' {
245
+ let i = tm. tm_wday as int ;
246
+ int:: str ( if i == 0 { 7 } else { i } )
247
+ }
248
+ //'V' {}
249
+ 'v' {
250
+ #fmt ( "%s-%s-%s" ,
251
+ parse_type ( 'e' , tm) ,
252
+ parse_type ( 'b' , tm) ,
253
+ parse_type ( 'Y' , tm) )
254
+ }
255
+ //'W' {}
256
+ 'w' { int:: str ( tm. tm_wday as int ) }
257
+ //'X' {}
258
+ //'x' {}
259
+ 'Y' { int:: str ( tm. tm_year as int + 1900 ) }
260
+ 'y' { #fmt ( "%02d" , ( tm. tm_year as int + 1900 ) % 100 ) }
261
+ 'Z' { tm. tm_zone }
262
+ 'z' {
263
+ let sign = if tm. tm_gmtoff > 0_i32 { '+' } else { '-' } ;
264
+ let mut m = i32:: abs ( tm. tm_gmtoff ) / 60_i32 ;
265
+ let h = m / 60_i32 ;
266
+ m -= h * 60_i32 ;
267
+ #fmt ( "%c%02d%02d" , sign, h as int , m as int )
268
+ }
269
+ //'+' {}
270
+ '%' { "%" }
271
+ }
272
+ }
273
+
274
+ let mut buf = "" ;
275
+
276
+ io:: with_str_reader ( format) { |rdr|
277
+ while !rdr. eof ( ) {
278
+ alt rdr. read_char ( ) {
279
+ '%' { buf += parse_type ( rdr. read_char ( ) , tm) ; }
280
+ ch { str : : push_char ( buf, ch) ; }
281
+ }
282
+ }
283
+ }
284
+
285
+ buf
286
+ }
287
+
119
288
impl tm for tm {
120
289
#[ doc = "Convert time to the seconds from January 1, 1970" ]
121
290
fn to_timespec ( ) -> timespec {
@@ -137,6 +306,58 @@ impl tm for tm {
137
306
fn to_utc ( ) -> tm {
138
307
at_utc ( self . to_timespec ( ) )
139
308
}
309
+
310
+ #[ doc = "
311
+ Return a string of the current time in the form
312
+ \" Thu Jan 1 00:00:00 1970\" .
313
+ " ]
314
+ fn ctime ( ) -> str { self . strftime ( "%c" ) }
315
+
316
+ #[ doc = "Formats the time according to the format string." ]
317
+ fn strftime ( format : str ) -> str { strftime ( format, self ) }
318
+
319
+ #[ doc = "
320
+ Returns a time string formatted according to RFC 822.
321
+
322
+ local: \" Thu, 22 Mar 2012 07:53:18 PST\"
323
+ utc: \" Thu, 22 Mar 2012 14:53:18 UTC\"
324
+ " ]
325
+ fn rfc822 ( ) -> str {
326
+ if self . tm_gmtoff == 0_i32 {
327
+ self . strftime ( "%a, %d %b %Y %T GMT" )
328
+ } else {
329
+ self . strftime ( "%a, %d %b %Y %T %Z" )
330
+ }
331
+ }
332
+
333
+ #[ doc = "
334
+ Returns a time string formatted according to RFC 822 with Zulu time.
335
+
336
+ local: \" Thu, 22 Mar 2012 07:53:18 -0700\"
337
+ utc: \" Thu, 22 Mar 2012 14:53:18 -0000\"
338
+ " ]
339
+ fn rfc822z ( ) -> str {
340
+ self . strftime ( "%a, %d %b %Y %T %z" )
341
+ }
342
+
343
+ #[ doc = "
344
+ Returns a time string formatted according to ISO 8601.
345
+
346
+ local: \" 2012-02-22T07:53:18-07:00\"
347
+ utc: \" 2012-02-22T14:53:18Z\"
348
+ " ]
349
+ fn rfc3339 ( ) -> str {
350
+ if self . tm_gmtoff == 0_i32 {
351
+ self . strftime ( "%Y-%m-%dT%H:%M:%SZ" )
352
+ } else {
353
+ let s = self . strftime ( "%Y-%m-%dT%H:%M:%S" ) ;
354
+ let sign = if self . tm_gmtoff > 0_i32 { '+' } else { '-' } ;
355
+ let mut m = i32:: abs ( self . tm_gmtoff ) / 60_i32 ;
356
+ let h = m / 60_i32 ;
357
+ m -= h * 60_i32 ;
358
+ s + #fmt ( "%c%02d:%02d" , sign, h as int , m as int )
359
+ }
360
+ }
140
361
}
141
362
142
363
#[ cfg( test) ]
@@ -258,4 +479,89 @@ mod tests {
258
479
assert utc. to_local ( ) == local;
259
480
assert utc. to_local ( ) . to_utc ( ) == utc;
260
481
}
482
+
483
+ #[ test]
484
+ fn test_ctime ( ) {
485
+ os:: setenv ( "TZ" , "America/Los_Angeles" ) ;
486
+
487
+ let time = { sec: 1234567890_i64 , nsec: 54321_i32 } ;
488
+ let utc = at_utc ( time) ;
489
+ let local = at ( time) ;
490
+
491
+ assert utc. ctime ( ) == "Fri Feb 13 23:31:30 2009" ;
492
+ assert local. ctime ( ) == "Fri Feb 13 15:31:30 2009" ;
493
+ }
494
+
495
+ #[ test]
496
+ fn test_strftime ( ) {
497
+ os:: setenv ( "TZ" , "America/Los_Angeles" ) ;
498
+
499
+ let time = { sec: 1234567890_i64 , nsec: 54321_i32 } ;
500
+ let utc = at_utc ( time) ;
501
+ let local = at ( time) ;
502
+
503
+ assert local. strftime ( "" ) == "" ;
504
+ assert local. strftime ( "%A" ) == "Friday" ;
505
+ assert local. strftime ( "%a" ) == "Fri" ;
506
+ assert local. strftime ( "%B" ) == "February" ;
507
+ assert local. strftime ( "%b" ) == "Feb" ;
508
+ assert local. strftime ( "%C" ) == "20" ;
509
+ assert local. strftime ( "%c" ) == "Fri Feb 13 15:31:30 2009" ;
510
+ assert local. strftime ( "%D" ) == "02/13/09" ;
511
+ assert local. strftime ( "%d" ) == "13" ;
512
+ assert local. strftime ( "%e" ) == "13" ;
513
+ assert local. strftime ( "%F" ) == "2009-02-13" ;
514
+ // assert local.strftime("%G") == "2009";
515
+ // assert local.strftime("%g") == "09";
516
+ assert local. strftime ( "%H" ) == "15" ;
517
+ assert local. strftime ( "%I" ) == "03" ;
518
+ assert local. strftime ( "%j" ) == "044" ;
519
+ assert local. strftime ( "%k" ) == "15" ;
520
+ assert local. strftime ( "%l" ) == " 3" ;
521
+ assert local. strftime ( "%M" ) == "31" ;
522
+ assert local. strftime ( "%m" ) == "02" ;
523
+ assert local. strftime ( "%n" ) == "\n " ;
524
+ assert local. strftime ( "%P" ) == "pm" ;
525
+ assert local. strftime ( "%p" ) == "PM" ;
526
+ assert local. strftime ( "%R" ) == "15:31" ;
527
+ assert local. strftime ( "%r" ) == "03:31:30 PM" ;
528
+ assert local. strftime ( "%S" ) == "30" ;
529
+ assert local. strftime ( "%s" ) == "1234567890" ;
530
+ assert local. strftime ( "%T" ) == "15:31:30" ;
531
+ assert local. strftime ( "%t" ) == "\t " ;
532
+ // assert local.strftime("%U") == "06";
533
+ assert local. strftime ( "%u" ) == "5" ;
534
+ // assert local.strftime("%V") == "07";
535
+ assert local. strftime ( "%v" ) == "13-Feb-2009" ;
536
+ // assert local.strftime("%W") == "06";
537
+ assert local. strftime ( "%w" ) == "5" ;
538
+ // handle "%X"
539
+ // handle "%x"
540
+ assert local. strftime ( "%Y" ) == "2009" ;
541
+ assert local. strftime ( "%y" ) == "09" ;
542
+
543
+ // FIXME: We should probably standardize on the timezone
544
+ // abbreviation.
545
+ let zone = local. strftime ( "%Z" ) ;
546
+ assert zone == "PST" || zone == "Pacific Standard Time" ;
547
+
548
+ assert local. strftime ( "%z" ) == "-0800" ;
549
+ assert local. strftime ( "%%" ) == "%" ;
550
+
551
+ // FIXME: We should probably standardize on the timezone
552
+ // abbreviation.
553
+ let rfc822 = local. rfc822 ( ) ;
554
+ let prefix = "Fri, 13 Feb 2009 15:31:30 " ;
555
+ assert rfc822 == prefix + "PST" ||
556
+ rfc822 == prefix + "Pacific Standard Time" ;
557
+
558
+ assert local. ctime ( ) == "Fri Feb 13 15:31:30 2009" ;
559
+ assert local. rfc822z ( ) == "Fri, 13 Feb 2009 15:31:30 -0800" ;
560
+ assert local. rfc3339 ( ) == "2009-02-13T15:31:30-08:00" ;
561
+
562
+ assert utc. ctime ( ) == "Fri Feb 13 23:31:30 2009" ;
563
+ assert utc. rfc822 ( ) == "Fri, 13 Feb 2009 23:31:30 GMT" ;
564
+ assert utc. rfc822z ( ) == "Fri, 13 Feb 2009 23:31:30 -0000" ;
565
+ assert utc. rfc3339 ( ) == "2009-02-13T23:31:30Z" ;
566
+ }
261
567
}
0 commit comments