Skip to content

Commit 51d068b

Browse files
authored
Parsing NanoSecond better (#14)
1 parent 8af87ea commit 51d068b

File tree

2 files changed

+25
-16
lines changed

2 files changed

+25
-16
lines changed

src/cli.yaml

+2
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ subcommands:
4141
help: Input to be parsed, will be merged into a single string
4242
takes_value: true
4343
multiple: true
44+
required: true
45+
allow_hyphen_values: true
4446
- har:
4547
about: Har...dy up those the matches!
4648
long_about: Take a Har file, apply some filtering, then output a new Har file

src/commands/time/parse.rs

+23-16
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@ lazy_static! {
1313
static ref TIME_ZONE: Regex = Regex::new(r"(?P<zone>[\+-]\d{2}(:?\d{2})?)").unwrap();
1414
}
1515

16+
const SECONDS_MAX: u64 = 10_000_000_000;
17+
const MILLI_PER_SEC: u64 = 1_000;
18+
const NANO_PER_SEC: u64 = 1_000_000_000;
19+
const MILLI_PER_NANO: u64 = 1_000_000;
20+
1621
#[derive(Debug, PartialEq)]
1722
pub struct StringTime {
1823
dates: Vec<CalendarDate>,
@@ -27,7 +32,7 @@ impl StringTime {
2732

2833
pub fn to_utc_date_time(&self) -> DateTime<chrono::Utc> {
2934
use chrono::{Utc, Local};
30-
use chrono::naive::{NaiveDate, NaiveTime};
35+
use chrono::naive::NaiveTime;
3136

3237
let date = self.dates.get(0)
3338
.map(|x| NaiveDate::from_ymd(x.year as i32, x.month, x.day))
@@ -48,7 +53,7 @@ impl StringTime {
4853

4954
pub fn make_permutations(&self) -> Vec<DateTime<FixedOffset>> {
5055
use chrono::{Local, Date};
51-
use chrono::naive::{NaiveDate, NaiveTime};
56+
use chrono::naive::NaiveTime;
5257

5358
let time = self.time.clone()
5459
.map(|x| NaiveTime::from_hms_nano(x.hour, x.min, x.second, x.nano as u32))
@@ -81,9 +86,8 @@ pub enum TimeResult {
8186

8287
#[derive(Debug, PartialEq)]
8388
pub enum EpochTime {
84-
Seconds(u128),
85-
Milliseconds(u128),
86-
Nanoseconds(u128)
89+
Seconds(u64),
90+
Nanoseconds(u64, u64)
8791
}
8892

8993
impl EpochTime {
@@ -92,8 +96,7 @@ impl EpochTime {
9296

9397
let date = match self {
9498
EpochTime::Seconds(s) => NaiveDateTime::from_timestamp(*s as i64, 0),
95-
EpochTime::Milliseconds(s) => NaiveDateTime::from_timestamp(*s as i64 / 1000, ((*s % 1000) * 1000) as u32),
96-
EpochTime::Nanoseconds(s) => NaiveDateTime::from_timestamp(*s as i64 / 100_000, (*s % 100_000) as u32)
99+
EpochTime::Nanoseconds(sec, nano) => NaiveDateTime::from_timestamp(*sec as i64, *nano as u32)
97100
};
98101

99102
DateTime::from_utc(date, Utc)
@@ -135,7 +138,7 @@ pub fn parse(input: &str) -> Result<TimeResult, String> {
135138
use chrono::Local;
136139

137140
let mut input = s!(input);
138-
if let Ok(value) = input.parse::<u128>() {
141+
if let Ok(value) = input.parse::<u64>() {
139142
return parse_number(value);
140143
}
141144

@@ -279,13 +282,17 @@ impl StringTime {
279282
}
280283
}
281284

282-
fn parse_number(input: u128) -> Result<TimeResult, String> {
283-
return if input < 2u128.pow(31) - 1 {
285+
fn parse_number(input: u64) -> Result<TimeResult, String> {
286+
return if input < SECONDS_MAX {
284287
Ok(TimeResult::Epoch(EpochTime::Seconds(input)))
285-
} else if input < (2u128.pow(31) - 1) * 1000 {
286-
Ok(TimeResult::Epoch(EpochTime::Milliseconds(input)))
287-
} else if input < (2u128.pow(31) - 1) * 1_000_000 {
288-
Ok(TimeResult::Epoch(EpochTime::Nanoseconds(input)))
288+
} else if input < SECONDS_MAX * MILLI_PER_SEC {
289+
let seconds = input / MILLI_PER_SEC;
290+
let millis = input % MILLI_PER_SEC;
291+
Ok(TimeResult::Epoch(EpochTime::Nanoseconds(seconds, millis * MILLI_PER_NANO)))
292+
} else if input < SECONDS_MAX * NANO_PER_SEC {
293+
let seconds = input / NANO_PER_SEC;
294+
let nanos = input % NANO_PER_SEC;
295+
Ok(TimeResult::Epoch(EpochTime::Nanoseconds(seconds, nanos)))
289296
} else {
290297
Err(format!("Unknown number {}", input))
291298
}
@@ -348,8 +355,8 @@ fn parse_unwrap(input: &str) -> TimeResult {
348355
#[test]
349356
fn parse_epoch_timestamps_samples() {
350357
assert_eq!(TimeResult::Epoch(EpochTime::Seconds(1554248133)), parse_unwrap("1554248133"));
351-
assert_eq!(TimeResult::Epoch(EpochTime::Milliseconds(1554248133358)), parse_unwrap("1554248133358"));
352-
assert_eq!(TimeResult::Epoch(EpochTime::Nanoseconds(1554248133358000)), parse_unwrap("1554248133358000"));
358+
assert_eq!(TimeResult::Epoch(EpochTime::Nanoseconds(1554248133, 358000000)), parse_unwrap("1554248133358"));
359+
assert_eq!(TimeResult::Epoch(EpochTime::Nanoseconds(1555438653, 801529000)), parse_unwrap("1555438653801529000"));
353360
}
354361

355362
#[test]

0 commit comments

Comments
 (0)