解析用户输入,包括tz数据库时区名称

时间:2013-01-22 12:28:46

标签: c# timezone nodatime

我正在尝试用Noda Time解析用户输入。

输入:

  • YYYY-MM-DD
  • 形式的日期
  • 小时
  • 分钟
  • tz数据库时区名称(从Google的时区API返回)

我需要将此数据转换为UTC和其他时区,同样基于tz数据库时区名称。

目前我正在尝试理解LocalDateTimeZonedDateTime之间的差异,但也许有人能够在我(希望)解决这个问题之前展示如何做到这一点。

2 个答案:

答案 0 :(得分:1)

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");
}

答案 1 :(得分:1)

你的回答非常接近我所做的 - 但如果你有单独的字符串中的日期,小时和分钟,我会使用:

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的含义 - 如果输入的本地日期/时间不明确,你肯定想失败吗?