这是在Nodatime之间转换时区的正确方法吗?

时间:2016-08-29 14:16:23

标签: c# nodatime

目标是创建一个函数,使用Nodatime将时间从一个时区转换为另一个时区。我不只是在寻找关于结果是否正确的反馈,而是针对“我如何”这样做的反馈(这是真的正确,还是有微妙的漏洞)。

这是功能:

static ZonedDateTime ConvertDateTimeToDifferentTimeZone(DateTime p_from_datetime, string p_from_zone, string p_to_zone)
{
    DateTimeZone from_zone = DateTimeZoneProviders.Tzdb[p_from_zone];
    LocalDateTime from_local = new LocalDateTime(p_from_datetime.Year, p_from_datetime.Month, p_from_datetime.Day, p_from_datetime.Hour, p_from_datetime.Minute);
    ZonedDateTime from_datetime = from_zone.AtStrictly(from_local);

    var from_instant = from_datetime.ToInstant();

    DateTimeZone to_zone = DateTimeZoneProviders.Tzdb[p_to_zone];
    ZonedDateTime to_datetime = to_zone.AtStrictly(from_local);

    var to_offset_datetime = from_instant.WithOffset(to_datetime.Offset);

    return to_zone.AtStrictly(to_offset_datetime.LocalDateTime);
}

我称之为的方式如下:

    DateTime from_datetime = new DateTime(2016, 10, 15, 16, 30, 0);
    string from_zone = "US/Central";
    string to_zone = "US/Eastern";
    var x = ConvertDateTimeToDifferentTimeZone(from_datetime, from_zone, to_zone);

    Console.WriteLine(from_datetime.ToString() + " (" + from_zone + ") = " + " (" + x.ToString() + " (" + to_zone + ")");

我错过了什么或做错了吗?

2 个答案:

答案 0 :(得分:6)

我会尽可能坚持使用Noda Time类型(和.NET命名约定)。区域之间的转换应该使用ZonedDateTime.WithZone - 这意味着您真正要求转换到ZonedDateTime和从DateTime转换。如果你真的,真的必须使用public static DateTime ConvertDateTimeToDifferentTimeZone( DateTime fromDateTime, string fromZoneId, string tozoneId) { LocalDateTime fromLocal = LocalDateTime.FromDateTime(fromDateTime); DateTimeZone fromZone = DateTimeZoneProviders.Tzdb[fromZoneId]; ZonedDateTime fromZoned = fromLocal.InZoneLeniently(fromZone); DateTimeZone toZone = DateTimeZoneProviders.Tzdb[toZoneId]; ZonedDateTime toZoned = fromZoned.WithZone(toZone); LocalDateTime toLocal = toZoned.LocalDateTime; return toLocal.ToDateTimeUnspecified(); } 而不是Noda Time类型,你可能需要这样的东西:

LocalDateTime

请注意此处使用InZoneLeniently - 这意味着如果由于UTC偏移的跳转(通常由于夏令时)而导致的当地时间无效,则仍会返回值而不是抛出异常 - 请参阅文档以获取更多详细信息。

如果您在整个过程中使用Noda Time,很难知道这种方法会是什么样的,因为我们不知道您是从ZonedDateTime还是以{a}开始public static LocalDateTime ConvertDateTimeToDifferentTimeZone( LocalDateTime fromLocal, string fromZoneId, string tozoneId) { DateTimeZone fromZone = DateTimeZoneProviders.Tzdb[fromZoneId]; ZonedDateTime fromZoned = fromLocal.InZoneLeniently(fromZone); DateTimeZone toZone = DateTimeZoneProviders.Tzdb[toZoneId]; ZonedDateTime toZoned = fromZoned.WithZone(fromZone); return toZoned.LocalDateTime; } 。例如,您可以:

false

答案 1 :(得分:1)

我觉得这个方法编写得很好。就我所知,你不会错过任何事情/做任何不妥之处的事情。但是这里有一个方法的改进版本:

static ZonedDateTime ConvertDateTimeToDifferentTimeZone(DateTime p_from_datetime, string p_from_zone, string p_to_zone)
{
    DateTimeZone from_zone = DateTimeZoneProviders.Tzdb[p_from_zone];
    var from_local = LocalDateTime.FromDateTime(p_from_datetime);
    ZonedDateTime from_datetime = from_zone.AtStrictly(from_local);

    DateTimeZone to_zone = DateTimeZoneProviders.Tzdb[p_to_zone];
    return from_datetime.WithZone(to_zone);
}