Merge pull request #190 from yuankunzhang/fix-base-datetime-handling

fix base datetime handling in the builder
This commit is contained in:
Daniel Hofstetter
2025-07-24 10:21:28 +02:00
committed by GitHub
2 changed files with 29 additions and 19 deletions
+23 -19
View File
@@ -105,16 +105,28 @@ impl DateTimeBuilder {
pub(super) fn build(self) -> Option<DateTime<FixedOffset>> {
let base = self.base.unwrap_or_else(|| chrono::Local::now().into());
let mut dt = new_date(
base.year(),
base.month(),
base.day(),
0,
0,
0,
0,
*base.offset(),
)?;
// If any of the following items are set, we truncate the time portion
// of the base date to zero; otherwise, we use the base date as is.
let mut dt = if self.timestamp.is_none()
&& self.date.is_none()
&& self.time.is_none()
&& self.weekday.is_none()
&& self.timezone.is_none()
{
base
} else {
new_date(
base.year(),
base.month(),
base.day(),
0,
0,
0,
0,
*base.offset(),
)?
};
if let Some(ts) = self.timestamp {
// TODO: How to make the fract -> nanosecond conversion more precise?
@@ -221,14 +233,6 @@ impl DateTimeBuilder {
}
for rel in self.relative {
if self.timestamp.is_none()
&& self.date.is_none()
&& self.time.is_none()
&& self.weekday.is_none()
{
dt = base;
}
match rel {
relative::Relative::Years(x) => {
dt = dt.with_year(dt.year() + x)?;
@@ -254,7 +258,7 @@ impl DateTimeBuilder {
relative::Relative::Minutes(x) => {
dt += chrono::Duration::try_minutes(x.into())?;
}
// Seconds are special because they can be given as a float
// Seconds are special because they can be given as a float.
relative::Relative::Seconds(x) => {
dt += chrono::Duration::try_seconds(x as i64)?;
}
+6
View File
@@ -446,6 +446,12 @@ mod tests {
assert_eq!(result.minute(), now.minute());
assert_eq!(result.second(), now.second());
let result = at_date(parse(&mut "2 days 3 days ago").unwrap(), now).unwrap();
assert_eq!(result, now - chrono::Duration::days(1));
assert_eq!(result.hour(), now.hour());
assert_eq!(result.minute(), now.minute());
assert_eq!(result.second(), now.second());
let result = at_date(parse(&mut "2025-01-01 2 days ago").unwrap(), now).unwrap();
assert_eq!(result.hour(), 0);
assert_eq!(result.minute(), 0);