Skip to content

Instantly share code, notes, and snippets.

@stepancheg
Last active September 4, 2018 04:34
Show Gist options
  • Save stepancheg/245d9dfa6abefbb74f522eb6c53800af to your computer and use it in GitHub Desktop.
Save stepancheg/245d9dfa6abefbb74f522eb6c53800af to your computer and use it in GitHub Desktop.
#![feature(system_time_display_iso_8601)]
#![feature(libc)]
extern crate libc;
use std::mem;
use std::time::SystemTime;
use std::slice;
use std::str;
use std::time::Duration;
extern "C" {
fn strftime(out: *mut libc::c_char, out_size: libc::size_t,
format: *const libc::c_char, timeptr: *const libc::tm) -> libc::size_t;
}
struct MyRandom {
state: u64,
}
impl MyRandom {
fn next(&mut self) -> u64 {
// from wikipedia
self.state ^= self.state >> 12; // a
self.state ^= self.state << 25; // b
self.state ^= self.state >> 27; // c
return self.state.wrapping_mul(0x2545F4914F6CDD1D);
}
fn next_bool(&mut self) -> bool {
self.next() & 1 != 0
}
}
unsafe fn test_system_time(st: &SystemTime) {
let mut result = mem::zeroed();
let t = match st.duration_since(SystemTime::UNIX_EPOCH) {
Ok(d) => d.as_secs() as i64,
Err(d) => -(d.duration().as_secs() as i64),
};
libc::gmtime_r(&t, &mut result);
let mut buf = [0; 30];
let len = strftime(buf.as_mut_ptr() as *mut libc::c_char, buf.len(), b"%Y-%m-%dT%H:%M:%SZ\0".as_ptr() as *const libc::c_char, &result);
assert!(len > 0);
let s = slice::from_raw_parts(buf.as_mut_ptr(), len);
let expected = str::from_utf8(s).unwrap();
let expected = if expected.starts_with("-") && &expected[4..5] == "-" {
// -123- -> -0123
format!("-0{}", &expected[1..])
} else {
expected.to_owned()
};
let actual = format!("{:.0}", st.display_iso_8601());
let actual = if actual.starts_with("+") {
&actual[1..]
} else {
&actual
};
assert_eq!(expected, actual, "{}", t);
}
fn random_duration(random: &mut MyRandom) -> Duration {
Duration::from_secs(random.next() % (86400 * 365 * 100000))
}
fn random_system_time(random: &mut MyRandom) -> SystemTime {
if random.next_bool() {
SystemTime::UNIX_EPOCH + random_duration(random)
} else {
SystemTime::UNIX_EPOCH - random_duration(random)
}
}
fn main() {
unsafe {
test_system_time(&SystemTime::now());
let mut random = MyRandom { state: 1 };
for i in 0u64.. {
let t = random_system_time(&mut random);
if i % 1000000 == 0 {
println!("{:.0}", t.display_iso_8601());
}
test_system_time(&t);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment