Как перейти от NaiveDate к определенной временной зоне с Chrono? - PullRequest
0 голосов
/ 13 мая 2018

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

Дата отображается в формате %d/%m/%Y (пример: 27/08/2018).Время показывается только с часом (пример: 12, 10, 21 и т. Д.)

Я хочу сохранить эти даты в формате UTC, чтобы я мог вычислить время, оставшееся до заданной даты в настоящем времени, в "часовой пояс ".Я знаю, из какого часового пояса эти даты и время (по парижскому времени).

Я создал NaiveDate из ввода даты (это работа, поэтому обработка ошибок еще не выполнена):

let naive_date = NaiveDate::parse_from_str(date, "%d/%m/%Y").unwrap()

С этого момента, как лучше всего получить UTC DateTime, учитывая, что у меня есть строка с часом?

Я потерян в различных чертах TimeZone / Offset и не знаю, следует ли мне использовать Local или FixedOffset, а затем преобразовать в Utc.

Ответы [ 3 ]

0 голосов
/ 14 мая 2018

Дата и время взяты с веб-сайта, на котором дата и время находятся в разных разделах страницы.

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

Ключом является использование функции parse для обновления структуры Parsed. Вы можете использовать итератор StrftimeItems, чтобы продолжать использовать более читаемые строки формата.

extern crate chrono;

use chrono::prelude::*;

fn example(date: &str, hour: &str) -> chrono::ParseResult<DateTime<Utc>> {
    use chrono::format::{self, strftime::StrftimeItems, Parsed};

    // Set up a struct to perform successive parsing into
    let mut p = Parsed::default();

    // Parse the date information
    format::parse(&mut p, date.trim(), StrftimeItems::new("%d/%m/%Y"))?;
    // Parse the time information and provide default values we don't parse
    format::parse(&mut p, hour.trim(), StrftimeItems::new("%H"))?;
    p.minute = Some(0);
    p.second = Some(0);

    // Convert parsed information into a DateTime in the Paris timezone
    let paris_time_zone_offset = FixedOffset::east(1 * 3600);
    let dt = p.to_datetime_with_timezone(&paris_time_zone_offset)?;

    // You can also use chrono-tz instead of hardcoding it
    // let dt = p.to_datetime_with_timezone(&chrono_tz::Europe::Paris)?;

    // Convert to UTC
    Ok(dt.with_timezone(&Utc))
}

fn main() {
    let date = "27/08/2018";
    let hour = "12";

    println!("dt = {:?}", example(date, hour)); // Ok(2018-08-27T11:00:00Z)
}
0 голосов
/ 15 мая 2018

Я обнаружил chrono-tz и обнаружил, что его гораздо проще использовать. Например:

pub fn create_date_time_from_paris(date: NaiveDate, time: NaiveTime) -> DateTime<Utc> {
    let naive_datetime = NaiveDateTime::new(date, time);
    let paris_time = Paris.from_local_datetime(&naive_datetime).unwrap();
    paris_time.with_timezone(&Utc)
}
0 голосов
/ 13 мая 2018

Документация Chrono, вероятно, может быть улучшена, чтобы упростить поиск этих действий.

Предполагая, что это ваша отправная точка:

use chrono::{DateTime, FixedOffset, NaiveDate, NaiveDateTime, NaiveTime, TimeZone, Utc};

// The date you parsed
let date = NaiveDate::from_ymd(2018, 5, 13);
// The known 1 hour time offset in seconds
let tz_offset = FixedOffset::east(1 * 3600);
// The known time
let time = NaiveTime::from_hms(17, 0, 0);
// Naive date time, with no time zone information
let datetime = NaiveDateTime::new(date, time);

Затем вы можете использовать FixedOffset для построения DateTime:

let dt_with_tz: DateTime<FixedOffset> = tz_offset.from_local_datetime(&datetime).unwrap();

Если вам нужно преобразовать его в DateTime<Utc>, вы можете сделать это:

let dt_with_tz_utc: DateTime<Utc> = Utc.from_utc_datetime(&dt_with_tz.naive_utc());
...