2013-05-27 11:55:42 -05:00
|
|
|
// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
|
2012-12-03 18:48:01 -06:00
|
|
|
// file at the top-level directory of this distribution and at
|
|
|
|
// http://rust-lang.org/COPYRIGHT.
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
|
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
|
|
// option. This file may not be copied, modified, or distributed
|
|
|
|
// except according to those terms.
|
|
|
|
|
2013-05-28 22:11:41 -05:00
|
|
|
#[allow(missing_doc)];
|
|
|
|
|
2013-06-28 17:32:26 -05:00
|
|
|
use std::io;
|
Replaces the free-standing functions in f32, &c.
The free-standing functions in f32, f64, i8, i16, i32, i64, u8, u16,
u32, u64, float, int, and uint are replaced with generic functions in
num instead.
If you were previously using any of those functions, just replace them
with the corresponding function with the same name in num.
Note: If you were using a function that corresponds to an operator, use
the operator instead.
2013-07-08 11:05:17 -05:00
|
|
|
use std::num;
|
2013-06-28 17:32:26 -05:00
|
|
|
use std::str;
|
2013-05-24 21:35:29 -05:00
|
|
|
|
2013-03-22 16:00:15 -05:00
|
|
|
static NSEC_PER_SEC: i32 = 1_000_000_000_i32;
|
2013-01-21 22:50:01 -06:00
|
|
|
|
2013-03-05 14:21:02 -06:00
|
|
|
pub mod rustrt {
|
|
|
|
use super::Tm;
|
|
|
|
|
2013-10-14 07:33:05 -05:00
|
|
|
extern {
|
2013-08-02 16:30:00 -05:00
|
|
|
pub fn get_time(sec: &mut i64, nsec: &mut i32);
|
|
|
|
pub fn precise_time_ns(ns: &mut u64);
|
|
|
|
pub fn rust_tzset();
|
|
|
|
pub fn rust_gmtime(sec: i64, nsec: i32, result: &mut Tm);
|
|
|
|
pub fn rust_localtime(sec: i64, nsec: i32, result: &mut Tm);
|
|
|
|
pub fn rust_timegm(tm: &Tm) -> i64;
|
|
|
|
pub fn rust_mktime(tm: &Tm) -> i64;
|
2013-03-05 14:21:02 -06:00
|
|
|
}
|
2011-04-29 13:54:06 -05:00
|
|
|
}
|
|
|
|
|
2012-08-11 14:12:40 -05:00
|
|
|
/// A record specifying a time value in seconds and nanoseconds.
|
2013-08-16 05:17:27 -05:00
|
|
|
#[deriving(Clone, DeepClone, Eq, Encodable, Decodable)]
|
2012-11-27 00:22:22 -06:00
|
|
|
pub struct Timespec { sec: i64, nsec: i32 }
|
|
|
|
|
2013-01-21 22:50:01 -06:00
|
|
|
/*
|
|
|
|
* Timespec assumes that pre-epoch Timespecs have negative sec and positive
|
|
|
|
* nsec fields. Darwin's and Linux's struct timespec functions handle pre-
|
|
|
|
* epoch timestamps using a "two steps back, one step forward" representation,
|
|
|
|
* though the man pages do not actually document this. For example, the time
|
|
|
|
* -1.2 seconds before the epoch is represented by `Timespec { sec: -2_i64,
|
|
|
|
* nsec: 800_000_000_i32 }`.
|
|
|
|
*/
|
2013-05-31 17:17:22 -05:00
|
|
|
impl Timespec {
|
|
|
|
pub fn new(sec: i64, nsec: i32) -> Timespec {
|
2013-03-28 20:39:09 -05:00
|
|
|
assert!(nsec >= 0 && nsec < NSEC_PER_SEC);
|
2012-11-27 00:22:22 -06:00
|
|
|
Timespec { sec: sec, nsec: nsec }
|
|
|
|
}
|
|
|
|
}
|
2011-04-29 13:54:06 -05:00
|
|
|
|
2013-02-14 13:47:00 -06:00
|
|
|
impl Ord for Timespec {
|
2013-03-21 23:34:30 -05:00
|
|
|
fn lt(&self, other: &Timespec) -> bool {
|
2013-01-17 01:37:21 -06:00
|
|
|
self.sec < other.sec ||
|
|
|
|
(self.sec == other.sec && self.nsec < other.nsec)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-07-04 16:53:12 -05:00
|
|
|
/**
|
|
|
|
* Returns the current time as a `timespec` containing the seconds and
|
2012-08-11 14:12:40 -05:00
|
|
|
* nanoseconds since 1970-01-01T00:00:00Z.
|
2012-07-04 16:53:12 -05:00
|
|
|
*/
|
2012-10-05 18:17:10 -05:00
|
|
|
pub fn get_time() -> Timespec {
|
2013-08-14 20:41:40 -05:00
|
|
|
#[fixed_stack_segment]; #[inline(never)];
|
|
|
|
|
2013-01-10 23:23:07 -06:00
|
|
|
unsafe {
|
|
|
|
let mut sec = 0i64;
|
|
|
|
let mut nsec = 0i32;
|
|
|
|
rustrt::get_time(&mut sec, &mut nsec);
|
|
|
|
return Timespec::new(sec, nsec);
|
|
|
|
}
|
2012-10-05 18:17:10 -05:00
|
|
|
}
|
|
|
|
|
2011-06-28 19:58:44 -05:00
|
|
|
|
2012-07-04 16:53:12 -05:00
|
|
|
/**
|
|
|
|
* Returns the current value of a high-resolution performance counter
|
|
|
|
* in nanoseconds since an unspecified epoch.
|
|
|
|
*/
|
2012-10-05 18:17:10 -05:00
|
|
|
pub fn precise_time_ns() -> u64 {
|
2013-08-14 20:41:40 -05:00
|
|
|
#[fixed_stack_segment]; #[inline(never)];
|
|
|
|
|
2013-01-10 23:23:07 -06:00
|
|
|
unsafe {
|
|
|
|
let mut ns = 0u64;
|
|
|
|
rustrt::precise_time_ns(&mut ns);
|
|
|
|
ns
|
|
|
|
}
|
2012-10-05 18:17:10 -05:00
|
|
|
}
|
|
|
|
|
2011-06-28 19:58:44 -05:00
|
|
|
|
2012-07-04 16:53:12 -05:00
|
|
|
/**
|
|
|
|
* Returns the current value of a high-resolution performance counter
|
|
|
|
* in seconds since an unspecified epoch.
|
|
|
|
*/
|
2013-09-26 01:26:09 -05:00
|
|
|
pub fn precise_time_s() -> f64 {
|
|
|
|
return (precise_time_ns() as f64) / 1000000000.;
|
2011-08-19 17:16:48 -05:00
|
|
|
}
|
2012-02-18 03:32:52 -06:00
|
|
|
|
2012-09-28 18:24:57 -05:00
|
|
|
pub fn tzset() {
|
2013-08-14 20:41:40 -05:00
|
|
|
#[fixed_stack_segment]; #[inline(never)];
|
|
|
|
|
2013-01-10 23:23:07 -06:00
|
|
|
unsafe {
|
|
|
|
rustrt::rust_tzset();
|
|
|
|
}
|
2012-04-13 19:33:02 -05:00
|
|
|
}
|
|
|
|
|
2013-08-16 05:17:27 -05:00
|
|
|
#[deriving(Clone, DeepClone, Eq, Encodable, Decodable)]
|
2012-11-27 00:22:22 -06:00
|
|
|
pub struct Tm {
|
2012-06-29 18:26:56 -05:00
|
|
|
tm_sec: i32, // seconds after the minute ~[0-60]
|
|
|
|
tm_min: i32, // minutes after the hour ~[0-59]
|
|
|
|
tm_hour: i32, // hours after midnight ~[0-23]
|
|
|
|
tm_mday: i32, // days of the month ~[1-31]
|
|
|
|
tm_mon: i32, // months since January ~[0-11]
|
2012-04-03 12:32:26 -05:00
|
|
|
tm_year: i32, // years since 1900
|
2012-06-29 18:26:56 -05:00
|
|
|
tm_wday: i32, // days since Sunday ~[0-6]
|
|
|
|
tm_yday: i32, // days since January 1 ~[0-365]
|
2012-04-03 12:32:26 -05:00
|
|
|
tm_isdst: i32, // Daylight Savings Time flag
|
|
|
|
tm_gmtoff: i32, // offset from UTC in seconds
|
2012-07-14 00:57:48 -05:00
|
|
|
tm_zone: ~str, // timezone abbreviation
|
2012-04-03 12:32:26 -05:00
|
|
|
tm_nsec: i32, // nanoseconds
|
2012-07-11 17:00:40 -05:00
|
|
|
}
|
|
|
|
|
2013-03-21 23:34:30 -05:00
|
|
|
pub fn empty_tm() -> Tm {
|
2013-08-23 00:11:30 -05:00
|
|
|
// 64 is the max size of the timezone buffer allocated on windows
|
|
|
|
// in rust_localtime. In glibc the max timezone size is supposedly 3.
|
|
|
|
let zone = str::with_capacity(64);
|
2012-11-27 00:22:22 -06:00
|
|
|
Tm {
|
2012-04-03 12:32:26 -05:00
|
|
|
tm_sec: 0_i32,
|
|
|
|
tm_min: 0_i32,
|
|
|
|
tm_hour: 0_i32,
|
|
|
|
tm_mday: 0_i32,
|
|
|
|
tm_mon: 0_i32,
|
|
|
|
tm_year: 0_i32,
|
|
|
|
tm_wday: 0_i32,
|
|
|
|
tm_yday: 0_i32,
|
|
|
|
tm_isdst: 0_i32,
|
|
|
|
tm_gmtoff: 0_i32,
|
2013-08-23 00:11:30 -05:00
|
|
|
tm_zone: zone,
|
2012-04-03 12:32:26 -05:00
|
|
|
tm_nsec: 0_i32,
|
2012-11-27 00:22:22 -06:00
|
|
|
}
|
2012-04-03 12:32:26 -05:00
|
|
|
}
|
|
|
|
|
2012-07-04 16:53:12 -05:00
|
|
|
/// Returns the specified time in UTC
|
2012-09-28 18:24:57 -05:00
|
|
|
pub fn at_utc(clock: Timespec) -> Tm {
|
2013-08-14 20:41:40 -05:00
|
|
|
#[fixed_stack_segment]; #[inline(never)];
|
|
|
|
|
2013-01-10 23:23:07 -06:00
|
|
|
unsafe {
|
2013-04-12 00:10:12 -05:00
|
|
|
let Timespec { sec, nsec } = clock;
|
2013-01-10 23:23:07 -06:00
|
|
|
let mut tm = empty_tm();
|
2013-03-08 19:44:37 -06:00
|
|
|
rustrt::rust_gmtime(sec, nsec, &mut tm);
|
2013-02-15 01:30:30 -06:00
|
|
|
tm
|
2013-01-10 23:23:07 -06:00
|
|
|
}
|
2012-04-03 12:32:26 -05:00
|
|
|
}
|
|
|
|
|
2012-07-04 16:53:12 -05:00
|
|
|
/// Returns the current time in UTC
|
2012-09-28 18:24:57 -05:00
|
|
|
pub fn now_utc() -> Tm {
|
2012-04-03 12:32:26 -05:00
|
|
|
at_utc(get_time())
|
|
|
|
}
|
|
|
|
|
2012-07-04 16:53:12 -05:00
|
|
|
/// Returns the specified time in the local timezone
|
2012-09-28 18:24:57 -05:00
|
|
|
pub fn at(clock: Timespec) -> Tm {
|
2013-08-14 20:41:40 -05:00
|
|
|
#[fixed_stack_segment]; #[inline(never)];
|
|
|
|
|
2013-01-10 23:23:07 -06:00
|
|
|
unsafe {
|
2013-04-12 00:10:12 -05:00
|
|
|
let Timespec { sec, nsec } = clock;
|
2013-01-10 23:23:07 -06:00
|
|
|
let mut tm = empty_tm();
|
2013-03-08 19:44:37 -06:00
|
|
|
rustrt::rust_localtime(sec, nsec, &mut tm);
|
2013-02-15 01:30:30 -06:00
|
|
|
tm
|
2013-01-10 23:23:07 -06:00
|
|
|
}
|
2012-04-03 12:32:26 -05:00
|
|
|
}
|
|
|
|
|
2012-07-04 16:53:12 -05:00
|
|
|
/// Returns the current time in the local timezone
|
2012-09-28 18:24:57 -05:00
|
|
|
pub fn now() -> Tm {
|
2012-04-03 12:32:26 -05:00
|
|
|
at(get_time())
|
|
|
|
}
|
|
|
|
|
2012-11-17 11:11:57 -06:00
|
|
|
|
2013-05-31 17:17:22 -05:00
|
|
|
impl Tm {
|
2012-11-17 11:11:57 -06:00
|
|
|
/// Convert time to the seconds from January 1, 1970
|
2013-05-31 17:17:22 -05:00
|
|
|
pub fn to_timespec(&self) -> Timespec {
|
2013-08-14 20:41:40 -05:00
|
|
|
#[fixed_stack_segment]; #[inline(never)];
|
|
|
|
|
2013-01-10 23:23:07 -06:00
|
|
|
unsafe {
|
2013-05-27 11:52:56 -05:00
|
|
|
let sec = match self.tm_gmtoff {
|
|
|
|
0_i32 => rustrt::rust_timegm(self),
|
|
|
|
_ => rustrt::rust_mktime(self)
|
|
|
|
};
|
|
|
|
|
2013-01-10 23:23:07 -06:00
|
|
|
Timespec::new(sec, self.tm_nsec)
|
2012-11-17 11:11:57 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Convert time to the local timezone
|
2013-05-31 17:17:22 -05:00
|
|
|
pub fn to_local(&self) -> Tm {
|
2012-11-17 11:11:57 -06:00
|
|
|
at(self.to_timespec())
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Convert time to the UTC
|
2013-05-31 17:17:22 -05:00
|
|
|
pub fn to_utc(&self) -> Tm {
|
2012-11-17 11:11:57 -06:00
|
|
|
at_utc(self.to_timespec())
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return a string of the current time in the form
|
|
|
|
* "Thu Jan 1 00:00:00 1970".
|
|
|
|
*/
|
2013-05-31 17:17:22 -05:00
|
|
|
pub fn ctime(&self) -> ~str { self.strftime("%c") }
|
2012-11-17 11:11:57 -06:00
|
|
|
|
|
|
|
/// Formats the time according to the format string.
|
2013-05-31 17:17:22 -05:00
|
|
|
pub fn strftime(&self, format: &str) -> ~str {
|
2013-02-15 01:30:30 -06:00
|
|
|
strftime(format, self)
|
2012-11-27 00:22:22 -06:00
|
|
|
}
|
2012-11-17 11:11:57 -06:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns a time string formatted according to RFC 822.
|
|
|
|
*
|
|
|
|
* local: "Thu, 22 Mar 2012 07:53:18 PST"
|
|
|
|
* utc: "Thu, 22 Mar 2012 14:53:18 UTC"
|
|
|
|
*/
|
2013-05-31 17:17:22 -05:00
|
|
|
pub fn rfc822(&self) -> ~str {
|
2012-11-17 11:11:57 -06:00
|
|
|
if self.tm_gmtoff == 0_i32 {
|
2013-05-19 00:07:44 -05:00
|
|
|
self.strftime("%a, %d %b %Y %T GMT")
|
2012-11-17 11:11:57 -06:00
|
|
|
} else {
|
2013-05-19 00:07:44 -05:00
|
|
|
self.strftime("%a, %d %b %Y %T %Z")
|
2012-11-17 11:11:57 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns a time string formatted according to RFC 822 with Zulu time.
|
|
|
|
*
|
|
|
|
* local: "Thu, 22 Mar 2012 07:53:18 -0700"
|
|
|
|
* utc: "Thu, 22 Mar 2012 14:53:18 -0000"
|
|
|
|
*/
|
2013-05-31 17:17:22 -05:00
|
|
|
pub fn rfc822z(&self) -> ~str {
|
2013-05-19 00:07:44 -05:00
|
|
|
self.strftime("%a, %d %b %Y %T %z")
|
2012-11-17 11:11:57 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns a time string formatted according to ISO 8601.
|
|
|
|
*
|
|
|
|
* local: "2012-02-22T07:53:18-07:00"
|
|
|
|
* utc: "2012-02-22T14:53:18Z"
|
|
|
|
*/
|
2013-05-31 17:17:22 -05:00
|
|
|
pub fn rfc3339(&self) -> ~str {
|
2012-11-17 11:11:57 -06:00
|
|
|
if self.tm_gmtoff == 0_i32 {
|
2013-05-19 00:07:44 -05:00
|
|
|
self.strftime("%Y-%m-%dT%H:%M:%SZ")
|
2012-11-17 11:11:57 -06:00
|
|
|
} else {
|
2013-05-19 00:07:44 -05:00
|
|
|
let s = self.strftime("%Y-%m-%dT%H:%M:%S");
|
2012-11-17 11:11:57 -06:00
|
|
|
let sign = if self.tm_gmtoff > 0_i32 { '+' } else { '-' };
|
Replaces the free-standing functions in f32, &c.
The free-standing functions in f32, f64, i8, i16, i32, i64, u8, u16,
u32, u64, float, int, and uint are replaced with generic functions in
num instead.
If you were previously using any of those functions, just replace them
with the corresponding function with the same name in num.
Note: If you were using a function that corresponds to an operator, use
the operator instead.
2013-07-08 11:05:17 -05:00
|
|
|
let mut m = num::abs(self.tm_gmtoff) / 60_i32;
|
2012-11-17 11:11:57 -06:00
|
|
|
let h = m / 60_i32;
|
|
|
|
m -= h * 60_i32;
|
2013-09-27 22:18:50 -05:00
|
|
|
s + format!("{}{:02d}:{:02d}", sign, h as int, m as int)
|
2012-11-17 11:11:57 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-10-03 15:01:42 -05:00
|
|
|
/// Parses the time from the string according to the format string.
|
|
|
|
pub fn strptime(s: &str, format: &str) -> Result<Tm, ~str> {
|
2012-08-24 14:03:11 -05:00
|
|
|
fn match_str(s: &str, pos: uint, needle: &str) -> bool {
|
2012-04-03 12:37:02 -05:00
|
|
|
let mut i = pos;
|
2013-08-03 11:45:23 -05:00
|
|
|
for ch in needle.byte_iter() {
|
2012-04-03 12:37:02 -05:00
|
|
|
if s[i] != ch {
|
2012-08-01 19:30:05 -05:00
|
|
|
return false;
|
2012-04-03 12:37:02 -05:00
|
|
|
}
|
|
|
|
i += 1u;
|
|
|
|
}
|
2012-08-01 19:30:05 -05:00
|
|
|
return true;
|
2012-04-03 12:37:02 -05:00
|
|
|
}
|
|
|
|
|
2012-08-24 14:03:11 -05:00
|
|
|
fn match_strs(ss: &str, pos: uint, strs: &[(~str, i32)])
|
2012-08-20 14:23:37 -05:00
|
|
|
-> Option<(i32, uint)> {
|
2012-04-03 12:37:02 -05:00
|
|
|
let mut i = 0u;
|
2012-11-27 00:22:22 -06:00
|
|
|
let len = strs.len();
|
2012-04-03 12:37:02 -05:00
|
|
|
while i < len {
|
2013-06-20 00:15:50 -05:00
|
|
|
match strs[i] { // can't use let due to let-pattern bugs
|
2013-05-29 18:59:33 -05:00
|
|
|
(ref needle, value) => {
|
|
|
|
if match_str(ss, pos, *needle) {
|
2013-06-09 09:44:58 -05:00
|
|
|
return Some((value, pos + needle.len()));
|
2013-05-29 18:59:33 -05:00
|
|
|
}
|
|
|
|
}
|
2012-04-03 12:37:02 -05:00
|
|
|
}
|
|
|
|
i += 1u;
|
|
|
|
}
|
|
|
|
|
2012-08-20 14:23:37 -05:00
|
|
|
None
|
2012-04-03 12:37:02 -05:00
|
|
|
}
|
|
|
|
|
2012-08-24 14:03:11 -05:00
|
|
|
fn match_digits(ss: &str, pos: uint, digits: uint, ws: bool)
|
2012-08-20 14:23:37 -05:00
|
|
|
-> Option<(i32, uint)> {
|
2012-04-03 12:37:02 -05:00
|
|
|
let mut pos = pos;
|
2013-07-07 02:54:41 -05:00
|
|
|
let len = ss.len();
|
2012-04-03 12:37:02 -05:00
|
|
|
let mut value = 0_i32;
|
|
|
|
|
|
|
|
let mut i = 0u;
|
|
|
|
while i < digits {
|
2013-07-07 02:54:41 -05:00
|
|
|
if pos >= len {
|
|
|
|
return None;
|
|
|
|
}
|
2013-06-10 06:46:36 -05:00
|
|
|
let range = ss.char_range_at(pos);
|
2012-11-26 22:05:19 -06:00
|
|
|
pos = range.next;
|
2012-04-03 12:37:02 -05:00
|
|
|
|
2012-11-26 22:05:19 -06:00
|
|
|
match range.ch {
|
2012-09-01 20:38:05 -05:00
|
|
|
'0' .. '9' => {
|
2012-11-26 22:05:19 -06:00
|
|
|
value = value * 10_i32 + (range.ch as i32 - '0' as i32);
|
2012-04-03 12:37:02 -05:00
|
|
|
}
|
2012-08-03 21:59:04 -05:00
|
|
|
' ' if ws => (),
|
2012-08-20 14:23:37 -05:00
|
|
|
_ => return None
|
2012-04-03 12:37:02 -05:00
|
|
|
}
|
|
|
|
i += 1u;
|
|
|
|
}
|
|
|
|
|
2012-08-20 14:23:37 -05:00
|
|
|
Some((value, pos))
|
2012-04-03 12:37:02 -05:00
|
|
|
}
|
|
|
|
|
2013-09-06 01:13:02 -05:00
|
|
|
fn match_fractional_seconds(ss: &str, pos: uint) -> (i32, uint) {
|
|
|
|
let len = ss.len();
|
|
|
|
let mut value = 0_i32;
|
|
|
|
let mut multiplier = NSEC_PER_SEC / 10;
|
|
|
|
let mut pos = pos;
|
|
|
|
|
|
|
|
loop {
|
|
|
|
if pos >= len {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
let range = ss.char_range_at(pos);
|
|
|
|
|
|
|
|
match range.ch {
|
|
|
|
'0' .. '9' => {
|
|
|
|
pos = range.next;
|
|
|
|
// This will drop digits after the nanoseconds place
|
|
|
|
let digit = range.ch as i32 - '0' as i32;
|
|
|
|
value += digit * multiplier;
|
|
|
|
multiplier /= 10;
|
|
|
|
}
|
|
|
|
_ => break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
(value, pos)
|
|
|
|
}
|
|
|
|
|
2013-01-13 22:31:09 -06:00
|
|
|
fn match_digits_in_range(ss: &str, pos: uint, digits: uint, ws: bool,
|
|
|
|
min: i32, max: i32) -> Option<(i32, uint)> {
|
2013-01-13 05:38:33 -06:00
|
|
|
match match_digits(ss, pos, digits, ws) {
|
|
|
|
Some((val, pos)) if val >= min && val <= max => {
|
|
|
|
Some((val, pos))
|
|
|
|
}
|
|
|
|
_ => None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-08-26 18:54:31 -05:00
|
|
|
fn parse_char(s: &str, pos: uint, c: char) -> Result<uint, ~str> {
|
2013-06-10 06:46:36 -05:00
|
|
|
let range = s.char_range_at(pos);
|
2012-04-03 12:37:02 -05:00
|
|
|
|
2012-11-26 22:05:19 -06:00
|
|
|
if c == range.ch {
|
|
|
|
Ok(range.next)
|
2012-04-03 12:37:02 -05:00
|
|
|
} else {
|
2013-09-27 22:18:50 -05:00
|
|
|
Err(format!("Expected {}, found {}",
|
2012-04-03 12:37:02 -05:00
|
|
|
str::from_char(c),
|
2012-11-26 22:05:19 -06:00
|
|
|
str::from_char(range.ch)))
|
2012-04-03 12:37:02 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-11-27 00:22:22 -06:00
|
|
|
fn parse_type(s: &str, pos: uint, ch: char, tm: &mut Tm)
|
2012-08-26 18:54:31 -05:00
|
|
|
-> Result<uint, ~str> {
|
2012-08-06 14:34:08 -05:00
|
|
|
match ch {
|
2013-05-19 00:07:44 -05:00
|
|
|
'A' => match match_strs(s, pos, [
|
2012-08-03 21:59:04 -05:00
|
|
|
(~"Sunday", 0_i32),
|
|
|
|
(~"Monday", 1_i32),
|
|
|
|
(~"Tuesday", 2_i32),
|
|
|
|
(~"Wednesday", 3_i32),
|
|
|
|
(~"Thursday", 4_i32),
|
|
|
|
(~"Friday", 5_i32),
|
|
|
|
(~"Saturday", 6_i32)
|
|
|
|
]) {
|
2012-08-26 18:54:31 -05:00
|
|
|
Some(item) => { let (v, pos) = item; tm.tm_wday = v; Ok(pos) }
|
|
|
|
None => Err(~"Invalid day")
|
2012-08-06 19:14:32 -05:00
|
|
|
},
|
2013-05-19 00:07:44 -05:00
|
|
|
'a' => match match_strs(s, pos, [
|
2012-08-03 21:59:04 -05:00
|
|
|
(~"Sun", 0_i32),
|
|
|
|
(~"Mon", 1_i32),
|
|
|
|
(~"Tue", 2_i32),
|
|
|
|
(~"Wed", 3_i32),
|
|
|
|
(~"Thu", 4_i32),
|
|
|
|
(~"Fri", 5_i32),
|
|
|
|
(~"Sat", 6_i32)
|
|
|
|
]) {
|
2012-08-26 18:54:31 -05:00
|
|
|
Some(item) => { let (v, pos) = item; tm.tm_wday = v; Ok(pos) }
|
|
|
|
None => Err(~"Invalid day")
|
2012-08-06 19:14:32 -05:00
|
|
|
},
|
2013-05-19 00:07:44 -05:00
|
|
|
'B' => match match_strs(s, pos, [
|
2012-08-03 21:59:04 -05:00
|
|
|
(~"January", 0_i32),
|
|
|
|
(~"February", 1_i32),
|
|
|
|
(~"March", 2_i32),
|
|
|
|
(~"April", 3_i32),
|
|
|
|
(~"May", 4_i32),
|
|
|
|
(~"June", 5_i32),
|
|
|
|
(~"July", 6_i32),
|
|
|
|
(~"August", 7_i32),
|
|
|
|
(~"September", 8_i32),
|
|
|
|
(~"October", 9_i32),
|
|
|
|
(~"November", 10_i32),
|
|
|
|
(~"December", 11_i32)
|
|
|
|
]) {
|
2012-08-26 18:54:31 -05:00
|
|
|
Some(item) => { let (v, pos) = item; tm.tm_mon = v; Ok(pos) }
|
|
|
|
None => Err(~"Invalid month")
|
2012-08-06 19:14:32 -05:00
|
|
|
},
|
2013-05-19 00:07:44 -05:00
|
|
|
'b' | 'h' => match match_strs(s, pos, [
|
2012-08-03 21:59:04 -05:00
|
|
|
(~"Jan", 0_i32),
|
|
|
|
(~"Feb", 1_i32),
|
|
|
|
(~"Mar", 2_i32),
|
|
|
|
(~"Apr", 3_i32),
|
|
|
|
(~"May", 4_i32),
|
|
|
|
(~"Jun", 5_i32),
|
|
|
|
(~"Jul", 6_i32),
|
|
|
|
(~"Aug", 7_i32),
|
|
|
|
(~"Sep", 8_i32),
|
|
|
|
(~"Oct", 9_i32),
|
|
|
|
(~"Nov", 10_i32),
|
|
|
|
(~"Dec", 11_i32)
|
|
|
|
]) {
|
2012-08-26 18:54:31 -05:00
|
|
|
Some(item) => { let (v, pos) = item; tm.tm_mon = v; Ok(pos) }
|
|
|
|
None => Err(~"Invalid month")
|
2012-08-06 19:14:32 -05:00
|
|
|
},
|
2013-01-13 22:31:09 -06:00
|
|
|
'C' => match match_digits_in_range(s, pos, 2u, false, 0_i32,
|
|
|
|
99_i32) {
|
2012-08-20 14:23:37 -05:00
|
|
|
Some(item) => {
|
2012-04-03 12:37:02 -05:00
|
|
|
let (v, pos) = item;
|
2012-08-03 21:59:04 -05:00
|
|
|
tm.tm_year += (v * 100_i32) - 1900_i32;
|
2012-08-26 18:54:31 -05:00
|
|
|
Ok(pos)
|
2012-04-03 12:37:02 -05:00
|
|
|
}
|
2012-08-26 18:54:31 -05:00
|
|
|
None => Err(~"Invalid year")
|
2012-08-06 19:14:32 -05:00
|
|
|
},
|
2012-08-03 21:59:04 -05:00
|
|
|
'c' => {
|
2013-01-11 23:01:42 -06:00
|
|
|
parse_type(s, pos, 'a', &mut *tm)
|
2013-09-11 14:52:17 -05:00
|
|
|
.and_then(|pos| parse_char(s, pos, ' '))
|
|
|
|
.and_then(|pos| parse_type(s, pos, 'b', &mut *tm))
|
|
|
|
.and_then(|pos| parse_char(s, pos, ' '))
|
|
|
|
.and_then(|pos| parse_type(s, pos, 'e', &mut *tm))
|
|
|
|
.and_then(|pos| parse_char(s, pos, ' '))
|
|
|
|
.and_then(|pos| parse_type(s, pos, 'T', &mut *tm))
|
|
|
|
.and_then(|pos| parse_char(s, pos, ' '))
|
|
|
|
.and_then(|pos| parse_type(s, pos, 'Y', &mut *tm))
|
2012-04-03 12:37:02 -05:00
|
|
|
}
|
2012-08-03 21:59:04 -05:00
|
|
|
'D' | 'x' => {
|
2013-01-11 23:01:42 -06:00
|
|
|
parse_type(s, pos, 'm', &mut *tm)
|
2013-09-11 14:52:17 -05:00
|
|
|
.and_then(|pos| parse_char(s, pos, '/'))
|
|
|
|
.and_then(|pos| parse_type(s, pos, 'd', &mut *tm))
|
|
|
|
.and_then(|pos| parse_char(s, pos, '/'))
|
|
|
|
.and_then(|pos| parse_type(s, pos, 'y', &mut *tm))
|
2012-04-03 12:37:02 -05:00
|
|
|
}
|
2013-01-13 22:31:09 -06:00
|
|
|
'd' => match match_digits_in_range(s, pos, 2u, false, 1_i32,
|
|
|
|
31_i32) {
|
2012-08-26 18:54:31 -05:00
|
|
|
Some(item) => { let (v, pos) = item; tm.tm_mday = v; Ok(pos) }
|
|
|
|
None => Err(~"Invalid day of the month")
|
2012-08-06 19:14:32 -05:00
|
|
|
},
|
2013-01-13 22:31:09 -06:00
|
|
|
'e' => match match_digits_in_range(s, pos, 2u, true, 1_i32,
|
|
|
|
31_i32) {
|
2012-08-26 18:54:31 -05:00
|
|
|
Some(item) => { let (v, pos) = item; tm.tm_mday = v; Ok(pos) }
|
|
|
|
None => Err(~"Invalid day of the month")
|
2012-08-06 19:14:32 -05:00
|
|
|
},
|
2013-09-06 01:13:02 -05:00
|
|
|
'f' => {
|
|
|
|
let (val, pos) = match_fractional_seconds(s, pos);
|
|
|
|
tm.tm_nsec = val;
|
|
|
|
Ok(pos)
|
|
|
|
}
|
2012-08-03 21:59:04 -05:00
|
|
|
'F' => {
|
2013-01-11 23:01:42 -06:00
|
|
|
parse_type(s, pos, 'Y', &mut *tm)
|
2013-09-11 14:52:17 -05:00
|
|
|
.and_then(|pos| parse_char(s, pos, '-'))
|
|
|
|
.and_then(|pos| parse_type(s, pos, 'm', &mut *tm))
|
|
|
|
.and_then(|pos| parse_char(s, pos, '-'))
|
|
|
|
.and_then(|pos| parse_type(s, pos, 'd', &mut *tm))
|
2012-04-03 12:37:02 -05:00
|
|
|
}
|
2012-08-03 21:59:04 -05:00
|
|
|
'H' => {
|
2013-01-13 05:38:33 -06:00
|
|
|
match match_digits_in_range(s, pos, 2u, false, 0_i32, 23_i32) {
|
2012-08-26 18:54:31 -05:00
|
|
|
Some(item) => { let (v, pos) = item; tm.tm_hour = v; Ok(pos) }
|
|
|
|
None => Err(~"Invalid hour")
|
2012-04-03 12:37:02 -05:00
|
|
|
}
|
|
|
|
}
|
2012-08-03 21:59:04 -05:00
|
|
|
'I' => {
|
2013-01-13 05:38:33 -06:00
|
|
|
match match_digits_in_range(s, pos, 2u, false, 1_i32, 12_i32) {
|
2012-08-20 14:23:37 -05:00
|
|
|
Some(item) => {
|
2012-04-03 12:37:02 -05:00
|
|
|
let (v, pos) = item;
|
|
|
|
tm.tm_hour = if v == 12_i32 { 0_i32 } else { v };
|
2012-08-26 18:54:31 -05:00
|
|
|
Ok(pos)
|
2012-04-03 12:37:02 -05:00
|
|
|
}
|
2012-08-26 18:54:31 -05:00
|
|
|
None => Err(~"Invalid hour")
|
2012-04-03 12:37:02 -05:00
|
|
|
}
|
|
|
|
}
|
2012-08-03 21:59:04 -05:00
|
|
|
'j' => {
|
2013-01-13 05:38:33 -06:00
|
|
|
match match_digits_in_range(s, pos, 3u, false, 1_i32, 366_i32) {
|
2012-08-20 14:23:37 -05:00
|
|
|
Some(item) => {
|
2012-04-03 12:37:02 -05:00
|
|
|
let (v, pos) = item;
|
|
|
|
tm.tm_yday = v - 1_i32;
|
2012-08-26 18:54:31 -05:00
|
|
|
Ok(pos)
|
2012-04-03 12:37:02 -05:00
|
|
|
}
|
2013-01-13 05:05:37 -06:00
|
|
|
None => Err(~"Invalid day of year")
|
2012-04-03 12:37:02 -05:00
|
|
|
}
|
|
|
|
}
|
2012-08-03 21:59:04 -05:00
|
|
|
'k' => {
|
2013-01-13 05:38:33 -06:00
|
|
|
match match_digits_in_range(s, pos, 2u, true, 0_i32, 23_i32) {
|
2012-08-26 18:54:31 -05:00
|
|
|
Some(item) => { let (v, pos) = item; tm.tm_hour = v; Ok(pos) }
|
|
|
|
None => Err(~"Invalid hour")
|
2012-04-03 12:37:02 -05:00
|
|
|
}
|
|
|
|
}
|
2012-08-03 21:59:04 -05:00
|
|
|
'l' => {
|
2013-01-13 05:38:33 -06:00
|
|
|
match match_digits_in_range(s, pos, 2u, true, 1_i32, 12_i32) {
|
2012-08-20 14:23:37 -05:00
|
|
|
Some(item) => {
|
2012-04-03 12:37:02 -05:00
|
|
|
let (v, pos) = item;
|
|
|
|
tm.tm_hour = if v == 12_i32 { 0_i32 } else { v };
|
2012-08-26 18:54:31 -05:00
|
|
|
Ok(pos)
|
2012-04-03 12:37:02 -05:00
|
|
|
}
|
2012-08-26 18:54:31 -05:00
|
|
|
None => Err(~"Invalid hour")
|
2012-04-03 12:37:02 -05:00
|
|
|
}
|
|
|
|
}
|
2012-08-03 21:59:04 -05:00
|
|
|
'M' => {
|
2013-01-13 05:38:33 -06:00
|
|
|
match match_digits_in_range(s, pos, 2u, false, 0_i32, 59_i32) {
|
2012-08-26 18:54:31 -05:00
|
|
|
Some(item) => { let (v, pos) = item; tm.tm_min = v; Ok(pos) }
|
|
|
|
None => Err(~"Invalid minute")
|
2012-04-03 12:37:02 -05:00
|
|
|
}
|
|
|
|
}
|
2012-08-03 21:59:04 -05:00
|
|
|
'm' => {
|
2013-01-13 05:38:33 -06:00
|
|
|
match match_digits_in_range(s, pos, 2u, false, 1_i32, 12_i32) {
|
2012-08-20 14:23:37 -05:00
|
|
|
Some(item) => {
|
2012-04-03 12:37:02 -05:00
|
|
|
let (v, pos) = item;
|
|
|
|
tm.tm_mon = v - 1_i32;
|
2012-08-26 18:54:31 -05:00
|
|
|
Ok(pos)
|
2012-04-03 12:37:02 -05:00
|
|
|
}
|
2012-08-26 18:54:31 -05:00
|
|
|
None => Err(~"Invalid month")
|
2012-04-03 12:37:02 -05:00
|
|
|
}
|
|
|
|
}
|
2012-08-03 21:59:04 -05:00
|
|
|
'n' => parse_char(s, pos, '\n'),
|
2012-08-06 14:34:08 -05:00
|
|
|
'P' => match match_strs(s, pos,
|
2013-05-19 00:07:44 -05:00
|
|
|
[(~"am", 0_i32), (~"pm", 12_i32)]) {
|
2012-08-06 14:34:08 -05:00
|
|
|
|
2012-08-26 18:54:31 -05:00
|
|
|
Some(item) => { let (v, pos) = item; tm.tm_hour += v; Ok(pos) }
|
|
|
|
None => Err(~"Invalid hour")
|
2012-08-06 19:14:32 -05:00
|
|
|
},
|
2012-08-06 14:34:08 -05:00
|
|
|
'p' => match match_strs(s, pos,
|
2013-05-19 00:07:44 -05:00
|
|
|
[(~"AM", 0_i32), (~"PM", 12_i32)]) {
|
2012-08-06 14:34:08 -05:00
|
|
|
|
2012-08-26 18:54:31 -05:00
|
|
|
Some(item) => { let (v, pos) = item; tm.tm_hour += v; Ok(pos) }
|
|
|
|
None => Err(~"Invalid hour")
|
2012-08-06 19:14:32 -05:00
|
|
|
},
|
2012-08-03 21:59:04 -05:00
|
|
|
'R' => {
|
2013-01-11 23:01:42 -06:00
|
|
|
parse_type(s, pos, 'H', &mut *tm)
|
2013-09-11 14:52:17 -05:00
|
|
|
.and_then(|pos| parse_char(s, pos, ':'))
|
|
|
|
.and_then(|pos| parse_type(s, pos, 'M', &mut *tm))
|
2012-04-03 12:37:02 -05:00
|
|
|
}
|
2012-08-03 21:59:04 -05:00
|
|
|
'r' => {
|
2013-01-11 23:01:42 -06:00
|
|
|
parse_type(s, pos, 'I', &mut *tm)
|
2013-09-11 14:52:17 -05:00
|
|
|
.and_then(|pos| parse_char(s, pos, ':'))
|
|
|
|
.and_then(|pos| parse_type(s, pos, 'M', &mut *tm))
|
|
|
|
.and_then(|pos| parse_char(s, pos, ':'))
|
|
|
|
.and_then(|pos| parse_type(s, pos, 'S', &mut *tm))
|
|
|
|
.and_then(|pos| parse_char(s, pos, ' '))
|
|
|
|
.and_then(|pos| parse_type(s, pos, 'p', &mut *tm))
|
2012-04-03 12:37:02 -05:00
|
|
|
}
|
2012-08-03 21:59:04 -05:00
|
|
|
'S' => {
|
2013-01-13 05:38:33 -06:00
|
|
|
match match_digits_in_range(s, pos, 2u, false, 0_i32, 60_i32) {
|
2012-08-20 14:23:37 -05:00
|
|
|
Some(item) => {
|
2012-04-03 12:37:02 -05:00
|
|
|
let (v, pos) = item;
|
|
|
|
tm.tm_sec = v;
|
2012-08-26 18:54:31 -05:00
|
|
|
Ok(pos)
|
2012-04-03 12:37:02 -05:00
|
|
|
}
|
2012-08-26 18:54:31 -05:00
|
|
|
None => Err(~"Invalid second")
|
2012-04-03 12:37:02 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
//'s' {}
|
2012-08-03 21:59:04 -05:00
|
|
|
'T' | 'X' => {
|
2013-01-11 23:01:42 -06:00
|
|
|
parse_type(s, pos, 'H', &mut *tm)
|
2013-09-11 14:52:17 -05:00
|
|
|
.and_then(|pos| parse_char(s, pos, ':'))
|
|
|
|
.and_then(|pos| parse_type(s, pos, 'M', &mut *tm))
|
|
|
|
.and_then(|pos| parse_char(s, pos, ':'))
|
|
|
|
.and_then(|pos| parse_type(s, pos, 'S', &mut *tm))
|
2012-04-03 12:37:02 -05:00
|
|
|
}
|
2012-08-03 21:59:04 -05:00
|
|
|
't' => parse_char(s, pos, '\t'),
|
|
|
|
'u' => {
|
2013-01-13 05:38:33 -06:00
|
|
|
match match_digits_in_range(s, pos, 1u, false, 1_i32, 7_i32) {
|
2012-08-20 14:23:37 -05:00
|
|
|
Some(item) => {
|
2012-04-03 12:37:02 -05:00
|
|
|
let (v, pos) = item;
|
2013-01-22 23:41:56 -06:00
|
|
|
tm.tm_wday = if v == 7 { 0 } else { v };
|
2012-08-26 18:54:31 -05:00
|
|
|
Ok(pos)
|
2012-04-03 12:37:02 -05:00
|
|
|
}
|
2013-01-13 05:05:37 -06:00
|
|
|
None => Err(~"Invalid day of week")
|
2012-04-03 12:37:02 -05:00
|
|
|
}
|
|
|
|
}
|
2012-08-03 21:59:04 -05:00
|
|
|
'v' => {
|
2013-01-11 23:01:42 -06:00
|
|
|
parse_type(s, pos, 'e', &mut *tm)
|
2013-09-11 14:52:17 -05:00
|
|
|
.and_then(|pos| parse_char(s, pos, '-'))
|
|
|
|
.and_then(|pos| parse_type(s, pos, 'b', &mut *tm))
|
|
|
|
.and_then(|pos| parse_char(s, pos, '-'))
|
|
|
|
.and_then(|pos| parse_type(s, pos, 'Y', &mut *tm))
|
2012-04-03 12:37:02 -05:00
|
|
|
}
|
|
|
|
//'W' {}
|
2012-08-03 21:59:04 -05:00
|
|
|
'w' => {
|
2013-01-13 05:38:33 -06:00
|
|
|
match match_digits_in_range(s, pos, 1u, false, 0_i32, 6_i32) {
|
2012-08-26 18:54:31 -05:00
|
|
|
Some(item) => { let (v, pos) = item; tm.tm_wday = v; Ok(pos) }
|
2013-01-13 05:05:37 -06:00
|
|
|
None => Err(~"Invalid day of week")
|
2012-04-03 12:37:02 -05:00
|
|
|
}
|
|
|
|
}
|
2012-08-03 21:59:04 -05:00
|
|
|
'Y' => {
|
2012-08-06 14:34:08 -05:00
|
|
|
match match_digits(s, pos, 4u, false) {
|
2012-08-20 14:23:37 -05:00
|
|
|
Some(item) => {
|
2012-04-03 12:37:02 -05:00
|
|
|
let (v, pos) = item;
|
|
|
|
tm.tm_year = v - 1900_i32;
|
2012-08-26 18:54:31 -05:00
|
|
|
Ok(pos)
|
2012-04-03 12:37:02 -05:00
|
|
|
}
|
2013-01-13 05:05:37 -06:00
|
|
|
None => Err(~"Invalid year")
|
2012-04-03 12:37:02 -05:00
|
|
|
}
|
|
|
|
}
|
2012-08-03 21:59:04 -05:00
|
|
|
'y' => {
|
2013-01-13 05:38:33 -06:00
|
|
|
match match_digits_in_range(s, pos, 2u, false, 0_i32, 99_i32) {
|
2012-08-20 14:23:37 -05:00
|
|
|
Some(item) => {
|
2012-04-03 12:37:02 -05:00
|
|
|
let (v, pos) = item;
|
2013-01-13 05:18:34 -06:00
|
|
|
tm.tm_year = v;
|
2012-08-26 18:54:31 -05:00
|
|
|
Ok(pos)
|
2012-04-03 12:37:02 -05:00
|
|
|
}
|
2013-01-13 05:05:37 -06:00
|
|
|
None => Err(~"Invalid year")
|
2012-04-03 12:37:02 -05:00
|
|
|
}
|
|
|
|
}
|
2012-08-03 21:59:04 -05:00
|
|
|
'Z' => {
|
2013-05-19 00:07:44 -05:00
|
|
|
if match_str(s, pos, "UTC") || match_str(s, pos, "GMT") {
|
2012-04-03 12:37:02 -05:00
|
|
|
tm.tm_gmtoff = 0_i32;
|
2012-07-14 00:57:48 -05:00
|
|
|
tm.tm_zone = ~"UTC";
|
2012-08-26 18:54:31 -05:00
|
|
|
Ok(pos + 3u)
|
2012-04-03 12:37:02 -05:00
|
|
|
} else {
|
|
|
|
// It's odd, but to maintain compatibility with c's
|
|
|
|
// strptime we ignore the timezone.
|
|
|
|
let mut pos = pos;
|
2013-06-09 09:44:58 -05:00
|
|
|
let len = s.len();
|
2012-04-03 12:37:02 -05:00
|
|
|
while pos < len {
|
2013-06-10 06:46:36 -05:00
|
|
|
let range = s.char_range_at(pos);
|
2012-11-26 22:05:19 -06:00
|
|
|
pos = range.next;
|
|
|
|
if range.ch == ' ' { break; }
|
2012-04-03 12:37:02 -05:00
|
|
|
}
|
|
|
|
|
2012-08-26 18:54:31 -05:00
|
|
|
Ok(pos)
|
2012-04-03 12:37:02 -05:00
|
|
|
}
|
|
|
|
}
|
2012-08-03 21:59:04 -05:00
|
|
|
'z' => {
|
2013-06-10 06:46:36 -05:00
|
|
|
let range = s.char_range_at(pos);
|
2012-04-03 12:37:02 -05:00
|
|
|
|
2012-11-26 22:05:19 -06:00
|
|
|
if range.ch == '+' || range.ch == '-' {
|
|
|
|
match match_digits(s, range.next, 4u, false) {
|
2012-08-20 14:23:37 -05:00
|
|
|
Some(item) => {
|
2012-04-03 12:37:02 -05:00
|
|
|
let (v, pos) = item;
|
|
|
|
if v == 0_i32 {
|
|
|
|
tm.tm_gmtoff = 0_i32;
|
2012-07-14 00:57:48 -05:00
|
|
|
tm.tm_zone = ~"UTC";
|
2012-04-03 12:37:02 -05:00
|
|
|
}
|
|
|
|
|
2012-08-26 18:54:31 -05:00
|
|
|
Ok(pos)
|
2012-04-03 12:37:02 -05:00
|
|
|
}
|
2012-08-26 18:54:31 -05:00
|
|
|
None => Err(~"Invalid zone offset")
|
2012-04-03 12:37:02 -05:00
|
|
|
}
|
|
|
|
} else {
|
2012-08-26 18:54:31 -05:00
|
|
|
Err(~"Invalid zone offset")
|
2012-04-03 12:37:02 -05:00
|
|
|
}
|
|
|
|
}
|
2012-08-03 21:59:04 -05:00
|
|
|
'%' => parse_char(s, pos, '%'),
|
|
|
|
ch => {
|
2013-09-27 22:18:50 -05:00
|
|
|
Err(format!("unknown formatting type: {}", str::from_char(ch)))
|
2012-04-03 12:37:02 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-05-29 13:10:16 -05:00
|
|
|
do io::with_str_reader(format) |rdr| {
|
2012-11-27 00:22:22 -06:00
|
|
|
let mut tm = Tm {
|
2012-11-17 11:17:43 -06:00
|
|
|
tm_sec: 0_i32,
|
|
|
|
tm_min: 0_i32,
|
|
|
|
tm_hour: 0_i32,
|
|
|
|
tm_mday: 0_i32,
|
|
|
|
tm_mon: 0_i32,
|
|
|
|
tm_year: 0_i32,
|
|
|
|
tm_wday: 0_i32,
|
|
|
|
tm_yday: 0_i32,
|
|
|
|
tm_isdst: 0_i32,
|
|
|
|
tm_gmtoff: 0_i32,
|
|
|
|
tm_zone: ~"",
|
|
|
|
tm_nsec: 0_i32,
|
2012-04-03 12:37:02 -05:00
|
|
|
};
|
|
|
|
let mut pos = 0u;
|
2013-06-09 09:44:58 -05:00
|
|
|
let len = s.len();
|
2012-08-26 18:54:31 -05:00
|
|
|
let mut result = Err(~"Invalid time");
|
2012-04-03 12:37:02 -05:00
|
|
|
|
|
|
|
while !rdr.eof() && pos < len {
|
2013-06-10 06:46:36 -05:00
|
|
|
let range = s.char_range_at(pos);
|
2012-11-26 22:05:19 -06:00
|
|
|
let ch = range.ch;
|
|
|
|
let next = range.next;
|
2012-04-03 12:37:02 -05:00
|
|
|
|
2012-08-06 14:34:08 -05:00
|
|
|
match rdr.read_char() {
|
2012-11-27 00:22:22 -06:00
|
|
|
'%' => {
|
|
|
|
match parse_type(s, pos, rdr.read_char(), &mut tm) {
|
|
|
|
Ok(next) => pos = next,
|
2013-02-15 01:30:30 -06:00
|
|
|
Err(e) => { result = Err(e); break; }
|
2012-11-27 00:22:22 -06:00
|
|
|
}
|
|
|
|
},
|
|
|
|
c => {
|
|
|
|
if c != ch { break }
|
|
|
|
pos = next;
|
|
|
|
}
|
2012-04-03 12:37:02 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if pos == len && rdr.eof() {
|
2012-11-27 00:22:22 -06:00
|
|
|
Ok(Tm {
|
2012-04-03 12:37:02 -05:00
|
|
|
tm_sec: tm.tm_sec,
|
|
|
|
tm_min: tm.tm_min,
|
|
|
|
tm_hour: tm.tm_hour,
|
|
|
|
tm_mday: tm.tm_mday,
|
|
|
|
tm_mon: tm.tm_mon,
|
|
|
|
tm_year: tm.tm_year,
|
|
|
|
tm_wday: tm.tm_wday,
|
|
|
|
tm_yday: tm.tm_yday,
|
|
|
|
tm_isdst: tm.tm_isdst,
|
|
|
|
tm_gmtoff: tm.tm_gmtoff,
|
2013-07-02 14:47:32 -05:00
|
|
|
tm_zone: tm.tm_zone.clone(),
|
2012-04-03 12:37:02 -05:00
|
|
|
tm_nsec: tm.tm_nsec,
|
2012-11-27 00:22:22 -06:00
|
|
|
})
|
2013-02-15 01:30:30 -06:00
|
|
|
} else { result }
|
2012-04-03 12:37:02 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-10-03 15:01:42 -05:00
|
|
|
/// Formats the time according to the format string.
|
|
|
|
pub fn strftime(format: &str, tm: &Tm) -> ~str {
|
2013-10-01 22:06:26 -05:00
|
|
|
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),
|
|
|
|
_ => ~""
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-08-29 18:09:41 -05:00
|
|
|
fn parse_type(ch: char, tm: &Tm) -> ~str {
|
2013-09-27 22:18:50 -05:00
|
|
|
let die = || format!("strftime: can't understand this format {} ", ch);
|
2012-08-15 13:55:17 -05:00
|
|
|
match ch {
|
|
|
|
'A' => match tm.tm_wday as int {
|
2012-08-03 21:59:04 -05:00
|
|
|
0 => ~"Sunday",
|
|
|
|
1 => ~"Monday",
|
|
|
|
2 => ~"Tuesday",
|
|
|
|
3 => ~"Wednesday",
|
|
|
|
4 => ~"Thursday",
|
|
|
|
5 => ~"Friday",
|
2012-08-15 13:55:17 -05:00
|
|
|
6 => ~"Saturday",
|
|
|
|
_ => die()
|
2012-08-06 19:14:32 -05:00
|
|
|
},
|
2012-08-15 13:55:17 -05:00
|
|
|
'a' => match tm.tm_wday as int {
|
2012-08-03 21:59:04 -05:00
|
|
|
0 => ~"Sun",
|
|
|
|
1 => ~"Mon",
|
|
|
|
2 => ~"Tue",
|
|
|
|
3 => ~"Wed",
|
|
|
|
4 => ~"Thu",
|
|
|
|
5 => ~"Fri",
|
2012-08-15 13:55:17 -05:00
|
|
|
6 => ~"Sat",
|
|
|
|
_ => die()
|
2012-08-06 19:14:32 -05:00
|
|
|
},
|
2012-08-15 13:55:17 -05:00
|
|
|
'B' => match tm.tm_mon as int {
|
2012-08-03 21:59:04 -05:00
|
|
|
0 => ~"January",
|
|
|
|
1 => ~"February",
|
|
|
|
2 => ~"March",
|
|
|
|
3 => ~"April",
|
|
|
|
4 => ~"May",
|
|
|
|
5 => ~"June",
|
|
|
|
6 => ~"July",
|
|
|
|
7 => ~"August",
|
|
|
|
8 => ~"September",
|
|
|
|
9 => ~"October",
|
|
|
|
10 => ~"November",
|
2012-08-15 13:55:17 -05:00
|
|
|
11 => ~"December",
|
|
|
|
_ => die()
|
2012-08-06 19:14:32 -05:00
|
|
|
},
|
2012-08-15 13:55:17 -05:00
|
|
|
'b' | 'h' => match tm.tm_mon as int {
|
2012-08-03 21:59:04 -05:00
|
|
|
0 => ~"Jan",
|
|
|
|
1 => ~"Feb",
|
|
|
|
2 => ~"Mar",
|
|
|
|
3 => ~"Apr",
|
|
|
|
4 => ~"May",
|
|
|
|
5 => ~"Jun",
|
|
|
|
6 => ~"Jul",
|
|
|
|
7 => ~"Aug",
|
|
|
|
8 => ~"Sep",
|
|
|
|
9 => ~"Oct",
|
|
|
|
10 => ~"Nov",
|
|
|
|
11 => ~"Dec",
|
2012-08-15 13:55:17 -05:00
|
|
|
_ => die()
|
2012-08-06 19:14:32 -05:00
|
|
|
},
|
2013-09-27 22:18:50 -05:00
|
|
|
'C' => format!("{:02d}", (tm.tm_year as int + 1900) / 100),
|
2012-08-03 21:59:04 -05:00
|
|
|
'c' => {
|
2013-09-27 22:18:50 -05:00
|
|
|
format!("{} {} {} {} {}",
|
2012-04-03 12:38:54 -05:00
|
|
|
parse_type('a', tm),
|
|
|
|
parse_type('b', tm),
|
|
|
|
parse_type('e', tm),
|
|
|
|
parse_type('T', tm),
|
2012-08-22 19:24:52 -05:00
|
|
|
parse_type('Y', tm))
|
2012-04-03 12:38:54 -05:00
|
|
|
}
|
2012-08-03 21:59:04 -05:00
|
|
|
'D' | 'x' => {
|
2013-09-27 22:18:50 -05:00
|
|
|
format!("{}/{}/{}",
|
2012-04-03 12:38:54 -05:00
|
|
|
parse_type('m', tm),
|
|
|
|
parse_type('d', tm),
|
2012-08-22 19:24:52 -05:00
|
|
|
parse_type('y', tm))
|
2012-04-03 12:38:54 -05:00
|
|
|
}
|
2013-09-27 22:18:50 -05:00
|
|
|
'd' => format!("{:02d}", tm.tm_mday),
|
|
|
|
'e' => format!("{:2d}", tm.tm_mday),
|
|
|
|
'f' => format!("{:09d}", tm.tm_nsec),
|
2012-08-03 21:59:04 -05:00
|
|
|
'F' => {
|
2013-09-27 22:18:50 -05:00
|
|
|
format!("{}-{}-{}",
|
2012-04-03 12:38:54 -05:00
|
|
|
parse_type('Y', tm),
|
|
|
|
parse_type('m', tm),
|
2012-08-22 19:24:52 -05:00
|
|
|
parse_type('d', tm))
|
2012-04-03 12:38:54 -05:00
|
|
|
}
|
2013-10-01 22:06:26 -05:00
|
|
|
'G' => iso_week('G', tm),
|
|
|
|
'g' => iso_week('g', tm),
|
2013-09-27 22:18:50 -05:00
|
|
|
'H' => format!("{:02d}", tm.tm_hour),
|
2012-08-03 21:59:04 -05:00
|
|
|
'I' => {
|
2013-09-27 22:18:50 -05:00
|
|
|
let mut h = tm.tm_hour;
|
2012-04-03 12:38:54 -05:00
|
|
|
if h == 0 { h = 12 }
|
|
|
|
if h > 12 { h -= 12 }
|
2013-09-27 22:18:50 -05:00
|
|
|
format!("{:02d}", h)
|
2012-04-03 12:38:54 -05:00
|
|
|
}
|
2013-09-27 22:18:50 -05:00
|
|
|
'j' => format!("{:03d}", tm.tm_yday + 1),
|
|
|
|
'k' => format!("{:2d}", tm.tm_hour),
|
2012-08-03 21:59:04 -05:00
|
|
|
'l' => {
|
2013-09-27 22:18:50 -05:00
|
|
|
let mut h = tm.tm_hour;
|
2012-04-03 12:38:54 -05:00
|
|
|
if h == 0 { h = 12 }
|
|
|
|
if h > 12 { h -= 12 }
|
2013-09-27 22:18:50 -05:00
|
|
|
format!("{:2d}", h)
|
2012-04-03 12:38:54 -05:00
|
|
|
}
|
2013-09-27 22:18:50 -05:00
|
|
|
'M' => format!("{:02d}", tm.tm_min),
|
|
|
|
'm' => format!("{:02d}", tm.tm_mon + 1),
|
2012-08-03 21:59:04 -05:00
|
|
|
'n' => ~"\n",
|
2013-03-20 15:24:09 -05:00
|
|
|
'P' => if (tm.tm_hour as int) < 12 { ~"am" } else { ~"pm" },
|
|
|
|
'p' => if (tm.tm_hour as int) < 12 { ~"AM" } else { ~"PM" },
|
2012-08-03 21:59:04 -05:00
|
|
|
'R' => {
|
2013-09-27 22:18:50 -05:00
|
|
|
format!("{}:{}",
|
2012-04-03 12:38:54 -05:00
|
|
|
parse_type('H', tm),
|
2012-08-22 19:24:52 -05:00
|
|
|
parse_type('M', tm))
|
2012-04-03 12:38:54 -05:00
|
|
|
}
|
2012-08-03 21:59:04 -05:00
|
|
|
'r' => {
|
2013-09-27 22:18:50 -05:00
|
|
|
format!("{}:{}:{} {}",
|
2012-04-03 12:38:54 -05:00
|
|
|
parse_type('I', tm),
|
|
|
|
parse_type('M', tm),
|
|
|
|
parse_type('S', tm),
|
2012-08-22 19:24:52 -05:00
|
|
|
parse_type('p', tm))
|
2012-04-03 12:38:54 -05:00
|
|
|
}
|
2013-09-27 22:18:50 -05:00
|
|
|
'S' => format!("{:02d}", tm.tm_sec),
|
|
|
|
's' => format!("{}", tm.to_timespec().sec),
|
2012-08-03 21:59:04 -05:00
|
|
|
'T' | 'X' => {
|
2013-09-27 22:18:50 -05:00
|
|
|
format!("{}:{}:{}",
|
2012-04-03 12:38:54 -05:00
|
|
|
parse_type('H', tm),
|
|
|
|
parse_type('M', tm),
|
2012-08-22 19:24:52 -05:00
|
|
|
parse_type('S', tm))
|
2012-04-03 12:38:54 -05:00
|
|
|
}
|
2012-08-03 21:59:04 -05:00
|
|
|
't' => ~"\t",
|
2013-10-01 21:20:46 -05:00
|
|
|
'U' => format!("{:02d}", (tm.tm_yday - tm.tm_wday + 7) / 7),
|
2012-08-03 21:59:04 -05:00
|
|
|
'u' => {
|
2012-04-03 12:38:54 -05:00
|
|
|
let i = tm.tm_wday as int;
|
2013-08-17 21:47:54 -05:00
|
|
|
(if i == 0 { 7 } else { i }).to_str()
|
2012-04-03 12:38:54 -05:00
|
|
|
}
|
2013-10-01 22:06:26 -05:00
|
|
|
'V' => iso_week('V', tm),
|
2012-08-03 21:59:04 -05:00
|
|
|
'v' => {
|
2013-09-27 22:18:50 -05:00
|
|
|
format!("{}-{}-{}",
|
2012-04-03 12:38:54 -05:00
|
|
|
parse_type('e', tm),
|
|
|
|
parse_type('b', tm),
|
2012-08-22 19:24:52 -05:00
|
|
|
parse_type('Y', tm))
|
2012-04-03 12:38:54 -05:00
|
|
|
}
|
2013-10-02 17:01:44 -05:00
|
|
|
'W' => format!("{:02d}", (tm.tm_yday - (tm.tm_wday - 1 + 7) % 7 + 7)
|
|
|
|
/ 7),
|
2013-08-17 21:47:54 -05:00
|
|
|
'w' => (tm.tm_wday as int).to_str(),
|
|
|
|
'Y' => (tm.tm_year as int + 1900).to_str(),
|
2013-09-27 22:18:50 -05:00
|
|
|
'y' => format!("{:02d}", (tm.tm_year as int + 1900) % 100),
|
2013-07-02 14:47:32 -05:00
|
|
|
'Z' => tm.tm_zone.clone(),
|
2012-08-03 21:59:04 -05:00
|
|
|
'z' => {
|
2012-04-03 12:38:54 -05:00
|
|
|
let sign = if tm.tm_gmtoff > 0_i32 { '+' } else { '-' };
|
Replaces the free-standing functions in f32, &c.
The free-standing functions in f32, f64, i8, i16, i32, i64, u8, u16,
u32, u64, float, int, and uint are replaced with generic functions in
num instead.
If you were previously using any of those functions, just replace them
with the corresponding function with the same name in num.
Note: If you were using a function that corresponds to an operator, use
the operator instead.
2013-07-08 11:05:17 -05:00
|
|
|
let mut m = num::abs(tm.tm_gmtoff) / 60_i32;
|
2012-04-03 12:38:54 -05:00
|
|
|
let h = m / 60_i32;
|
|
|
|
m -= h * 60_i32;
|
2013-09-27 22:18:50 -05:00
|
|
|
format!("{}{:02d}{:02d}", sign, h, m)
|
2012-04-03 12:38:54 -05:00
|
|
|
}
|
2013-10-02 17:01:44 -05:00
|
|
|
'+' => tm.rfc3339(),
|
2012-08-15 13:55:17 -05:00
|
|
|
'%' => ~"%",
|
|
|
|
_ => die()
|
2012-04-03 12:38:54 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-07-14 00:57:48 -05:00
|
|
|
let mut buf = ~"";
|
2012-04-03 12:38:54 -05:00
|
|
|
|
2013-05-29 13:10:16 -05:00
|
|
|
do io::with_str_reader(format) |rdr| {
|
2012-04-03 12:38:54 -05:00
|
|
|
while !rdr.eof() {
|
2012-08-06 14:34:08 -05:00
|
|
|
match rdr.read_char() {
|
2013-06-11 21:13:42 -05:00
|
|
|
'%' => buf.push_str(parse_type(rdr.read_char(), tm)),
|
2013-06-10 02:42:24 -05:00
|
|
|
ch => buf.push_char(ch)
|
2012-04-03 12:38:54 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-02-15 01:30:30 -06:00
|
|
|
buf
|
2012-04-03 12:38:54 -05:00
|
|
|
}
|
|
|
|
|
2012-02-18 03:32:52 -06:00
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
2013-07-07 02:54:41 -05:00
|
|
|
use super::*;
|
2013-01-08 21:37:25 -06:00
|
|
|
|
2013-09-26 01:26:09 -05:00
|
|
|
use std::f64;
|
2013-06-28 17:32:26 -05:00
|
|
|
use std::os;
|
|
|
|
use std::result::{Err, Ok};
|
2012-12-27 20:24:18 -06:00
|
|
|
|
2013-04-15 10:08:52 -05:00
|
|
|
fn test_get_time() {
|
2013-06-30 22:51:13 -05:00
|
|
|
static SOME_RECENT_DATE: i64 = 1325376000i64; // 2012-01-01T00:00:00Z
|
|
|
|
static SOME_FUTURE_DATE: i64 = 1577836800i64; // 2020-01-01T00:00:00Z
|
2012-02-18 03:32:52 -06:00
|
|
|
|
|
|
|
let tv1 = get_time();
|
2013-10-21 15:08:31 -05:00
|
|
|
debug!("tv1={:?} sec + {:?} nsec", tv1.sec as uint, tv1.nsec as uint);
|
2012-02-18 03:32:52 -06:00
|
|
|
|
2013-06-30 22:51:13 -05:00
|
|
|
assert!(tv1.sec > SOME_RECENT_DATE);
|
2013-03-28 20:39:09 -05:00
|
|
|
assert!(tv1.nsec < 1000000000i32);
|
2012-02-18 03:32:52 -06:00
|
|
|
|
|
|
|
let tv2 = get_time();
|
2013-10-21 15:08:31 -05:00
|
|
|
debug!("tv2={:?} sec + {:?} nsec", tv2.sec as uint, tv2.nsec as uint);
|
2012-02-18 03:32:52 -06:00
|
|
|
|
2013-03-28 20:39:09 -05:00
|
|
|
assert!(tv2.sec >= tv1.sec);
|
2013-06-30 22:51:13 -05:00
|
|
|
assert!(tv2.sec < SOME_FUTURE_DATE);
|
2013-03-28 20:39:09 -05:00
|
|
|
assert!(tv2.nsec < 1000000000i32);
|
2012-02-18 03:32:52 -06:00
|
|
|
if tv2.sec == tv1.sec {
|
2013-03-28 20:39:09 -05:00
|
|
|
assert!(tv2.nsec >= tv1.nsec);
|
2012-02-18 03:32:52 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-04-15 10:08:52 -05:00
|
|
|
fn test_precise_time() {
|
2012-02-18 03:32:52 -06:00
|
|
|
let s0 = precise_time_s();
|
|
|
|
let ns1 = precise_time_ns();
|
|
|
|
|
2013-10-21 15:08:31 -05:00
|
|
|
debug!("s0={} sec", f64::to_str_digits(s0, 9u));
|
2013-03-28 20:39:09 -05:00
|
|
|
assert!(s0 > 0.);
|
2012-02-18 03:32:52 -06:00
|
|
|
let ns0 = (s0 * 1000000000.) as u64;
|
2013-10-21 15:08:31 -05:00
|
|
|
debug!("ns0={:?} ns", ns0);
|
2012-02-18 03:32:52 -06:00
|
|
|
|
2013-10-21 15:08:31 -05:00
|
|
|
debug!("ns1={:?} ns", ns0);
|
2013-03-28 20:39:09 -05:00
|
|
|
assert!(ns1 >= ns0);
|
2012-02-18 03:32:52 -06:00
|
|
|
|
|
|
|
let ns2 = precise_time_ns();
|
2013-10-21 15:08:31 -05:00
|
|
|
debug!("ns2={:?} ns", ns0);
|
2013-03-28 20:39:09 -05:00
|
|
|
assert!(ns2 >= ns1);
|
2012-02-18 03:32:52 -06:00
|
|
|
}
|
2012-04-03 12:32:26 -05:00
|
|
|
|
2013-04-15 10:08:52 -05:00
|
|
|
fn test_at_utc() {
|
2013-05-23 11:39:00 -05:00
|
|
|
os::setenv("TZ", "America/Los_Angeles");
|
2012-04-13 19:33:02 -05:00
|
|
|
tzset();
|
2012-04-03 12:32:26 -05:00
|
|
|
|
2013-07-07 02:54:41 -05:00
|
|
|
let time = Timespec::new(1234567890, 54321);
|
2012-04-03 12:32:26 -05:00
|
|
|
let utc = at_utc(time);
|
|
|
|
|
2013-03-28 20:39:09 -05:00
|
|
|
assert!(utc.tm_sec == 30_i32);
|
|
|
|
assert!(utc.tm_min == 31_i32);
|
|
|
|
assert!(utc.tm_hour == 23_i32);
|
|
|
|
assert!(utc.tm_mday == 13_i32);
|
|
|
|
assert!(utc.tm_mon == 1_i32);
|
|
|
|
assert!(utc.tm_year == 109_i32);
|
|
|
|
assert!(utc.tm_wday == 5_i32);
|
|
|
|
assert!(utc.tm_yday == 43_i32);
|
|
|
|
assert!(utc.tm_isdst == 0_i32);
|
|
|
|
assert!(utc.tm_gmtoff == 0_i32);
|
|
|
|
assert!(utc.tm_zone == ~"UTC");
|
|
|
|
assert!(utc.tm_nsec == 54321_i32);
|
2012-04-03 12:32:26 -05:00
|
|
|
}
|
|
|
|
|
2013-04-15 10:08:52 -05:00
|
|
|
fn test_at() {
|
2013-05-23 11:39:00 -05:00
|
|
|
os::setenv("TZ", "America/Los_Angeles");
|
2012-04-13 19:33:02 -05:00
|
|
|
tzset();
|
2012-04-03 12:32:26 -05:00
|
|
|
|
2013-07-07 02:54:41 -05:00
|
|
|
let time = Timespec::new(1234567890, 54321);
|
2012-04-03 12:32:26 -05:00
|
|
|
let local = at(time);
|
|
|
|
|
2013-10-21 15:08:31 -05:00
|
|
|
error!("time_at: {:?}", local);
|
2012-04-13 19:33:02 -05:00
|
|
|
|
2013-03-28 20:39:09 -05:00
|
|
|
assert!(local.tm_sec == 30_i32);
|
|
|
|
assert!(local.tm_min == 31_i32);
|
|
|
|
assert!(local.tm_hour == 15_i32);
|
|
|
|
assert!(local.tm_mday == 13_i32);
|
|
|
|
assert!(local.tm_mon == 1_i32);
|
|
|
|
assert!(local.tm_year == 109_i32);
|
|
|
|
assert!(local.tm_wday == 5_i32);
|
|
|
|
assert!(local.tm_yday == 43_i32);
|
|
|
|
assert!(local.tm_isdst == 0_i32);
|
|
|
|
assert!(local.tm_gmtoff == -28800_i32);
|
2012-04-03 12:32:26 -05:00
|
|
|
|
2012-06-21 18:44:10 -05:00
|
|
|
// FIXME (#2350): We should probably standardize on the timezone
|
2012-04-03 12:32:26 -05:00
|
|
|
// abbreviation.
|
2012-11-27 00:22:22 -06:00
|
|
|
let zone = &local.tm_zone;
|
2013-03-28 20:39:09 -05:00
|
|
|
assert!(*zone == ~"PST" || *zone == ~"Pacific Standard Time");
|
2012-04-03 12:32:26 -05:00
|
|
|
|
2013-03-28 20:39:09 -05:00
|
|
|
assert!(local.tm_nsec == 54321_i32);
|
2012-04-03 12:32:26 -05:00
|
|
|
}
|
|
|
|
|
2013-04-15 10:08:52 -05:00
|
|
|
fn test_to_timespec() {
|
2013-05-23 11:39:00 -05:00
|
|
|
os::setenv("TZ", "America/Los_Angeles");
|
2012-04-13 19:33:02 -05:00
|
|
|
tzset();
|
2012-04-03 12:32:26 -05:00
|
|
|
|
2013-07-07 02:54:41 -05:00
|
|
|
let time = Timespec::new(1234567890, 54321);
|
2012-04-03 12:32:26 -05:00
|
|
|
let utc = at_utc(time);
|
|
|
|
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(utc.to_timespec(), time);
|
|
|
|
assert_eq!(utc.to_local().to_timespec(), time);
|
2012-04-03 12:32:26 -05:00
|
|
|
}
|
|
|
|
|
2013-04-15 10:08:52 -05:00
|
|
|
fn test_conversions() {
|
2013-05-23 11:39:00 -05:00
|
|
|
os::setenv("TZ", "America/Los_Angeles");
|
2012-04-13 19:33:02 -05:00
|
|
|
tzset();
|
2012-04-03 12:32:26 -05:00
|
|
|
|
2013-07-07 02:54:41 -05:00
|
|
|
let time = Timespec::new(1234567890, 54321);
|
2012-04-03 12:32:26 -05:00
|
|
|
let utc = at_utc(time);
|
|
|
|
let local = at(time);
|
|
|
|
|
2013-03-28 20:39:09 -05:00
|
|
|
assert!(local.to_local() == local);
|
|
|
|
assert!(local.to_utc() == utc);
|
|
|
|
assert!(local.to_utc().to_local() == local);
|
|
|
|
assert!(utc.to_utc() == utc);
|
|
|
|
assert!(utc.to_local() == local);
|
|
|
|
assert!(utc.to_local().to_utc() == utc);
|
2012-04-03 12:32:26 -05:00
|
|
|
}
|
2012-04-03 12:38:54 -05:00
|
|
|
|
2013-04-15 10:08:52 -05:00
|
|
|
fn test_strptime() {
|
2013-05-23 11:39:00 -05:00
|
|
|
os::setenv("TZ", "America/Los_Angeles");
|
2012-04-13 19:33:02 -05:00
|
|
|
tzset();
|
2012-04-03 12:37:02 -05:00
|
|
|
|
2013-05-23 11:39:00 -05:00
|
|
|
match strptime("", "") {
|
2012-09-28 04:26:20 -05:00
|
|
|
Ok(ref tm) => {
|
2013-03-28 20:39:09 -05:00
|
|
|
assert!(tm.tm_sec == 0_i32);
|
|
|
|
assert!(tm.tm_min == 0_i32);
|
|
|
|
assert!(tm.tm_hour == 0_i32);
|
|
|
|
assert!(tm.tm_mday == 0_i32);
|
|
|
|
assert!(tm.tm_mon == 0_i32);
|
|
|
|
assert!(tm.tm_year == 0_i32);
|
|
|
|
assert!(tm.tm_wday == 0_i32);
|
2013-05-18 21:02:45 -05:00
|
|
|
assert!(tm.tm_isdst == 0_i32);
|
2013-03-28 20:39:09 -05:00
|
|
|
assert!(tm.tm_gmtoff == 0_i32);
|
|
|
|
assert!(tm.tm_zone == ~"");
|
|
|
|
assert!(tm.tm_nsec == 0_i32);
|
2012-04-03 12:37:02 -05:00
|
|
|
}
|
2012-08-26 18:54:31 -05:00
|
|
|
Err(_) => ()
|
2012-04-03 12:37:02 -05:00
|
|
|
}
|
|
|
|
|
2013-09-06 01:13:02 -05:00
|
|
|
let format = "%a %b %e %T.%f %Y";
|
2013-05-23 11:39:00 -05:00
|
|
|
assert_eq!(strptime("", format), Err(~"Invalid time"));
|
|
|
|
assert!(strptime("Fri Feb 13 15:31:30", format)
|
2013-03-06 15:58:02 -06:00
|
|
|
== Err(~"Invalid time"));
|
2012-04-03 12:37:02 -05:00
|
|
|
|
2013-09-06 01:13:02 -05:00
|
|
|
match strptime("Fri Feb 13 15:31:30.01234 2009", format) {
|
2013-10-21 15:08:31 -05:00
|
|
|
Err(e) => fail!(e),
|
2012-09-28 04:26:20 -05:00
|
|
|
Ok(ref tm) => {
|
2013-03-28 20:39:09 -05:00
|
|
|
assert!(tm.tm_sec == 30_i32);
|
|
|
|
assert!(tm.tm_min == 31_i32);
|
|
|
|
assert!(tm.tm_hour == 15_i32);
|
|
|
|
assert!(tm.tm_mday == 13_i32);
|
|
|
|
assert!(tm.tm_mon == 1_i32);
|
|
|
|
assert!(tm.tm_year == 109_i32);
|
|
|
|
assert!(tm.tm_wday == 5_i32);
|
|
|
|
assert!(tm.tm_yday == 0_i32);
|
|
|
|
assert!(tm.tm_isdst == 0_i32);
|
|
|
|
assert!(tm.tm_gmtoff == 0_i32);
|
|
|
|
assert!(tm.tm_zone == ~"");
|
2013-09-06 01:13:02 -05:00
|
|
|
assert!(tm.tm_nsec == 12340000_i32);
|
2012-04-03 12:37:02 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-08-24 14:03:11 -05:00
|
|
|
fn test(s: &str, format: &str) -> bool {
|
2012-08-06 14:34:08 -05:00
|
|
|
match strptime(s, format) {
|
2013-07-23 08:49:17 -05:00
|
|
|
Ok(ref tm) => tm.strftime(format) == s.to_owned(),
|
2013-10-21 15:08:31 -05:00
|
|
|
Err(e) => fail!(e)
|
2012-04-03 12:37:02 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-06-21 07:29:53 -05:00
|
|
|
let days = [
|
2012-07-14 00:57:48 -05:00
|
|
|
~"Sunday",
|
|
|
|
~"Monday",
|
|
|
|
~"Tuesday",
|
|
|
|
~"Wednesday",
|
|
|
|
~"Thursday",
|
|
|
|
~"Friday",
|
|
|
|
~"Saturday"
|
2013-06-21 07:29:53 -05:00
|
|
|
];
|
2013-08-03 11:45:23 -05:00
|
|
|
for day in days.iter() {
|
2013-05-23 11:39:00 -05:00
|
|
|
assert!(test(*day, "%A"));
|
2012-09-18 23:41:37 -05:00
|
|
|
}
|
2012-04-03 12:37:02 -05:00
|
|
|
|
2013-06-21 07:29:53 -05:00
|
|
|
let days = [
|
2012-07-14 00:57:48 -05:00
|
|
|
~"Sun",
|
|
|
|
~"Mon",
|
|
|
|
~"Tue",
|
|
|
|
~"Wed",
|
|
|
|
~"Thu",
|
|
|
|
~"Fri",
|
|
|
|
~"Sat"
|
2013-06-21 07:29:53 -05:00
|
|
|
];
|
2013-08-03 11:45:23 -05:00
|
|
|
for day in days.iter() {
|
2013-05-23 11:39:00 -05:00
|
|
|
assert!(test(*day, "%a"));
|
2012-09-18 23:41:37 -05:00
|
|
|
}
|
2012-04-03 12:37:02 -05:00
|
|
|
|
2013-06-21 07:29:53 -05:00
|
|
|
let months = [
|
2012-07-14 00:57:48 -05:00
|
|
|
~"January",
|
|
|
|
~"February",
|
|
|
|
~"March",
|
|
|
|
~"April",
|
|
|
|
~"May",
|
|
|
|
~"June",
|
|
|
|
~"July",
|
|
|
|
~"August",
|
|
|
|
~"September",
|
|
|
|
~"October",
|
|
|
|
~"November",
|
|
|
|
~"December"
|
2013-06-21 07:29:53 -05:00
|
|
|
];
|
2013-08-03 11:45:23 -05:00
|
|
|
for day in months.iter() {
|
2013-05-23 11:39:00 -05:00
|
|
|
assert!(test(*day, "%B"));
|
2012-09-18 23:41:37 -05:00
|
|
|
}
|
2012-04-03 12:37:02 -05:00
|
|
|
|
2013-06-21 07:29:53 -05:00
|
|
|
let months = [
|
2012-07-14 00:57:48 -05:00
|
|
|
~"Jan",
|
|
|
|
~"Feb",
|
|
|
|
~"Mar",
|
|
|
|
~"Apr",
|
|
|
|
~"May",
|
|
|
|
~"Jun",
|
|
|
|
~"Jul",
|
|
|
|
~"Aug",
|
|
|
|
~"Sep",
|
|
|
|
~"Oct",
|
|
|
|
~"Nov",
|
|
|
|
~"Dec"
|
2013-06-21 07:29:53 -05:00
|
|
|
];
|
2013-08-03 11:45:23 -05:00
|
|
|
for day in months.iter() {
|
2013-05-23 11:39:00 -05:00
|
|
|
assert!(test(*day, "%b"));
|
2012-09-18 23:41:37 -05:00
|
|
|
}
|
2012-07-14 00:57:48 -05:00
|
|
|
|
2013-05-23 11:39:00 -05:00
|
|
|
assert!(test("19", "%C"));
|
|
|
|
assert!(test("Fri Feb 13 23:31:30 2009", "%c"));
|
|
|
|
assert!(test("02/13/09", "%D"));
|
|
|
|
assert!(test("03", "%d"));
|
|
|
|
assert!(test("13", "%d"));
|
|
|
|
assert!(test(" 3", "%e"));
|
|
|
|
assert!(test("13", "%e"));
|
|
|
|
assert!(test("2009-02-13", "%F"));
|
|
|
|
assert!(test("03", "%H"));
|
|
|
|
assert!(test("13", "%H"));
|
|
|
|
assert!(test("03", "%I")); // FIXME (#2350): flesh out
|
|
|
|
assert!(test("11", "%I")); // FIXME (#2350): flesh out
|
|
|
|
assert!(test("044", "%j"));
|
|
|
|
assert!(test(" 3", "%k"));
|
|
|
|
assert!(test("13", "%k"));
|
|
|
|
assert!(test(" 1", "%l"));
|
|
|
|
assert!(test("11", "%l"));
|
|
|
|
assert!(test("03", "%M"));
|
|
|
|
assert!(test("13", "%M"));
|
|
|
|
assert!(test("\n", "%n"));
|
|
|
|
assert!(test("am", "%P"));
|
|
|
|
assert!(test("pm", "%P"));
|
|
|
|
assert!(test("AM", "%p"));
|
|
|
|
assert!(test("PM", "%p"));
|
|
|
|
assert!(test("23:31", "%R"));
|
|
|
|
assert!(test("11:31:30 AM", "%r"));
|
|
|
|
assert!(test("11:31:30 PM", "%r"));
|
|
|
|
assert!(test("03", "%S"));
|
|
|
|
assert!(test("13", "%S"));
|
|
|
|
assert!(test("15:31:30", "%T"));
|
|
|
|
assert!(test("\t", "%t"));
|
|
|
|
assert!(test("1", "%u"));
|
|
|
|
assert!(test("7", "%u"));
|
|
|
|
assert!(test("13-Feb-2009", "%v"));
|
|
|
|
assert!(test("0", "%w"));
|
|
|
|
assert!(test("6", "%w"));
|
|
|
|
assert!(test("2009", "%Y"));
|
|
|
|
assert!(test("09", "%y"));
|
2013-07-26 20:36:51 -05:00
|
|
|
assert!(strptime("UTC", "%Z").unwrap().tm_zone ==
|
2013-03-06 21:09:17 -06:00
|
|
|
~"UTC");
|
2013-07-26 20:36:51 -05:00
|
|
|
assert!(strptime("PST", "%Z").unwrap().tm_zone ==
|
2013-03-06 21:09:17 -06:00
|
|
|
~"");
|
2013-07-26 20:36:51 -05:00
|
|
|
assert!(strptime("-0000", "%z").unwrap().tm_gmtoff ==
|
2013-03-06 21:09:17 -06:00
|
|
|
0);
|
2013-07-26 20:36:51 -05:00
|
|
|
assert!(strptime("-0800", "%z").unwrap().tm_gmtoff ==
|
2013-03-06 21:09:17 -06:00
|
|
|
0);
|
2013-05-23 11:39:00 -05:00
|
|
|
assert!(test("%", "%%"));
|
2013-06-20 10:07:05 -05:00
|
|
|
|
|
|
|
// Test for #7256
|
|
|
|
assert_eq!(strptime("360", "%Y-%m-%d"), Err(~"Invalid year"))
|
2012-04-03 12:37:02 -05:00
|
|
|
}
|
|
|
|
|
2013-04-15 10:08:52 -05:00
|
|
|
fn test_ctime() {
|
2013-05-23 11:39:00 -05:00
|
|
|
os::setenv("TZ", "America/Los_Angeles");
|
2012-04-13 19:33:02 -05:00
|
|
|
tzset();
|
2012-04-03 12:38:54 -05:00
|
|
|
|
2013-07-07 02:54:41 -05:00
|
|
|
let time = Timespec::new(1234567890, 54321);
|
2012-04-03 12:38:54 -05:00
|
|
|
let utc = at_utc(time);
|
|
|
|
let local = at(time);
|
|
|
|
|
2013-10-21 15:08:31 -05:00
|
|
|
error!("test_ctime: {:?} {:?}", utc.ctime(), local.ctime());
|
2012-04-13 19:33:02 -05:00
|
|
|
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(utc.ctime(), ~"Fri Feb 13 23:31:30 2009");
|
|
|
|
assert_eq!(local.ctime(), ~"Fri Feb 13 15:31:30 2009");
|
2012-04-03 12:38:54 -05:00
|
|
|
}
|
|
|
|
|
2013-04-15 10:08:52 -05:00
|
|
|
fn test_strftime() {
|
2013-05-23 11:39:00 -05:00
|
|
|
os::setenv("TZ", "America/Los_Angeles");
|
2012-04-13 19:33:02 -05:00
|
|
|
tzset();
|
2012-04-03 12:38:54 -05:00
|
|
|
|
2013-07-07 02:54:41 -05:00
|
|
|
let time = Timespec::new(1234567890, 54321);
|
2012-04-03 12:38:54 -05:00
|
|
|
let utc = at_utc(time);
|
|
|
|
let local = at(time);
|
|
|
|
|
2013-05-23 11:39:00 -05:00
|
|
|
assert_eq!(local.strftime(""), ~"");
|
|
|
|
assert_eq!(local.strftime("%A"), ~"Friday");
|
|
|
|
assert_eq!(local.strftime("%a"), ~"Fri");
|
|
|
|
assert_eq!(local.strftime("%B"), ~"February");
|
|
|
|
assert_eq!(local.strftime("%b"), ~"Feb");
|
|
|
|
assert_eq!(local.strftime("%C"), ~"20");
|
|
|
|
assert_eq!(local.strftime("%c"), ~"Fri Feb 13 15:31:30 2009");
|
|
|
|
assert_eq!(local.strftime("%D"), ~"02/13/09");
|
|
|
|
assert_eq!(local.strftime("%d"), ~"13");
|
|
|
|
assert_eq!(local.strftime("%e"), ~"13");
|
2013-09-06 01:13:02 -05:00
|
|
|
assert_eq!(local.strftime("%f"), ~"000054321");
|
2013-05-23 11:39:00 -05:00
|
|
|
assert_eq!(local.strftime("%F"), ~"2009-02-13");
|
2013-10-01 22:06:26 -05:00
|
|
|
assert_eq!(local.strftime("%G"), ~"2009");
|
|
|
|
assert_eq!(local.strftime("%g"), ~"09");
|
2013-05-23 11:39:00 -05:00
|
|
|
assert_eq!(local.strftime("%H"), ~"15");
|
|
|
|
assert_eq!(local.strftime("%I"), ~"03");
|
|
|
|
assert_eq!(local.strftime("%j"), ~"044");
|
|
|
|
assert_eq!(local.strftime("%k"), ~"15");
|
|
|
|
assert_eq!(local.strftime("%l"), ~" 3");
|
|
|
|
assert_eq!(local.strftime("%M"), ~"31");
|
|
|
|
assert_eq!(local.strftime("%m"), ~"02");
|
|
|
|
assert_eq!(local.strftime("%n"), ~"\n");
|
|
|
|
assert_eq!(local.strftime("%P"), ~"pm");
|
|
|
|
assert_eq!(local.strftime("%p"), ~"PM");
|
|
|
|
assert_eq!(local.strftime("%R"), ~"15:31");
|
|
|
|
assert_eq!(local.strftime("%r"), ~"03:31:30 PM");
|
|
|
|
assert_eq!(local.strftime("%S"), ~"30");
|
|
|
|
assert_eq!(local.strftime("%s"), ~"1234567890");
|
|
|
|
assert_eq!(local.strftime("%T"), ~"15:31:30");
|
|
|
|
assert_eq!(local.strftime("%t"), ~"\t");
|
2013-10-01 21:20:46 -05:00
|
|
|
assert_eq!(local.strftime("%U"), ~"06");
|
2013-05-23 11:39:00 -05:00
|
|
|
assert_eq!(local.strftime("%u"), ~"5");
|
2013-10-01 22:06:26 -05:00
|
|
|
assert_eq!(local.strftime("%V"), ~"07");
|
2013-05-23 11:39:00 -05:00
|
|
|
assert_eq!(local.strftime("%v"), ~"13-Feb-2009");
|
2013-10-02 17:01:44 -05:00
|
|
|
assert_eq!(local.strftime("%W"), ~"06");
|
2013-05-23 11:39:00 -05:00
|
|
|
assert_eq!(local.strftime("%w"), ~"5");
|
2013-10-02 17:01:44 -05:00
|
|
|
assert_eq!(local.strftime("%X"), ~"15:31:30"); // FIXME (#2350): support locale
|
|
|
|
assert_eq!(local.strftime("%x"), ~"02/13/09"); // FIXME (#2350): support locale
|
2013-05-23 11:39:00 -05:00
|
|
|
assert_eq!(local.strftime("%Y"), ~"2009");
|
|
|
|
assert_eq!(local.strftime("%y"), ~"09");
|
2013-10-02 17:01:44 -05:00
|
|
|
assert_eq!(local.strftime("%+"), ~"2009-02-13T15:31:30-08:00");
|
2012-04-03 12:38:54 -05:00
|
|
|
|
2012-06-21 18:44:10 -05:00
|
|
|
// FIXME (#2350): We should probably standardize on the timezone
|
2012-04-03 12:38:54 -05:00
|
|
|
// abbreviation.
|
2013-05-23 11:39:00 -05:00
|
|
|
let zone = local.strftime("%Z");
|
2013-03-28 20:39:09 -05:00
|
|
|
assert!(zone == ~"PST" || zone == ~"Pacific Standard Time");
|
2012-04-03 12:38:54 -05:00
|
|
|
|
2013-05-23 11:39:00 -05:00
|
|
|
assert_eq!(local.strftime("%z"), ~"-0800");
|
|
|
|
assert_eq!(local.strftime("%%"), ~"%");
|
2012-04-03 12:38:54 -05:00
|
|
|
|
2012-06-21 18:44:10 -05:00
|
|
|
// FIXME (#2350): We should probably standardize on the timezone
|
2012-04-03 12:38:54 -05:00
|
|
|
// abbreviation.
|
|
|
|
let rfc822 = local.rfc822();
|
2012-07-14 00:57:48 -05:00
|
|
|
let prefix = ~"Fri, 13 Feb 2009 15:31:30 ";
|
2013-05-27 18:04:00 -05:00
|
|
|
assert!(rfc822 == prefix + "PST" ||
|
|
|
|
rfc822 == prefix + "Pacific Standard Time");
|
2012-07-14 00:57:48 -05:00
|
|
|
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(local.ctime(), ~"Fri Feb 13 15:31:30 2009");
|
|
|
|
assert_eq!(local.rfc822z(), ~"Fri, 13 Feb 2009 15:31:30 -0800");
|
|
|
|
assert_eq!(local.rfc3339(), ~"2009-02-13T15:31:30-08:00");
|
2012-07-14 00:57:48 -05:00
|
|
|
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(utc.ctime(), ~"Fri Feb 13 23:31:30 2009");
|
|
|
|
assert_eq!(utc.rfc822(), ~"Fri, 13 Feb 2009 23:31:30 GMT");
|
|
|
|
assert_eq!(utc.rfc822z(), ~"Fri, 13 Feb 2009 23:31:30 -0000");
|
|
|
|
assert_eq!(utc.rfc3339(), ~"2009-02-13T23:31:30Z");
|
2012-04-03 12:38:54 -05:00
|
|
|
}
|
2013-01-17 01:37:21 -06:00
|
|
|
|
2013-04-15 10:08:52 -05:00
|
|
|
fn test_timespec_eq_ord() {
|
2013-01-17 01:37:21 -06:00
|
|
|
let a = &Timespec::new(-2, 1);
|
|
|
|
let b = &Timespec::new(-1, 2);
|
|
|
|
let c = &Timespec::new(1, 2);
|
|
|
|
let d = &Timespec::new(2, 1);
|
|
|
|
let e = &Timespec::new(2, 1);
|
|
|
|
|
2013-06-09 02:23:05 -05:00
|
|
|
assert!(d.eq(e));
|
|
|
|
assert!(c.ne(e));
|
2013-01-17 01:37:21 -06:00
|
|
|
|
2013-06-09 02:23:05 -05:00
|
|
|
assert!(a.lt(b));
|
|
|
|
assert!(b.lt(c));
|
|
|
|
assert!(c.lt(d));
|
2013-01-17 01:37:21 -06:00
|
|
|
|
2013-06-09 02:23:05 -05:00
|
|
|
assert!(a.le(b));
|
|
|
|
assert!(b.le(c));
|
|
|
|
assert!(c.le(d));
|
|
|
|
assert!(d.le(e));
|
|
|
|
assert!(e.le(d));
|
2013-01-17 01:37:21 -06:00
|
|
|
|
2013-06-09 02:23:05 -05:00
|
|
|
assert!(b.ge(a));
|
|
|
|
assert!(c.ge(b));
|
|
|
|
assert!(d.ge(c));
|
|
|
|
assert!(e.ge(d));
|
|
|
|
assert!(d.ge(e));
|
2013-01-17 01:37:21 -06:00
|
|
|
|
2013-06-09 02:23:05 -05:00
|
|
|
assert!(b.gt(a));
|
|
|
|
assert!(c.gt(b));
|
|
|
|
assert!(d.gt(c));
|
2013-01-17 01:37:21 -06:00
|
|
|
}
|
2013-01-23 18:38:07 -06:00
|
|
|
|
|
|
|
#[test]
|
2013-04-15 10:08:52 -05:00
|
|
|
fn run_tests() {
|
2013-01-23 18:38:07 -06:00
|
|
|
// The tests race on tzset. So instead of having many independent
|
|
|
|
// tests, we will just call the functions now.
|
|
|
|
test_get_time();
|
|
|
|
test_precise_time();
|
|
|
|
test_at_utc();
|
|
|
|
test_at();
|
|
|
|
test_to_timespec();
|
|
|
|
test_conversions();
|
|
|
|
test_strptime();
|
|
|
|
test_ctime();
|
|
|
|
test_strftime();
|
|
|
|
test_timespec_eq_ord();
|
|
|
|
}
|
2012-02-18 03:32:52 -06:00
|
|
|
}
|