Skip to content

Commit

Permalink
output six decimal digits for timestamp microseconds (#47)
Browse files Browse the repository at this point in the history
output six decimal digits for timestamp nanonseconds
  • Loading branch information
albertodonato committed Aug 15, 2023
1 parent e133861 commit fd0c948
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 54 deletions.
2 changes: 1 addition & 1 deletion fuzz/fuzz_targets/parse_float.rs
Expand Up @@ -6,7 +6,7 @@ fn check_float_matches(data: &str) {
match float_parse_str(data) {
IntFloat::Int(i) => assert_eq!(data.parse::<i64>().unwrap(), i),
IntFloat::Float(f) => assert_eq!(data.parse::<f64>().unwrap(), f),
IntFloat::Err => assert!(data.parse::<f64>().is_err())
IntFloat::Err => assert!(data.parse::<f64>().is_err()),
}
}

Expand Down
2 changes: 1 addition & 1 deletion fuzz/fuzz_targets/parse_int.rs
Expand Up @@ -5,7 +5,7 @@ use speedate::int_parse_str;
fn check_int_matches(data: &str) {
match int_parse_str(data) {
Some(i) => assert_eq!(data.parse::<i64>().unwrap(), i),
None => assert!(data.parse::<i64>().is_err())
None => assert!(data.parse::<i64>().is_err()),
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/datetime.rs
Expand Up @@ -371,7 +371,7 @@ impl DateTime {
/// assert_eq!(d.to_string(), "2022-06-07T16:28:40.000123");
///
/// let d = DateTime::from_timestamp_with_config(1_654_619_320_123, 123_000, &TimeConfigBuilder::new().build()).unwrap();
/// assert_eq!(d.to_string(), "2022-06-07T16:28:40.246");
/// assert_eq!(d.to_string(), "2022-06-07T16:28:40.246000");
/// ```
pub fn from_timestamp_with_config(
timestamp: i64,
Expand Down Expand Up @@ -429,7 +429,7 @@ impl DateTime {
/// assert_eq!(d.to_string(), "2022-06-07T16:28:40.000123");
///
/// let d = DateTime::from_timestamp(1_654_619_320_123, 123_000).unwrap();
/// assert_eq!(d.to_string(), "2022-06-07T16:28:40.246");
/// assert_eq!(d.to_string(), "2022-06-07T16:28:40.246000");
/// ```
pub fn from_timestamp(timestamp: i64, timestamp_microsecond: u32) -> Result<Self, ParseError> {
Self::from_timestamp_with_config(timestamp, timestamp_microsecond, &TimeConfigBuilder::new().build())
Expand Down
2 changes: 1 addition & 1 deletion src/time.rs
Expand Up @@ -45,7 +45,7 @@ impl fmt::Display for Time {
crate::display_num_buf(2, 3, self.minute as u32, &mut buf);
crate::display_num_buf(2, 6, self.second as u32, &mut buf);
crate::display_num_buf(6, 9, self.microsecond, &mut buf);
f.write_str(std::str::from_utf8(&buf[..]).unwrap().trim_end_matches('0'))?
f.write_str(std::str::from_utf8(&buf[..]).unwrap())?
} else {
let mut buf: [u8; 8] = *b"00:00:00";
crate::display_num_buf(2, 0, self.hour as u32, &mut buf);
Expand Down
32 changes: 16 additions & 16 deletions tests/main.rs
Expand Up @@ -424,13 +424,13 @@ fn datetime_watershed() {
let dt = DateTime::from_timestamp(20_000_000_000, 0).unwrap();
assert_eq!(dt.to_string(), "2603-10-11T11:33:20");
let dt = DateTime::from_timestamp(20_000_000_001, 0).unwrap();
assert_eq!(dt.to_string(), "1970-08-20T11:33:20.001");
assert_eq!(dt.to_string(), "1970-08-20T11:33:20.001000");
match DateTime::from_timestamp(-20_000_000_000, 0) {
Ok(dt) => panic!("unexpectedly valid, {dt}"),
Err(e) => assert_eq!(e, ParseError::DateTooSmall),
}
let dt = DateTime::from_timestamp(-20_000_000_001, 0).unwrap();
assert_eq!(dt.to_string(), "1969-05-14T12:26:39.999");
assert_eq!(dt.to_string(), "1969-05-14T12:26:39.999000");
}

#[test]
Expand All @@ -456,10 +456,10 @@ fn datetime_with_tz_offset() {
let dt_z = DateTime::parse_str("2022-01-01T12:13:14.567+00:00").unwrap();

let dt_m8 = dt_z.with_timezone_offset(Some(-8 * 3600)).unwrap();
assert_eq!(dt_m8.to_string(), "2022-01-01T12:13:14.567-08:00");
assert_eq!(dt_m8.to_string(), "2022-01-01T12:13:14.567000-08:00");

let dt_naive = dt_z.with_timezone_offset(None).unwrap();
assert_eq!(dt_naive.to_string(), "2022-01-01T12:13:14.567");
assert_eq!(dt_naive.to_string(), "2022-01-01T12:13:14.567000");

let dt_naive = DateTime::parse_str("2000-01-01T00:00:00").unwrap();

Expand All @@ -475,13 +475,13 @@ fn datetime_with_tz_offset() {

#[test]
fn datetime_in_timezone() {
let dt_z = DateTime::parse_str("2000-01-01T15:00:00.567Z").unwrap();
let dt_z = DateTime::parse_str("2000-01-01T15:00:00.567000Z").unwrap();

let dt_p1 = dt_z.in_timezone(3_600).unwrap();
assert_eq!(dt_p1.to_string(), "2000-01-01T16:00:00.567+01:00");
assert_eq!(dt_p1.to_string(), "2000-01-01T16:00:00.567000+01:00");

let dt_m2 = dt_z.in_timezone(-7_200).unwrap();
assert_eq!(dt_m2.to_string(), "2000-01-01T13:00:00.567-02:00");
assert_eq!(dt_m2.to_string(), "2000-01-01T13:00:00.567000-02:00");

let dt_naive = DateTime::parse_str("2000-01-01T00:00:00").unwrap();
let error = match dt_naive.in_timezone(3_600) {
Expand Down Expand Up @@ -573,10 +573,10 @@ fn time_with_tz_offset() {
let t_z = Time::parse_str("12:13:14.567+00:00").unwrap();

let t_m8 = t_z.with_timezone_offset(Some(-8 * 3600)).unwrap();
assert_eq!(t_m8.to_string(), "12:13:14.567-08:00");
assert_eq!(t_m8.to_string(), "12:13:14.567000-08:00");

let t_naive = t_z.with_timezone_offset(None).unwrap();
assert_eq!(t_naive.to_string(), "12:13:14.567");
assert_eq!(t_naive.to_string(), "12:13:14.567000");

let t_naive = Time::parse_str("00:00:00").unwrap();

Expand All @@ -595,10 +595,10 @@ fn time_in_timezone() {
let t_z = Time::parse_str("15:00:00.567Z").unwrap();

let t_p1 = t_z.in_timezone(3_600).unwrap();
assert_eq!(t_p1.to_string(), "16:00:00.567+01:00");
assert_eq!(t_p1.to_string(), "16:00:00.567000+01:00");

let t_m2 = t_z.in_timezone(-7_200).unwrap();
assert_eq!(t_m2.to_string(), "13:00:00.567-02:00");
assert_eq!(t_m2.to_string(), "13:00:00.567000-02:00");

let t_naive = Time::parse_str("10:00:00").unwrap();
let error = match t_naive.in_timezone(3_600) {
Expand All @@ -619,7 +619,7 @@ param_tests! {
time_min: ok => "00:00:00.000000", "00:00:00";
time_max: ok => "23:59:59.999999", "23:59:59.999999";
time_no_fraction: ok => "12:13:14", "12:13:14";
time_fraction_small: ok => "12:13:14.123", "12:13:14.123";
time_fraction_small: ok => "12:13:14.123", "12:13:14.123000";
time_no_sec: ok => "12:13", "12:13:00";
time_tz: ok => "12:13:14z", "12:13:14Z";
time: err => "xxx", TooShort;
Expand Down Expand Up @@ -813,12 +813,12 @@ param_tests! {
dt_tz_negative: ok => "2020-01-01T12:13:14-02:15", "2020-01-01T12:13:14-02:15";
dt_tz_negative_10: ok => "2020-01-01T12:13:14-11:30", "2020-01-01T12:13:14-11:30";
dt_tz_no_colon: ok => "2020-01-01T12:13:14+1234", "2020-01-01T12:13:14+12:34";
dt_seconds_fraction_break: ok => "2020-01-01 12:13:14.123z", "2020-01-01T12:13:14.123Z";
dt_seconds_fraction_comma: ok => "2020-01-01 12:13:14,123z", "2020-01-01T12:13:14.123Z";
dt_underscore: ok => "2020-01-01_12:13:14,123z", "2020-01-01T12:13:14.123Z";
dt_seconds_fraction_break: ok => "2020-01-01 12:13:14.123z", "2020-01-01T12:13:14.123000Z";
dt_seconds_fraction_comma: ok => "2020-01-01 12:13:14,123z", "2020-01-01T12:13:14.123000Z";
dt_underscore: ok => "2020-01-01_12:13:14,123z", "2020-01-01T12:13:14.123000Z";
dt_unix1: ok => "1654646400", "2022-06-08T00:00:00";
dt_unix2: ok => "1654646404", "2022-06-08T00:00:04";
dt_unix_float: ok => "1654646404.5", "2022-06-08T00:00:04.5";
dt_unix_float: ok => "1654646404.5", "2022-06-08T00:00:04.500000";
dt_short_date: err => "xxx", TooShort;
dt_short_time: err => "2020-01-01T12:0", TooShort;
dt: err => "202x-01-01", InvalidCharYear;
Expand Down
66 changes: 33 additions & 33 deletions tests/values_ok.txt
Expand Up @@ -2,56 +2,56 @@
date: 2022-05-30 -> 2022-05-30
# times with timezones are removed since they're not supported by this library
time: 20:26:52 -> 20:26:52
time: 20:26:52.3 -> 20:26:52.3
time: 20:26:52.36 -> 20:26:52.36
time: 20:26:52.361 -> 20:26:52.361
time: 20:26:52.361000 -> 20:26:52.361
time: 20:26:52.3 -> 20:26:52.300000
time: 20:26:52.36 -> 20:26:52.360000
time: 20:26:52.361 -> 20:26:52.361000
time: 20:26:52.361000 -> 20:26:52.361000
dt: 2022-05-30T20:26:52Z -> 2022-05-30T20:26:52Z
dt: 2022-05-30T20:26:52.3Z -> 2022-05-30T20:26:52.3Z
dt: 2022-05-30T20:26:52.36Z -> 2022-05-30T20:26:52.36Z
dt: 2022-05-30T20:26:52.361Z -> 2022-05-30T20:26:52.361Z
dt: 2022-05-30T20:26:52.361000Z -> 2022-05-30T20:26:52.361Z
dt: 2022-05-30T20:26:52.3Z -> 2022-05-30T20:26:52.300000Z
dt: 2022-05-30T20:26:52.36Z -> 2022-05-30T20:26:52.360000Z
dt: 2022-05-30T20:26:52.361Z -> 2022-05-30T20:26:52.361000Z
dt: 2022-05-30T20:26:52.361000Z -> 2022-05-30T20:26:52.361000Z
dt: 2022-05-30T21:26:52+01:00 -> 2022-05-30T21:26:52+01:00
dt: 2022-05-30T21:26:52.361+01:00 -> 2022-05-30T21:26:52.361+01:00
dt: 2022-05-30T21:26:52.361000+01:00 -> 2022-05-30T21:26:52.361+01:00
dt: 2022-05-30T21:26:52.361+01:00 -> 2022-05-30T21:26:52.361000+01:00
dt: 2022-05-30T21:26:52.361000+01:00 -> 2022-05-30T21:26:52.361000+01:00
dt: 2022-05-30 21:26:52+01:00 -> 2022-05-30T21:26:52+01:00
dt: 2022-05-30 21:26:52.3+01:00 -> 2022-05-30T21:26:52.3+01:00
dt: 2022-05-30 21:26:52.36+01:00 -> 2022-05-30T21:26:52.36+01:00
dt: 2022-05-30 21:26:52.361+01:00 -> 2022-05-30T21:26:52.361+01:00
dt: 2022-05-30 21:26:52.361000+01:00 -> 2022-05-30T21:26:52.361+01:00
dt: 2022-05-30 21:26:52.3+01:00 -> 2022-05-30T21:26:52.300000+01:00
dt: 2022-05-30 21:26:52.36+01:00 -> 2022-05-30T21:26:52.360000+01:00
dt: 2022-05-30 21:26:52.361+01:00 -> 2022-05-30T21:26:52.361000+01:00
dt: 2022-05-30 21:26:52.361000+01:00 -> 2022-05-30T21:26:52.361000+01:00
dt: 2022-05-30 20:26:52Z -> 2022-05-30T20:26:52Z
dt: 2022-05-30_20:26:52Z -> 2022-05-30T20:26:52Z
dt: 2022-05-30 20:26:52z -> 2022-05-30T20:26:52Z
dt: 2022-05-30_20:26:52z -> 2022-05-30T20:26:52Z
dt: 2022-05-30 20:26:52.3Z -> 2022-05-30T20:26:52.3Z
dt: 2022-05-30 20:26:52.36Z -> 2022-05-30T20:26:52.36Z
dt: 2022-05-30 20:26:52.361Z -> 2022-05-30T20:26:52.361Z
dt: 2022-05-30_20:26:52.361Z -> 2022-05-30T20:26:52.361Z
dt: 2022-05-30 20:26:52.361000Z -> 2022-05-30T20:26:52.361Z
dt: 2022-05-30_20:26:52.361000Z -> 2022-05-30T20:26:52.361Z
dt: 2022-05-30 20:26:52.361z -> 2022-05-30T20:26:52.361Z
dt: 2022-05-30_20:26:52.361z -> 2022-05-30T20:26:52.361Z
dt: 2022-05-30 20:26:52.361000z -> 2022-05-30T20:26:52.361Z
dt: 2022-05-30_20:26:52.361000z -> 2022-05-30T20:26:52.361Z
dt: 2022-05-30 20:26:52.3Z -> 2022-05-30T20:26:52.300000Z
dt: 2022-05-30 20:26:52.36Z -> 2022-05-30T20:26:52.360000Z
dt: 2022-05-30 20:26:52.361Z -> 2022-05-30T20:26:52.361000Z
dt: 2022-05-30_20:26:52.361Z -> 2022-05-30T20:26:52.361000Z
dt: 2022-05-30 20:26:52.361000Z -> 2022-05-30T20:26:52.361000Z
dt: 2022-05-30_20:26:52.361000Z -> 2022-05-30T20:26:52.361000Z
dt: 2022-05-30 20:26:52.361z -> 2022-05-30T20:26:52.361000Z
dt: 2022-05-30_20:26:52.361z -> 2022-05-30T20:26:52.361000Z
dt: 2022-05-30 20:26:52.361000z -> 2022-05-30T20:26:52.361000Z
dt: 2022-05-30_20:26:52.361000z -> 2022-05-30T20:26:52.361000Z
dt: 2022-05-30 20:26:52-00:00 -> 2022-05-30T20:26:52Z
dt: 2022-05-30 20:26:52.361-00:00 -> 2022-05-30T20:26:52.361Z
dt: 2022-05-30 20:26:52.361-00:00 -> 2022-05-30T20:26:52.361000Z
dt: 2022-05-30T20:26:52-00:00 -> 2022-05-30T20:26:52Z
dt: 2022-05-30T20:26:52.361-00:00 -> 2022-05-30T20:26:52.361Z
dt: 2022-05-30T20:26:52.361-00:00 -> 2022-05-30T20:26:52.361000Z
dt: 2022-05-31T05:11:52+08:45 -> 2022-05-31T05:11:52+08:45
dt: 2022-05-30T20:26:52+00:00 -> 2022-05-30T20:26:52Z
dt: 2022-05-30T20:26:52.361+00:00 -> 2022-05-30T20:26:52.361Z
dt: 2022-05-30T20:26:52.361+00:00 -> 2022-05-30T20:26:52.361000Z

# from https://github.com/python/cpython/blob/5849af7a80166e9e82040e082f22772bd7cf3061/Lib/test/datetimetester.py#L3104-L3226
# with invalid cases moved to values_err.txt
dt: 2025-01-02T03:04 -> 2025-01-02T03:04:00
dt: 2025-01-02T03:04:05 -> 2025-01-02T03:04:05
dt: 2025-01-02T03:04:05.6 -> 2025-01-02T03:04:05.6
dt: 2025-01-02T03:04:05,6 -> 2025-01-02T03:04:05.6
dt: 2025-01-02T03:04:05.678 -> 2025-01-02T03:04:05.678
dt: 2025-01-02T03:04:05.6 -> 2025-01-02T03:04:05.600000
dt: 2025-01-02T03:04:05,6 -> 2025-01-02T03:04:05.600000
dt: 2025-01-02T03:04:05.678 -> 2025-01-02T03:04:05.678000
dt: 2025-01-02T03:04:05.678901 -> 2025-01-02T03:04:05.678901
dt: 2025-01-02T03:04:05,678901 -> 2025-01-02T03:04:05.678901
dt: 2009-04-19T03:15:45.2345 -> 2009-04-19T03:15:45.2345
dt: 2025-01-02T03:04:05,678 -> 2025-01-02T03:04:05.678
dt: 2009-04-19T03:15:45.2345 -> 2009-04-19T03:15:45.234500
dt: 2025-01-02T03:04:05,678 -> 2025-01-02T03:04:05.678000
dt: 2025-01-02T03:04:05Z -> 2025-01-02T03:04:05Z
dt: 2025-01-02T03:05:06+0300 -> 2025-01-02T03:05:06+03:00
dt: 2025-01-02T03:05:06-0300 -> 2025-01-02T03:05:06-03:00
Expand All @@ -62,4 +62,4 @@ dt: 2020-06-01T04:05:06.111111-04:00 -> 2020-06-01T04:05:06.111111-04:00
dt: 2020-06-01T04:05:06.111111-0400 -> 2020-06-01T04:05:06.111111-04:00
dt: 2021-10-31T01:30:00.000000+01:00 -> 2021-10-31T01:30:00+01:00
dt: 2021-10-31T01:30:00.000000+0100 -> 2021-10-31T01:30:00+01:00
dt: 2025-01-02T03:04:05,678+00:00 -> 2025-01-02T03:04:05.678Z
dt: 2025-01-02T03:04:05,678+00:00 -> 2025-01-02T03:04:05.678000Z

0 comments on commit fd0c948

Please sign in to comment.