@@ -46,7 +46,7 @@ pub fn parse_relative_time_at_date<T: TimeZone>(
4646 let time_pattern: Regex = Regex :: new (
4747 r"(?x)
4848 (?:(?P<value>[-+]?\d*)\s*)?
49- (\s*(?P<direction>next|last)?\s*)?
49+ (\s*(?P<direction>next|this| last)?\s*)?
5050 (?P<unit>years?|months?|fortnights?|weeks?|days?|hours?|h|minutes?|mins?|m|seconds?|secs?|s|yesterday|tomorrow|now|today)
5151 (\s*(?P<separator>and|,)?\s*)?
5252 (\s*(?P<ago>ago)?)?" ,
@@ -71,10 +71,10 @@ pub fn parse_relative_time_at_date<T: TimeZone>(
7171 . map_err ( |_| ParseDateTimeError :: InvalidInput ) ?
7272 } ;
7373
74- if let Some ( direction) = capture. name ( "direction" ) {
75- if direction . as_str ( ) == "last" {
76- is_ago = true ;
77- }
74+ let direction = capture. name ( "direction" ) . map_or ( "" , |d| d . as_str ( ) ) ;
75+
76+ if direction == "last" {
77+ is_ago = true ;
7878 }
7979
8080 let unit = capture
@@ -86,23 +86,27 @@ pub fn parse_relative_time_at_date<T: TimeZone>(
8686 is_ago = true ;
8787 }
8888
89- let new_datetime = match unit {
90- "years" | "year" => add_months ( datetime, value * 12 , is_ago) ,
91- "months" | "month" => add_months ( datetime, value, is_ago) ,
92- "fortnights" | "fortnight" => add_days ( datetime, value * 14 , is_ago) ,
93- "weeks" | "week" => add_days ( datetime, value * 7 , is_ago) ,
94- "days" | "day" => add_days ( datetime, value, is_ago) ,
95- "hours" | "hour" | "h" => add_duration ( datetime, Duration :: hours ( value) , is_ago) ,
96- "minutes" | "minute" | "mins" | "min" | "m" => {
97- add_duration ( datetime, Duration :: minutes ( value) , is_ago)
98- }
99- "seconds" | "second" | "secs" | "sec" | "s" => {
100- add_duration ( datetime, Duration :: seconds ( value) , is_ago)
89+ let new_datetime = if direction == "this" {
90+ add_days ( datetime, 0 , is_ago)
91+ } else {
92+ match unit {
93+ "years" | "year" => add_months ( datetime, value * 12 , is_ago) ,
94+ "months" | "month" => add_months ( datetime, value, is_ago) ,
95+ "fortnights" | "fortnight" => add_days ( datetime, value * 14 , is_ago) ,
96+ "weeks" | "week" => add_days ( datetime, value * 7 , is_ago) ,
97+ "days" | "day" => add_days ( datetime, value, is_ago) ,
98+ "hours" | "hour" | "h" => add_duration ( datetime, Duration :: hours ( value) , is_ago) ,
99+ "minutes" | "minute" | "mins" | "min" | "m" => {
100+ add_duration ( datetime, Duration :: minutes ( value) , is_ago)
101+ }
102+ "seconds" | "second" | "secs" | "sec" | "s" => {
103+ add_duration ( datetime, Duration :: seconds ( value) , is_ago)
104+ }
105+ "yesterday" => add_days ( datetime, 1 , true ) ,
106+ "tomorrow" => add_days ( datetime, 1 , false ) ,
107+ "now" | "today" => Some ( datetime) ,
108+ _ => None ,
101109 }
102- "yesterday" => add_days ( datetime, 1 , true ) ,
103- "tomorrow" => add_days ( datetime, 1 , false ) ,
104- "now" | "today" => Some ( datetime) ,
105- _ => None ,
106110 } ;
107111 datetime = match new_datetime {
108112 Some ( dt) => dt,
@@ -191,6 +195,10 @@ mod tests {
191195 parse_relative_time_at_date( now, "1 year" ) . unwrap( ) ,
192196 now. checked_add_months( Months :: new( 12 ) ) . unwrap( )
193197 ) ;
198+ assert_eq ! (
199+ parse_relative_time_at_date( now, "this year" ) . unwrap( ) ,
200+ now. checked_add_months( Months :: new( 0 ) ) . unwrap( )
201+ ) ;
194202 assert_eq ! (
195203 parse_relative_time_at_date( now, "-2 years" ) . unwrap( ) ,
196204 now. checked_sub_months( Months :: new( 24 ) ) . unwrap( )
@@ -212,6 +220,10 @@ mod tests {
212220 parse_relative_time_at_date( now, "1 month" ) . unwrap( ) ,
213221 now. checked_add_months( Months :: new( 1 ) ) . unwrap( )
214222 ) ;
223+ assert_eq ! (
224+ parse_relative_time_at_date( now, "this month" ) . unwrap( ) ,
225+ now. checked_add_months( Months :: new( 0 ) ) . unwrap( )
226+ ) ;
215227 assert_eq ! (
216228 parse_relative_time_at_date( now, "1 month and 2 weeks" ) . unwrap( ) ,
217229 now. checked_add_months( Months :: new( 1 ) )
@@ -242,6 +254,10 @@ mod tests {
242254 parse_duration( "1 fortnight" ) . unwrap( ) ,
243255 Duration :: seconds( 1_209_600 )
244256 ) ;
257+ assert_eq ! (
258+ parse_duration( "this fortnight" ) . unwrap( ) ,
259+ Duration :: seconds( 0 )
260+ ) ;
245261 assert_eq ! (
246262 parse_duration( "3 fortnights" ) . unwrap( ) ,
247263 Duration :: seconds( 3_628_800 )
@@ -258,6 +274,7 @@ mod tests {
258274 parse_duration( "1 week" ) . unwrap( ) ,
259275 Duration :: seconds( 604_800 )
260276 ) ;
277+ assert_eq ! ( parse_duration( "this week" ) . unwrap( ) , Duration :: seconds( 0 ) ) ;
261278 assert_eq ! (
262279 parse_duration( "1 week 3 days" ) . unwrap( ) ,
263280 Duration :: seconds( 864_000 )
@@ -284,6 +301,7 @@ mod tests {
284301 parse_duration( "2 days ago" ) . unwrap( ) ,
285302 Duration :: seconds( -172_800 )
286303 ) ;
304+ assert_eq ! ( parse_duration( "this day" ) . unwrap( ) , Duration :: seconds( 0 ) ) ;
287305 assert_eq ! (
288306 parse_duration( "-2 days" ) . unwrap( ) ,
289307 Duration :: seconds( -172_800 )
@@ -298,6 +316,7 @@ mod tests {
298316 parse_duration( "1 hour ago" ) . unwrap( ) ,
299317 Duration :: seconds( -3600 )
300318 ) ;
319+ assert_eq ! ( parse_duration( "this hour" ) . unwrap( ) , Duration :: seconds( 0 ) ) ;
301320 assert_eq ! (
302321 parse_duration( "-2 hours" ) . unwrap( ) ,
303322 Duration :: seconds( -7200 )
@@ -307,13 +326,15 @@ mod tests {
307326
308327 #[ test]
309328 fn test_minutes ( ) {
329+ assert_eq ! ( parse_duration( "this minute" ) . unwrap( ) , Duration :: seconds( 0 ) ) ;
310330 assert_eq ! ( parse_duration( "1 minute" ) . unwrap( ) , Duration :: seconds( 60 ) ) ;
311331 assert_eq ! ( parse_duration( "2 minutes" ) . unwrap( ) , Duration :: seconds( 120 ) ) ;
312332 assert_eq ! ( parse_duration( "min" ) . unwrap( ) , Duration :: seconds( 60 ) ) ;
313333 }
314334
315335 #[ test]
316336 fn test_seconds ( ) {
337+ assert_eq ! ( parse_duration( "this second" ) . unwrap( ) , Duration :: seconds( 0 ) ) ;
317338 assert_eq ! ( parse_duration( "1 second" ) . unwrap( ) , Duration :: seconds( 1 ) ) ;
318339 assert_eq ! ( parse_duration( "2 seconds" ) . unwrap( ) , Duration :: seconds( 2 ) ) ;
319340 assert_eq ! ( parse_duration( "sec" ) . unwrap( ) , Duration :: seconds( 1 ) ) ;
@@ -347,6 +368,7 @@ mod tests {
347368 parse_duration( "2weeks 1hour ago" ) . unwrap( ) ,
348369 Duration :: seconds( -1_213_200 )
349370 ) ;
371+ assert_eq ! ( parse_duration( "thismonth" ) . unwrap( ) , Duration :: days( 0 ) ) ;
350372 assert_eq ! (
351373 parse_relative_time_at_date( now, "+4months" ) . unwrap( ) ,
352374 now. checked_add_months( Months :: new( 4 ) ) . unwrap( )
@@ -418,6 +440,10 @@ mod tests {
418440 parse_relative_time_at_date( now, "last month" ) . unwrap( ) ,
419441 now. checked_sub_months( Months :: new( 1 ) ) . unwrap( )
420442 ) ;
443+
444+ assert_eq ! ( parse_duration( "this month" ) . unwrap( ) , Duration :: days( 0 ) ) ;
445+
446+ assert_eq ! ( parse_duration( "this year" ) . unwrap( ) , Duration :: days( 0 ) ) ;
421447 }
422448
423449 #[ test]
0 commit comments