我想要完成的是将DateTime(从假定的字符串解析为EST/EDT中)转换为UTC。我使用的是NodaTime,因为我需要使用Olson时区。使用NodaTime将无效(跳过)的日期时间值转换为UTC
使用NodaTime的ZoneLocalMappingResolver将无效的(跳过的)DateTime转换为UTC ZoneLocalMappingResolver不会转换输入的分秒部分,因为我已配置CustomResolver以在间隔后返回间隔的开始。 NodaTime似乎没有相应的TimeZoneInfo.IsInvalidTime。
如何使用NodaTime将跳过的日期时间值转换为UTC并与下面的Utils类中的GetUtc()方法的结果相匹配? (Utils.GetUtc方法使用System.TimeZoneInfo不NodaTime)
这是测试用例:
[TestMethod]
public void Test_Invalid_Date()
{
var ts = new DateTime(2013, 3, 10, 2, 15, 45);
// Convert to UTC using System.TimeZoneInfo
var utc = Utils.GetUtc(ts).ToString(Utils.Format);
// Convert to UTC using NodaTime (Tzdb/Olson dataabase)
var utcNodaTime = Utils.GetUtcTz(ts).ToString(Utils.Format);
Assert.AreEqual(utc, utcNodaTime);
}
这就是我得到:
Assert.AreEqual失败。预计:< 2013-03-10 07:15:45.000000>。实际:< 2013-03-10 07:00:00.000000>。
这里是utils的类(也github):
using System;
using NodaTime;
using NodaTime.TimeZones;
/// <summary>
/// Functions to Convert To and From UTC
/// </summary>
public class Utils
{
/// <summary>
/// The date format for display/compare
/// </summary>
public const string Format = "yyyy-MM-dd HH:mm:ss.ffffff";
/// <summary>
/// The eastern U.S. time zone
/// </summary>
private static readonly NodaTime.DateTimeZone BclEast = NodaTime.DateTimeZoneProviders.Bcl.GetZoneOrNull("Eastern Standard Time");
private static readonly TimeZoneInfo EasternTimeZone = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
private static readonly NodaTime.DateTimeZone TzEast = NodaTime.DateTimeZoneProviders.Tzdb.GetZoneOrNull("America/New_York");
private static readonly ZoneLocalMappingResolver CustomResolver = Resolvers.CreateMappingResolver(Resolvers.ReturnLater, Resolvers.ReturnStartOfIntervalAfter);
public static DateTime GetUtc(DateTime ts)
{
return TimeZoneInfo.ConvertTimeToUtc(EasternTimeZone.IsInvalidTime(ts) ? ts.AddHours(1.0) : ts, EasternTimeZone);
}
public static DateTime GetUtcTz(DateTime ts)
{
var local = LocalDateTime.FromDateTime(ts);
var zdt = TzEast.ResolveLocal(local, CustomResolver);
return zdt.ToDateTimeUtc();
}
public static DateTime GetUtcBcl(DateTime ts)
{
var local = LocalDateTime.FromDateTime(ts);
var zdt = BclEast.ResolveLocal(local, CustomResolver);
return zdt.ToDateTimeUtc();
}
}
我已更新此答案中的参考链接,以导致您在nodatime.org上托管的新API文档而不是旧的缺失的Google代码网站。 – clarkitect 2016-03-08 15:36:46