我有将长整数转换为日期的代码。
DateTimeOffset value =
DateTimeOffset.FromUnixTimeSeconds(1597325462);
DateTime showTime = value.DateTime;
string easternZoneId = "America/New_York";
TimeZoneInfo easternZone =
TimeZoneInfo.FindSystemTimeZoneById(easternZoneId);
DateTime targetTime =
TimeZoneInfo.ConvertTime(showTime, easternZone);
Console.WriteLine("DateTime is {0}", targetTime);
在我的Mac上,输出为"DateTime is 8/13/2020 6:31:02 AM"
在我的服务器上,输出为"DateTime is 8/13/2020 9:31:02 AM"
两者上的代码相同。Linux盒值是准确的。如何在Mac上获得相同的结果?
最佳答案
您正在使用的TimeZone.ConvertTime
的重载采用DateTime
值和目标TimeZoneInfo
。由于没有提及源时区,因此可以从传入的.Kind
的DateTime
属性中推断出来。
在您的情况下,即DateTimeKind.Unspecified
,因为.DateTime
的DateTimeOffset
属性始终返回unspecified,而不管偏移量是多少。
在ConvertTime
调用中,如果类型为DateTimeKind.Unspecified
,则假定它是本地时间(就好像是DateTimeKind.Local
一样)。 (向下滚动到“备注”部分in the docs here。)因此,您进行的转换就好像Unix时间戳是基于本地时间的,而不是实际上是基于UTC的。在工作站和服务器之间获得不同的结果是因为它们具有不同的系统本地时区,而不是因为它们运行的是不同的操作系统。
有很多不同的方法可以重写此代码以解决该问题。我将按照您的偏好为您提供一些选择:
DateTimeOffset
:DateTimeOffset value = DateTimeOffset.FromUnixTimeSeconds(1597325462);
string easternZoneId = "America/New_York";
TimeZoneInfo easternZone = TimeZoneInfo.FindSystemTimeZoneById(easternZoneId);
DateTimeOffset targetTime = TimeZoneInfo.ConvertTime(value, easternZone);
.UtcDateTime
属性代替.DateTime
属性:DateTimeOffset value = DateTimeOffset.FromUnixTimeSeconds(1597325462);
DateTime showTime = value.UtcDateTime;
string easternZoneId = "America/New_York";
TimeZoneInfo easternZone = TimeZoneInfo.FindSystemTimeZoneById(easternZoneId);
DateTime targetTime = TimeZoneInfo.ConvertTime(showTime, easternZone);
ConvertTimeFromUtc
代替ConvertTime
:DateTimeOffset value = DateTimeOffset.FromUnixTimeSeconds(1597325462);
DateTime showTime = value.DateTime;
string easternZoneId = "America/New_York";
TimeZoneInfo easternZone = TimeZoneInfo.FindSystemTimeZoneById(easternZoneId);
DateTime targetTime = TimeZoneInfo.ConvertTimeFromUtc(showTime, easternZone);
ConvertTime
调用中将UTC指定为源时区:DateTimeOffset value = DateTimeOffset.FromUnixTimeSeconds(1597325462);
DateTime showTime = value.DateTime;
string easternZoneId = "America/New_York";
TimeZoneInfo easternZone = TimeZoneInfo.FindSystemTimeZoneById(easternZoneId);
DateTime targetTime = TimeZoneInfo.ConvertTime(showTime, TimeZoneInfo.Utc, easternZone);
还有其他一些选择,例如显式设置种类,但我认为以上内容为您提供了足够的机会。
如有疑问,请选择第一个选项。在大多数情况下,
DateTimeOffset
比DateTime
更容易合理化。