Как получить продолжительность 1 дня с Rust Chrono? - PullRequest
3 голосов
/ 09 января 2020

Я имею дело с некоторым кодом Rust, который работает с продолжительностью дней, но реализация Duration::days(n), согласно документации, n * 24 * 60 * 60 секунд, что не n дней, потому что не все дни 24 * 60 * 60 секунд.

Это поведение хорошо задокументировано:

pub fn days(days: i64) -> Duration

Создает новый Duration с заданным числом дней. Эквивалент Duration::seconds(days * 24 * 60 * 60) с проверками переполнения. Паникует, когда продолжительность выходит за пределы.

Есть ли способ с Rust Chrono получить продолжительность, которая строго 1 день, а не количество секунд и совместима с DateTime типы? Не все дни имеют одинаковое количество секунд. seconds и days - совершенно разные единицы. Если бы была такая функция, то следующее всегда давало бы результат с тем же временем дня следующего дня?

let start = Local.now();
let one_day_later = start + function_that_returns_a_duration_of_days(1);

Опять же, Duration:days(1) не такая функция, потому что она возвращает 1 * 24 * 60 * 60 секунд, а не 1 день .

Например, с TZ , установленным на Америка / Денвер , следующее:

let start = Local.ymd(2019, 3, 10).and_hms(0, 0, 0);
println!("start: {}", start);
let end = Local.ymd(2019, 3, 11).and_hms(0, 0, 0);
println!("end: {}", end);
let elapsed_seconds = end.timestamp() - start.timestamp();
println!("elapsed_seconds: {}", elapsed_seconds);
let end2 = start + Duration::days(1);
println!("end2: {}", end2);
let elapsed_seconds2 = end2.timestamp() - start.timestamp();
println!("elapsed_seconds2: {}", elapsed_seconds2);

Возвращает:

start: 2019-03-10 00:00:00 -07:00
end: 2019-03-11 00:00:00 -06:00
elapsed_seconds: 82800
end2: 2019-03-11 01:00:00 -06:00
elapsed_seconds2: 86400

Добавляет 86400 секунд , а не 1 день .

Я могу получить правильно результат с:

let one_day_later =
    (start.date() + Duration::days(1)).and_hms(start.hour(), start.minute(), start.second());

Но я бы предпочел функцию, которая возвращает продолжительность дней, и в целом хотел бы узнать больше о возможностях Rust Chrono для обработки продолжительности. Есть ли у него продолжительность с единицами, отличными от секунд? А как насчет недель, месяцев и лет, которые также имеют переменное число секунд?

Я, вероятно, должен сказать, что я не знаю Rust, только работая с ним уже несколько дней, и у меня не так много прочитайте исходный код Я посмотрел на него, но мне трудно его понять из-за моего ограниченного знания языка.

1 Ответ

3 голосов
/ 09 января 2020

A Duration - количество времени. Нет никакого количества времени, которое при добавлении к мгновению всегда дает то же самое время на следующий день, потому что, как вы заметили, в календарных днях может быть разное количество времени.

Не только годы, недели и дни, но даже часы и минуты не всегда составляют одинаковое количество времени ( високосная секунда ). Duration - это количество времени, а не «календарная единица». Так что нет, Duration не способен выразить такую ​​идею, как «в то же время на следующей неделе».

Самый простой способ express «в то же время на следующий день» - это succ и and_time методы для Date:

let one_day_later = start.date().succ().and_time(start.time());

and_time будут Pani c, если время не существует на новую дату.

...