Разбор пользовательского ввода, включая имя часового пояса базы данных tz

Я пытаюсь проанализировать пользовательский ввод с помощью Noda Time.

Вход:

  • Дата в виде YYYY-MM-DD
  • Час
  • Минута
  • имя часового пояса базы данных tz (возвращается из Google Time Zone API)

Мне нужно преобразовать эти данные в UTC и другие часовые пояса, также на основе имени часового пояса базы данных tz.

В настоящее время я пытаюсь разобраться в различиях LocalDateTime и ZonedDateTime, но, возможно, кто-то сможет показать, как это сделать, прежде чем я (надеюсь) разберусь с этим.


person user247702    schedule 22.01.2013    source источник


Ответы (2)


Ваш ответ довольно близок к тому, что сделал бы я, но если у вас есть дата, час и минута в отдельных строках, я бы использовал:

var zoneProvider = DateTimeZoneProviders.Tzdb;
var sourceZone = zoneProvider.GetZoneOrNull("Europe/Brussels");
var targetZone = zoneProvider.GetZoneOrNull("Australia/Melbourne");

if (sourceZone == null || targetZone == null)
{
    Console.WriteLine("Time zone not found");
    return;
}

var dateParseResult = LocalDatePattern.IsoPattern.Parse(date);
int hourValue, minuteValue;
if (!dateParseResult.Success ||
    !int.TryParse(hour, out hourValue) ||
    !int.TryParse(minute, out minuteValue))
{
    Console.WriteLine("Parsing failed");
    return;       
}

var localDateTime = dateParseResult.Value + new LocalTime(hour, minute);
var zonedDateTime = localDateTime.InZoneStrictly(sourceZone);
Console.WriteLine(zonedDateTime.ToInstant());
Console.WriteLine(zonedDateTime);
Console.WriteLine(zonedDateTime.WithZone(targetZone));

Единственная существенная разница здесь заключается в синтаксическом анализе - я бы не стал склеивать все биты вместе; Я бы просто проанализировал строки отдельно. (Я также предпочитаю «ранние выходы» из-за неудач :)

Однако вы должны отметить значение InZoneStrictly - вы определенно хотите потерпеть неудачу, если введенная локальная дата/время неоднозначна?

person Jon Skeet    schedule 24.01.2013
comment
Спасибо за ваши идеи. Нам все еще нужно решить, как мы будем обрабатывать неоднозначные значения, поэтому я просто использовал InZoneStrictly в своей тестовой программе. - person user247702; 25.01.2013
comment
@Stijn: Пока вы знаете о возможной проблеме и доступных вариантах, я счастлив :) - person Jon Skeet; 25.01.2013

http://msmvps.com/blogs/jon_skeet/archive/2012/02.aspx содержит отличную информацию, и хотя он немного устарел, в официальной документации легко найти соответствующие имена методов.

Ниже приведен некоторый демонстрационный код.

string date = "2013-01-22";
string hour = "13";
string minute = "15";

var result = LocalDateTimePattern.ExtendedIsoPattern.Parse(date + "T" + hour + ":" + minute + ":00");

if (result.Success == true)
{
    DateTimeZone source_zone = DateTimeZoneProviders.Tzdb.GetZoneOrNull("Europe/Brussels");
    DateTimeZone target_zone = DateTimeZoneProviders.Tzdb.GetZoneOrNull("Australia/Melbourne");

    if (source_zone != null && target_zone != null)
    {
        ZonedDateTime source_zoned_dt = result.Value.InZoneStrictly(source_zone);

        Console.WriteLine(source_zoned_dt.ToInstant());
        Console.WriteLine(source_zoned_dt);
        Console.WriteLine(source_zoned_dt.WithZone(target_zone));
    }
    else
    {
        Console.WriteLine("time zone not found");
    }
}
else
{
    Console.WriteLine("parsing failed");
}
person user247702    schedule 22.01.2013