这是在 Nodatime 中时区之间转换的正确方法吗?
Is this the proper way to convert between time zones in Nodatime?
目标是创建一个函数,使用 Nodatime 将时间从一个时区正确转换为另一个时区。我不只是在寻找关于结果是否正确的反馈,而是针对我正在做的 "how" 的反馈(它是否真的正确,或者是否存在细微的漏洞)。
函数如下:
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 + ")");
我是不是遗漏了什么或做错了什么?
我觉得方法写的很好。据我所知,你没有遗漏 anything/doing 任何不正确的东西。但这里有一个改进版的方法:
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);
}
我会尽可能坚持使用 Noda Time 类型(和 .NET 命名约定)。区域之间的转换应使用 ZonedDateTime.WithZone
完成 - 这意味着您实际上是在询问与 ZonedDateTime
之间的转换。如果你真的,真的必须使用 DateTime
而不是 Noda Time 类型,你可能想要这样的东西:
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();
}
请注意此处使用 InZoneLeniently
- 这意味着如果您提供的本地时间由于 UTC 偏移量的跳跃(通常是由于夏令时)而无效,它仍然会 return 一个值而不是抛出异常 - 有关更多详细信息,请参阅文档。
很难知道如果您始终使用 Noda Time,该方法会是什么样子,因为我们不知道您是从 LocalDateTime
还是 ZonedDateTime
开始。例如,您可以:
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;
}
目标是创建一个函数,使用 Nodatime 将时间从一个时区正确转换为另一个时区。我不只是在寻找关于结果是否正确的反馈,而是针对我正在做的 "how" 的反馈(它是否真的正确,或者是否存在细微的漏洞)。
函数如下:
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 + ")");
我是不是遗漏了什么或做错了什么?
我觉得方法写的很好。据我所知,你没有遗漏 anything/doing 任何不正确的东西。但这里有一个改进版的方法:
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);
}
我会尽可能坚持使用 Noda Time 类型(和 .NET 命名约定)。区域之间的转换应使用 ZonedDateTime.WithZone
完成 - 这意味着您实际上是在询问与 ZonedDateTime
之间的转换。如果你真的,真的必须使用 DateTime
而不是 Noda Time 类型,你可能想要这样的东西:
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();
}
请注意此处使用 InZoneLeniently
- 这意味着如果您提供的本地时间由于 UTC 偏移量的跳跃(通常是由于夏令时)而无效,它仍然会 return 一个值而不是抛出异常 - 有关更多详细信息,请参阅文档。
很难知道如果您始终使用 Noda Time,该方法会是什么样子,因为我们不知道您是从 LocalDateTime
还是 ZonedDateTime
开始。例如,您可以:
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;
}