Как преобразовать вариант перечисления TimeZone в фиксированное смещение?
Я пытаюсь преобразоватьchrono_tz::Tz
смещение часового пояса в фиксированное смещение в единицах количества часов.
Вот как мне удалось создать объект Tz:
let input_string_timezone = "Europe/London";
let tz_timezone = Tz::from_str(input_string_timezone)
.expect("failed to convert string to chrono tz");
Отсюда я могу получить имя смещения, а также смещение в секундах, когда летнее время действует, а когда не действует. Вот как я это сделал:
println!("tz_offset: {}", tz_offset);
println!("tz_offset base_utc_offset: {}", tz_offset.base_utc_offset());
println!("tz_offset dst_offset: {}", tz_offset.dst_offset());
Мне удалось преобразовать объект часового пояса в смещение по количеству секунд от UTC. Однако то, что я создал, — это два возможных значения смещения, а не текущее значение смещения на сегодняшний день.
Я хочу получить смещение «сегодня». Чтобы сделать это, мне пришлось бы указать сегодняшнюю дату для какой-то черты или функции, но я не знаю, будет ли Rustchrono
илиchrono_tz
ящики имеют поддержку этой операции.
2 ответа
Проблему можно решить, найдя разницу между датой и временем в формате UTC и локальной датой и временем.
let input_string_timezone = "Europe/London";
let tz_timezone = Tz::from_str(input_string_timezone)
.expect("failed to convert string to chrono tz");
// First create a UTC datetime
let utc_now = Utc::now();
println!("utc_now: {}", utc_now);
// From this we need the naive datetime
let naive_date_now = utc_now.date_naive();
println!("naive_date_now: {}", naive_date_now);
// Using the naive datetime, we can construct a datetime, in the
// timezone of our choosing. In this case, I have used the previously
// obtained timezone object for Europe/London
let london_now = tz_timezone.from_local_datetime(&naive_datetime).unwrap();
println!("london_now: {}", london_now);
// Note that rather than constructing a timezone object from a string
// we can also select the timezone type from the module of our choice
let london_now = chrono_tz::Europe::London.from_local_datetime(&naive_datetime).unwrap();
println!("london_now: {}", london_now);
// We need to convert this to UTC
let london_now_utc = Utc.from_utc_datetime(&london_now.naive_utc());
println!("london_now_utc: {}", london_now_utc);
// Finally, we can subtract to obtain a Duration
let difference_from_utc = london_now_utc - utc_now;
println!("difference_from_utc: {}", difference_from_utc);
Возможно, вы захотите проверить документацию
dst_offset()
опять же (выделено мной) это дает
Дополнительное смещение от UTC, действующее в данный момент ; обычно для летнего времени
Итак, полная функция получения сегодняшнего смещения от UTC для часового пояса такова:
/*
[dependencies]
chrono = "*"
chrono-tz = "*"
*/
use chrono::TimeZone;
use chrono_tz::OffsetComponents;
fn get_todays_offset(tz: chrono_tz::Tz) -> chrono::Duration {
let now = chrono::Utc::now().naive_utc();
let offset = tz.offset_from_utc_datetime(&now);
offset.base_utc_offset() + offset.dst_offset()
}
Вы можете убедиться, что он действительно дает текущее смещение, добавив пару месяцев кnow
например с.checked_add_months(chrono::Months::new(6)).unwrap()