我正在研究writing a managed wrapper around Massachusetts Bay Transportation Authority (MBTA) Realtime API。它们有一个API,它返回服务器时间,即unix时间戳(epoch)。我正在实施它的库是PCL Profile 78
,这意味着我对BCL TimeZone的支持有限,所以我使用了Nodatime
我正在尝试将从服务器返回的时间转换为东部时间,America/New_York
作为DateTime
对象并反向转换。 My current code is very dirty
public static class TimeUtils
{
static readonly DateTimeZone mbtaTimeZone = DateTimeZoneProviders.Tzdb["America/New_York"];
static readonly DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
public static DateTime GetMbtaDateTime (long unixTimestamp)
{
var mbtaEpochTime = epoch.AddSeconds (unixTimestamp);
var instant = Instant.FromUtc (mbtaEpochTime.Year, mbtaEpochTime.Month,
mbtaEpochTime.Day, mbtaEpochTime.Hour, mbtaEpochTime.Minute, mbtaEpochTime.Second);
var nodaTime = instant.InZone (mbtaTimeZone);
return nodaTime.ToDateTimeUnspecified ();
}
public static long MbtaDateTimeToUnixTimestamp (DateTime time)
{
TimeSpan secondsSinceEpochMbtaTz = time - epoch;
var instant = Instant.FromUtc (time.Year, time.Month, time.Day, time.Hour, time.Minute, time.Second);
var mbtaTzSpan = mbtaTimeZone.GetUtcOffset (instant).ToTimeSpan ();
var epochDiff = secondsSinceEpochMbtaTz - mbtaTzSpan;
return (long)epochDiff.TotalSeconds;
}
}
还有另一种方法可以简单地写这个。我希望Nodatime应该支持将纪元时间转换为America/New_York
DateTime和America/New_York
DateTime到纪元时间。我的方法MbtaDateTimeToUnixTimestamp
是一个残酷的黑客
答案 0 :(得分:7)
首先,正如评论中所提到的,最好在整个代码中使用Noda Time类型 - 当真正必须时,只使用DateTime
。这应该会导致整个代码更加清晰。
将Unix时间戳转换为Instant
非常简单:
Instant instant = Instant.FromSecondsSinceUnixEpoch(seconds);
然后,您可以根据当前代码转换为ZonedDateTime
...如果您确实需要使用ToDateTimeUnspecified
,则可以使用DateTime
。
反过来说,你当前的代码看起来很糟糕 - 你假设DateTime
是一个有效的UTC值。这与你以后使用时区不符。我怀疑你想将输入转换为LocalDateTime
,然后应用时区。例如:
public static long MbtaDateTimeToUnixTimestamp(DateTime time)
{
var local = LocalDateTime.FromDateTime(time);
var zoned = local.InZoneStrictly(mbtaTimeZone);
var instant = zoned.ToInstant();
return instant.Ticks / NodaConstants.TicksPerSecond;
}
请注意InZoneStrictly
来电。如果你传入一个不存在的本地时间或一个存在两次的情况,这将引发异常 - 在两种情况下都是由于DST转换。这可能不是您想要的 - 您真的需要考虑在这些情况下您想要发生什么,或者尽量避免它们可行。有关详细信息和选项,请参阅time zones section of the documentation。