summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordfhoughton <dfhoughton@gmail.com>2019-02-02 17:53:10 -0500
committerdfhoughton <dfhoughton@gmail.com>2019-02-02 17:53:10 -0500
commitc84e86ecb1f28134ecb0f9ea4b69c43c98ee1ba2 (patch)
tree21467ba99cac52c6d6849b6805e79c84cdb661b9
parent42bd15810e323a96fdd684da26bd890de68d5b9c (diff)
downloadtwo-timer-c84e86ecb1f28134ecb0f9ea4b69c43c98ee1ba2.zip
handle noon and midnight
-rw-r--r--README.md2
-rw-r--r--src/lib.rs30
-rw-r--r--tests/tests.rs32
3 files changed, 56 insertions, 8 deletions
diff --git a/README.md b/README.md
index c90a1ef..f509d0c 100644
--- a/README.md
+++ b/README.md
@@ -30,5 +30,7 @@ Some expressions it can handle:
* two seconds before 12:00 PM
* 1 week after May first
* 15 minutes around 12:13:43 PM
+* noon on May 6, 1969
+* midnight on May 6, 1969
The complete API is available at https://docs.rs/two_timer/0.1.0/two_timer/.
diff --git a/src/lib.rs b/src/lib.rs
index b5be34e..474dda3 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -249,7 +249,8 @@ lazy_static! {
o_n_day => <n_day> | <o_day>
at_time -> ("at") <time>
at_time_on -> ("at")? <time> ("on")?
- time -> <hour_12> <am_pm>? | <hour_24>
+ time -> <hour_12> <am_pm>? | <hour_24> | <canonical_time>
+ canonical_time => [["noon", "midnight"]]
hour_24 => <h24>
hour_24 => <h24> (":") <minute>
hour_24 => <h24> (":") <minute> (":") <second>
@@ -976,7 +977,7 @@ fn handle_one_time(
// add time to a date
fn moment_and_time(config: &Config, daytime: Option<&Match>) -> (NaiveDateTime, NaiveDateTime) {
if let Some(daytime) = daytime {
- let (hour, minute, second) = time(daytime);
+ let (hour, minute, second, is_midnight) = time(daytime);
let period = if second.is_some() {
Period::Second
} else if minute.is_some() {
@@ -984,7 +985,7 @@ fn moment_and_time(config: &Config, daytime: Option<&Match>) -> (NaiveDateTime,
} else {
Period::Hour
};
- let m = config
+ let mut m = config
.now
.with_hour(hour)
.unwrap()
@@ -992,6 +993,9 @@ fn moment_and_time(config: &Config, daytime: Option<&Match>) -> (NaiveDateTime,
.unwrap()
.with_second(second.unwrap_or(0))
.unwrap();
+ if is_midnight {
+ m = m + Duration::days(1); // midnight is second 0 *of the next day*
+ }
moment_to_period(m, &period, config)
} else {
moment_to_period(config.now, &config.period, config)
@@ -1030,7 +1034,7 @@ fn relative_moment(
));
}
if let Some(t) = m.name("time") {
- let (hour, minute, second) = time(t);
+ let (hour, minute, second, is_midnight) = time(t);
let period = if second.is_some() {
Period::Second
} else if minute.is_some() {
@@ -1045,6 +1049,9 @@ fn relative_moment(
.unwrap()
.with_second(second.unwrap_or(0))
.unwrap();
+ if is_midnight {
+ t = t + Duration::days(1); // midnight is second 0 *of the next day*
+ }
if before && t > *other_time {
t = t - Duration::days(1);
} else if !before && t < *other_time {
@@ -1177,7 +1184,14 @@ fn a_month(m: &Match) -> u32 {
}
// extract hour, minute, and second from time match
-fn time(m: &Match) -> (u32, Option<u32>, Option<u32>) {
+// last parameter is basically whether the value returned is for "midnight", which requires special handling
+fn time(m: &Match) -> (u32, Option<u32>, Option<u32>, bool) {
+ if let Some(m) = m.name("canonical_time") {
+ return match m.as_str().chars().nth(0).unwrap() {
+ 'n' | 'N' => (12, None, None, false),
+ _ => (0, None, None, true),
+ };
+ }
let hour = if let Some(hour_24) = m.name("hour_24") {
s_to_n(hour_24.name("h24").unwrap().as_str())
} else if let Some(hour_12) = m.name("hour_12") {
@@ -1202,12 +1216,12 @@ fn time(m: &Match) -> (u32, Option<u32>, Option<u32>) {
let minute = s_to_n(minute.as_str());
if let Some(second) = m.name("second") {
let second = s_to_n(second.as_str());
- (hour, Some(minute), Some(second))
+ (hour, Some(minute), Some(second), false)
} else {
- (hour, Some(minute), None)
+ (hour, Some(minute), None, false)
}
} else {
- (hour, None, None)
+ (hour, None, None, false)
}
}
diff --git a/tests/tests.rs b/tests/tests.rs
index 4cfe14b..51d466c 100644
--- a/tests/tests.rs
+++ b/tests/tests.rs
@@ -1300,3 +1300,35 @@ fn number_before_test() {
}
}
}
+
+#[test]
+fn noon() {
+ let d1 = NaiveDate::from_ymd(1969, 5, 6).and_hms(12, 0, 0);
+ let d2 = d1 + Duration::hours(1);
+ match parse("noon on May 6, 1969", None) {
+ Ok((start, end, _)) => {
+ assert_eq!(d1, start);
+ assert_eq!(d2, end);
+ }
+ Err(e) => {
+ println!("{:?}", e);
+ assert!(false, "didn't match");
+ }
+ }
+}
+
+#[test]
+fn midnight() {
+ let d1 = NaiveDate::from_ymd(1969, 5, 7).and_hms(0, 0, 0);
+ let d2 = d1 + Duration::hours(1);
+ match parse("midnight on May 6, 1969", None) {
+ Ok((start, end, _)) => {
+ assert_eq!(d1, start);
+ assert_eq!(d2, end);
+ }
+ Err(e) => {
+ println!("{:?}", e);
+ assert!(false, "didn't match");
+ }
+ }
+} \ No newline at end of file