@@ -734,6 +734,59 @@ fn do_strptime(s: &str, format: &str) -> Result<Tm, ~str> {
734734}
735735
736736fn do_strftime( format : & str , tm : & Tm ) -> ~str {
737+ fn days_in_year ( year : int ) -> i32 {
738+ if ( ( year % 4 == 0 ) && ( ( year % 100 != 0 ) || ( year % 400 == 0 ) ) ) {
739+ 366 /* Days in a leap year */
740+ } else {
741+ 365 /* Days in a non-leap year */
742+ }
743+ }
744+
745+ fn iso_week_days ( yday : i32 , wday : i32 ) -> int {
746+ /* The number of days from the first day of the first ISO week of this
747+ * year to the year day YDAY with week day WDAY.
748+ * ISO weeks start on Monday. The first ISO week has the year's first
749+ * Thursday.
750+ * YDAY may be as small as yday_minimum.
751+ */
752+ let yday: int = yday as int ;
753+ let wday: int = wday as int ;
754+ let iso_week_start_wday: int = 1 ; /* Monday */
755+ let iso_week1_wday: int = 4 ; /* Thursday */
756+ let yday_minimum: int = 366 ;
757+ /* Add enough to the first operand of % to make it nonnegative. */
758+ let big_enough_multiple_of_7: int = ( yday_minimum / 7 + 2 ) * 7 ;
759+
760+ yday - ( yday - wday + iso_week1_wday + big_enough_multiple_of_7) % 7
761+ + iso_week1_wday - iso_week_start_wday
762+ }
763+
764+ fn iso_week( ch : char , tm : & Tm ) -> ~str {
765+ let mut year: int = tm. tm_year as int + 1900 ;
766+ let mut days: int = iso_week_days ( tm. tm_yday , tm. tm_wday ) ;
767+
768+ if ( days < 0 ) {
769+ /* This ISO week belongs to the previous year. */
770+ year -= 1 ;
771+ days = iso_week_days ( tm. tm_yday + ( days_in_year ( year) ) , tm. tm_wday ) ;
772+ } else {
773+ let d: int = iso_week_days ( tm. tm_yday - ( days_in_year ( year) ) ,
774+ tm. tm_wday ) ;
775+ if ( 0 <= d) {
776+ /* This ISO week belongs to the next year. */
777+ year += 1 ;
778+ days = d;
779+ }
780+ }
781+
782+ match ch {
783+ 'G' => format ! ( "{}" , year) ,
784+ 'g' => format ! ( "{:02d}" , ( year % 100 + 100 ) % 100 ) ,
785+ 'V' => format ! ( "{:02d}" , days / 7 + 1 ) ,
786+ _ => ~""
787+ }
788+ }
789+
737790 fn parse_type ( ch: char, tm: & Tm ) -> ~str {
738791 //FIXME (#2350): Implement missing types.
739792 let die = || format ! ( "strftime: can't understand this format {} " , ch) ;
@@ -812,8 +865,8 @@ fn do_strftime(format: &str, tm: &Tm) -> ~str {
812865 parse_type( 'm' , tm) ,
813866 parse_type( 'd' , tm) )
814867 }
815- // 'G' {}
816- // 'g' {}
868+ 'G' => iso_week ( 'G' , tm ) ,
869+ 'g' => iso_week ( 'g' , tm ) ,
817870 'H' => format ! ( "{:02d}" , tm. tm_hour) ,
818871 'I' => {
819872 let mut h = tm. tm_hour ;
@@ -855,12 +908,12 @@ fn do_strftime(format: &str, tm: &Tm) -> ~str {
855908 parse_type( 'S' , tm) )
856909 }
857910 't' => ~"\t ",
858- // 'U' {}
911+ 'U' => format ! ( "{:02d}" , ( tm . tm_yday - tm . tm_wday + 7 ) / 7 ) ,
859912 'u' => {
860913 let i = tm. tm_wday as int ;
861914 ( if i == 0 { 7 } else { i } ) . to_str ( )
862915 }
863- // 'V' {}
916+ 'V' => iso_week ( 'V' , tm ) ,
864917 'v' => {
865918 format ! ( "{}-{}-{}" ,
866919 parse_type( 'e' , tm) ,
@@ -1222,8 +1275,8 @@ mod tests {
12221275 assert_eq!(local.strftime(" %e"), ~" 13 ");
12231276 assert_eq!(local.strftime(" %f"), ~" 000054321 ");
12241277 assert_eq!(local.strftime(" %F "), ~" 2009 -02 -13 ");
1225- // assert !(local.strftime(" %G ") == " 2009 ");
1226- // assert !(local.strftime(" %g") == " 09 ");
1278+ assert_eq !(local.strftime(" %G "), ~ " 2009 ");
1279+ assert_eq !(local.strftime(" %g"), ~ " 09 ");
12271280 assert_eq!(local.strftime(" %H "), ~" 15 ");
12281281 assert_eq!(local.strftime(" %I "), ~" 03 ");
12291282 assert_eq!(local.strftime(" %j"), ~" 044 ");
@@ -1240,9 +1293,9 @@ mod tests {
12401293 assert_eq!(local.strftime(" %s"), ~" 1234567890 ");
12411294 assert_eq!(local.strftime(" %T "), ~" 15 : 31 : 30 ");
12421295 assert_eq!(local.strftime(" %t"), ~"\t " ) ;
1243- // assert !(local.strftime("%U") == "06");
1296+ assert_eq ! ( local. strftime( "%U" ) , ~ "06 ");
12441297 assert_eq!(local.strftime(" %u"), ~" 5 ");
1245- // assert !(local.strftime(" %V ") == " 07 ");
1298+ assert_eq !(local.strftime(" %V "), ~ " 07 ");
12461299 assert_eq!(local.strftime(" %v"), ~" 13 -Feb -2009 ");
12471300 // assert!(local.strftime(" %W ") == " 06 ");
12481301 assert_eq!(local.strftime(" %w"), ~" 5 ");
0 commit comments