From c463772ebdbfca65017ac1bc2c8322d229b291a9 Mon Sep 17 00:00:00 2001 From: Luis de Bethencourt Date: Tue, 1 Oct 2013 22:20:46 -0400 Subject: [PATCH 1/2] extra: %U support in time::strftime Fixes #2350 --- src/libextra/time.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libextra/time.rs b/src/libextra/time.rs index 7f08fcd908a..34b50588ae2 100644 --- a/src/libextra/time.rs +++ b/src/libextra/time.rs @@ -855,7 +855,7 @@ fn do_strftime(format: &str, tm: &Tm) -> ~str { parse_type('S', tm)) } 't' => ~"\t", - //'U' {} + 'U' => format!("{:02d}", (tm.tm_yday - tm.tm_wday + 7) / 7), 'u' => { let i = tm.tm_wday as int; (if i == 0 { 7 } else { i }).to_str() @@ -1240,7 +1240,7 @@ mod tests { assert_eq!(local.strftime("%s"), ~"1234567890"); assert_eq!(local.strftime("%T"), ~"15:31:30"); assert_eq!(local.strftime("%t"), ~"\t"); - // assert!(local.strftime("%U") == "06"); + assert_eq!(local.strftime("%U"), ~"06"); assert_eq!(local.strftime("%u"), ~"5"); // assert!(local.strftime("%V") == "07"); assert_eq!(local.strftime("%v"), ~"13-Feb-2009"); From 1005b7976bde4b8d42ec2e1d924015b754567401 Mon Sep 17 00:00:00 2001 From: Luis de Bethencourt Date: Tue, 1 Oct 2013 23:06:26 -0400 Subject: [PATCH 2/2] extra: %G, %g and %V support in time::strftime Fixes #2350 --- src/libextra/time.rs | 65 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 59 insertions(+), 6 deletions(-) diff --git a/src/libextra/time.rs b/src/libextra/time.rs index 34b50588ae2..161a96b1676 100644 --- a/src/libextra/time.rs +++ b/src/libextra/time.rs @@ -734,6 +734,59 @@ fn do_strptime(s: &str, format: &str) -> Result { } fn do_strftime(format: &str, tm: &Tm) -> ~str { + fn days_in_year(year: int) -> i32 { + if ((year % 4 == 0) && ((year % 100 != 0) || (year % 400 == 0))) { + 366 /* Days in a leap year */ + } else { + 365 /* Days in a non-leap year */ + } + } + + fn iso_week_days(yday: i32, wday: i32) -> int { + /* The number of days from the first day of the first ISO week of this + * year to the year day YDAY with week day WDAY. + * ISO weeks start on Monday. The first ISO week has the year's first + * Thursday. + * YDAY may be as small as yday_minimum. + */ + let yday: int = yday as int; + let wday: int = wday as int; + let iso_week_start_wday: int = 1; /* Monday */ + let iso_week1_wday: int = 4; /* Thursday */ + let yday_minimum: int = 366; + /* Add enough to the first operand of % to make it nonnegative. */ + let big_enough_multiple_of_7: int = (yday_minimum / 7 + 2) * 7; + + yday - (yday - wday + iso_week1_wday + big_enough_multiple_of_7) % 7 + + iso_week1_wday - iso_week_start_wday + } + + fn iso_week(ch:char, tm: &Tm) -> ~str { + let mut year: int = tm.tm_year as int + 1900; + let mut days: int = iso_week_days (tm.tm_yday, tm.tm_wday); + + if (days < 0) { + /* This ISO week belongs to the previous year. */ + year -= 1; + days = iso_week_days (tm.tm_yday + (days_in_year(year)), tm.tm_wday); + } else { + let d: int = iso_week_days (tm.tm_yday - (days_in_year(year)), + tm.tm_wday); + if (0 <= d) { + /* This ISO week belongs to the next year. */ + year += 1; + days = d; + } + } + + match ch { + 'G' => format!("{}", year), + 'g' => format!("{:02d}", (year % 100 + 100) % 100), + 'V' => format!("{:02d}", days / 7 + 1), + _ => ~"" + } + } + fn parse_type(ch: char, tm: &Tm) -> ~str { //FIXME (#2350): Implement missing types. let die = || format!("strftime: can't understand this format {} ", ch); @@ -812,8 +865,8 @@ fn do_strftime(format: &str, tm: &Tm) -> ~str { parse_type('m', tm), parse_type('d', tm)) } - //'G' {} - //'g' {} + 'G' => iso_week('G', tm), + 'g' => iso_week('g', tm), 'H' => format!("{:02d}", tm.tm_hour), 'I' => { let mut h = tm.tm_hour; @@ -860,7 +913,7 @@ fn do_strftime(format: &str, tm: &Tm) -> ~str { let i = tm.tm_wday as int; (if i == 0 { 7 } else { i }).to_str() } - //'V' {} + 'V' => iso_week('V', tm), 'v' => { format!("{}-{}-{}", parse_type('e', tm), @@ -1222,8 +1275,8 @@ mod tests { assert_eq!(local.strftime("%e"), ~"13"); assert_eq!(local.strftime("%f"), ~"000054321"); assert_eq!(local.strftime("%F"), ~"2009-02-13"); - // assert!(local.strftime("%G") == "2009"); - // assert!(local.strftime("%g") == "09"); + assert_eq!(local.strftime("%G"), ~"2009"); + assert_eq!(local.strftime("%g"), ~"09"); assert_eq!(local.strftime("%H"), ~"15"); assert_eq!(local.strftime("%I"), ~"03"); assert_eq!(local.strftime("%j"), ~"044"); @@ -1242,7 +1295,7 @@ mod tests { assert_eq!(local.strftime("%t"), ~"\t"); assert_eq!(local.strftime("%U"), ~"06"); assert_eq!(local.strftime("%u"), ~"5"); - // assert!(local.strftime("%V") == "07"); + assert_eq!(local.strftime("%V"), ~"07"); assert_eq!(local.strftime("%v"), ~"13-Feb-2009"); // assert!(local.strftime("%W") == "06"); assert_eq!(local.strftime("%w"), ~"5");