diff --git a/taskchampion/lib/src/atomic.rs b/taskchampion/lib/src/atomic.rs index 34e28bb36..048fc4dd6 100644 --- a/taskchampion/lib/src/atomic.rs +++ b/taskchampion/lib/src/atomic.rs @@ -1,7 +1,7 @@ //! Trait implementations for a few atomic types use crate::traits::*; -use taskchampion::chrono::prelude::*; +use taskchampion::chrono::{offset::LocalResult, prelude::*}; impl PassByValue for usize { type RustType = usize; @@ -20,11 +20,12 @@ impl PassByValue for libc::time_t { type RustType = Option>; unsafe fn from_ctype(self) -> Option> { - if self == 0 { - None - } else { - Some(Utc.timestamp(self, 0)) + if self != 0 { + if let LocalResult::Single(ts) = Utc.timestamp_opt(self, 0) { + return Some(ts); + } } + None } fn as_ctype(arg: Option>) -> libc::time_t { diff --git a/taskchampion/lib/src/task.rs b/taskchampion/lib/src/task.rs index c1fbff33d..495ca909f 100644 --- a/taskchampion/lib/src/task.rs +++ b/taskchampion/lib/src/task.rs @@ -5,7 +5,7 @@ use std::convert::TryFrom; use std::ops::Deref; use std::ptr::NonNull; use std::str::FromStr; -use taskchampion::chrono::{TimeZone, Utc}; +use taskchampion::chrono::{offset::LocalResult, TimeZone, Utc}; use taskchampion::{Annotation, Tag, Task, TaskMut, Uuid}; /// A task, as publicly exposed by this library. @@ -760,7 +760,9 @@ pub unsafe extern "C" fn tc_task_remove_annotation(task: *mut TCTask, entry: i64 wrap_mut( task, |task| { - task.remove_annotation(Utc.timestamp(entry, 0))?; + if let LocalResult::Single(ts) = Utc.timestamp_opt(entry, 0) { + task.remove_annotation(ts)?; + } Ok(TCResult::Ok) }, TCResult::Error, diff --git a/taskchampion/taskchampion/src/task/task.rs b/taskchampion/taskchampion/src/task/task.rs index ba57e95cb..ce0194fe6 100644 --- a/taskchampion/taskchampion/src/task/task.rs +++ b/taskchampion/taskchampion/src/task/task.rs @@ -4,7 +4,7 @@ use crate::depmap::DependencyMap; use crate::errors::{Error, Result}; use crate::replica::Replica; use crate::storage::TaskMap; -use chrono::prelude::*; +use chrono::{offset::LocalResult, prelude::*}; use log::trace; use std::convert::AsRef; use std::convert::TryInto; @@ -227,10 +227,15 @@ impl Task { self.taskmap.iter().filter_map(|(k, v)| { if let Some(ts) = k.strip_prefix("annotation_") { if let Ok(ts) = ts.parse::() { - return Some(Annotation { - entry: Utc.timestamp(ts, 0), - description: v.to_owned(), - }); + if let LocalResult::Single(entry) = Utc.timestamp_opt(ts, 0) { + return Some(Annotation { + entry, + description: v.to_owned(), + }); + } else { + // ignore an invalid timestamp + return None; + } } // note that invalid "annotation_*" are ignored } @@ -311,7 +316,9 @@ impl Task { fn get_timestamp(&self, property: &str) -> Option> { if let Some(ts) = self.taskmap.get(property) { if let Ok(ts) = ts.parse() { - return Some(Utc.timestamp(ts, 0)); + if let LocalResult::Single(entry) = Utc.timestamp_opt(ts, 0) { + return Some(entry); + } } // if the value does not parse as an integer, default to None }