@@ -7,12 +7,16 @@ use std::str::FromStr;
77
88use crate :: endpoints:: tasks:: task_query_builder:: { TaskQuery , TaskReport } ;
99use crate :: endpoints:: tasks:: { is_a_tag, is_tag_keyword} ;
10- use chrono:: { DateTime , TimeDelta } ;
10+ use chrono:: { DateTime , TimeDelta , Utc } ;
1111use rand:: distr:: { Alphanumeric , SampleString } ;
1212use serde:: { de, Deserialize , Deserializer , Serialize } ;
1313use taskchampion:: Uuid ;
1414use tera:: Context ;
1515use tracing:: warn;
16+ #[ cfg( test) ]
17+ mod tests;
18+ #[ cfg( test) ]
19+ use chrono:: TimeZone ;
1620
1721lazy_static:: lazy_static! {
1822 pub static ref TEMPLATES : tera:: Tera = {
@@ -26,6 +30,7 @@ lazy_static::lazy_static! {
2630 tera. register_function( "project_name" , get_project_name_link( ) ) ;
2731 tera. register_function( "date_proper" , get_date_proper( ) ) ;
2832 tera. register_function( "timer_value" , get_timer( ) ) ;
33+ tera. register_function( "datetime_iso" , get_datetime_iso( ) ) ;
2934 tera. register_function( "date" , get_date( ) ) ;
3035 tera. register_function( "obj" , obj( ) ) ;
3136 tera. register_function( "remove_project_tag" , remove_project_from_tag( ) ) ;
@@ -319,6 +324,17 @@ fn update_tag_bar_key_comb() -> impl tera::Filter {
319324 )
320325}
321326
327+ #[ cfg( not( test) ) ]
328+ #[ allow( dead_code) ]
329+ fn get_utc_now ( ) -> DateTime < Utc > {
330+ chrono:: prelude:: Utc :: now ( )
331+ }
332+ #[ cfg( test) ]
333+ #[ allow( dead_code) ]
334+ fn get_utc_now ( ) -> DateTime < Utc > {
335+ chrono:: Utc . with_ymd_and_hms ( 2025 , 5 , 1 , 3 , 55 , 0 ) . unwrap ( )
336+ }
337+
322338pub struct DeltaNow {
323339 pub now : DateTime < chrono:: Utc > ,
324340 pub delta : TimeDelta ,
@@ -332,7 +348,7 @@ impl DeltaNow {
332348 // Try taskchampions variant.
333349 chrono:: prelude:: NaiveDateTime :: parse_from_str ( time, "%Y-%m-%dT%H:%M:%SZ" ) . unwrap ( ) )
334350 . and_utc ( ) ;
335- let now = chrono :: prelude :: Utc :: now ( ) ;
351+ let now = get_utc_now ( ) ;
336352 let delta = now - time;
337353 Self { now, delta, time }
338354 }
@@ -376,6 +392,22 @@ fn get_date_proper() -> impl tera::Function {
376392 )
377393}
378394
395+ fn get_datetime_iso ( ) -> impl tera:: Function {
396+ Box :: new (
397+ move |args : & HashMap < String , tera:: Value > | -> tera:: Result < tera:: Value > {
398+ let date_time_str = args. get ( "datetime" ) . unwrap ( ) . as_str ( ) . unwrap ( ) ;
399+ // we are working with utc time
400+ let date_time = chrono:: prelude:: NaiveDateTime :: parse_from_str ( date_time_str, "%Y%m%dT%H%M%SZ" )
401+ . unwrap_or_else ( |_|
402+ // Try taskchampions variant.
403+ chrono:: prelude:: NaiveDateTime :: parse_from_str ( date_time_str, "%Y-%m-%dT%H:%M:%SZ" ) . unwrap ( )
404+ )
405+ . and_utc ( ) ;
406+ Ok ( tera:: to_value ( date_time. to_rfc3339 ( ) ) . unwrap ( ) )
407+ } ,
408+ )
409+ }
410+
379411fn get_date ( ) -> impl tera:: Function {
380412 Box :: new (
381413 move |args : & HashMap < String , tera:: Value > | -> tera:: Result < tera:: Value > {
@@ -437,7 +469,7 @@ fn get_timer() -> impl tera::Function {
437469
438470 let s = if delta. num_hours ( ) > 0 {
439471 format ! (
440- "{:>02}:{:>02}" ,
472+ "{:>02}:{:>02}:00 " ,
441473 delta. num_hours( ) ,
442474 delta. num_minutes( ) - ( delta. num_hours( ) * 60 )
443475 )
@@ -449,7 +481,7 @@ fn get_timer() -> impl tera::Function {
449481 num_seconds % 60
450482 )
451483 } else {
452- format ! ( "{}s " , num_seconds)
484+ format ! ( "00:00:{:>02} " , num_seconds)
453485 } ;
454486 Ok ( tera:: to_value ( s) . unwrap ( ) )
455487 } ,
0 commit comments