感謝Jon Skeet和Matt Johnson對Noda Time Google Group http://goo.gl/I9unm0的回答。 Jon解釋瞭如何獲得給定Olson TZID和NodaTime LocalDateTime值的Microsoft BCL DateTimeOffset值。 Matt指出了一個確定DST是否在ZonedDateTime時有效的例子:What is the System.TimeZoneInfo.IsDaylightSavingTime equivalent in NodaTime?
我打算寫一篇博客文章,總結我從Lat /我將在那裏展示GetTmzIdByLocation(緯度,經度)和GetRoughDateTimeOffsetByLocation(緯度,經度)方法的工作原理以及爲什麼我需要這兩種方法(第一種方法不適用于海洋上的位置)。一旦我寫這篇文章,我會在這裏添加評論。
請注意,在下面的代碼中解析DateTime字符串還不是最優的;正如馬特在谷歌集團的一篇文章中所解釋的(上面的鏈接),使用野田時間工具比BCL更好。看到相關的問題在http://goo.gl/ZRZ7XP
我當前的代碼:
public object GetDateTimeOffset(string latitude, string longitude, string dateTime)
{
var tzFound = false;
var isDST = false;
var tmpDateTime = new DateTimeOffset(DateTime.Now).DateTime;
if (!String.IsNullOrEmpty(dateTime))
{
try
{
// Note: Looks stupid? I need to throw away TimeZone Offset specified in dateTime string (if any).
// Funny thing is that calling DateTime.Parse(dateTime) would automatically modify DateTime for its value in a system timezone.
tmpDateTime = DateTimeOffset.Parse(dateTime).DateTime;
}
catch (Exception) { }
}
try
{
var tmzID = GetTmzIdByLocation(latitude, longitude);
DateTimeOffset result;
if (String.IsNullOrEmpty(tmzID) || tmzID.ToLower() == "uninhabited") // TimeZone is unknown, it's probably an ocean, so we would just return time offest based on Lat/Long.
{
var offset = GetRoughDateTimeOffsetByLocation(latitude, longitude);
result = new DateTimeOffset(tmpDateTime, TimeSpan.FromMinutes(offset * 60)); // This only works correctly if tmpDateTime.Kind = Unspecified, see http://goo.gl/at3Vba
} // A known TimeZone is found, we can adjust for DST using Noda Time calls below.
else
{
tzFound = true;
// This was provided by Jon Skeet
var localDateTime = LocalDateTime.FromDateTime(tmpDateTime); // See Noda Time docs at http://goo.gl/XseiSa
var dateTimeZone = DateTimeZoneProviders.Tzdb[tmzID];
var zonedDateTime = localDateTime.InZoneLeniently(dateTimeZone); // See Noda Time docs at http://goo.gl/AqE8Qo
result = zonedDateTime.ToDateTimeOffset(); // BCL DateTimeOffset
isDST = zonedDateTime.IsDaylightSavingsTime();
}
return new { result = result.ToString(IncidentDateFormat), tzFound, isDST };
}
catch (Exception ex)
{
IMAPLog.LogEvent(System.Reflection.MethodBase.GetCurrentMethod().Name, "", ex);
throw new CustomHttpException("Unable to get timezone offset.");
}
}
擴展方法(由馬特·約翰遜提供),以便確定是否DST是活動What is the System.TimeZoneInfo.IsDaylightSavingTime equivalent in NodaTime?
public static class NodaTimeUtil
{
// An extension method by Matt Johnson - on Stack Overflow at http://goo.gl/ymy7Wb
public static bool IsDaylightSavingsTime(this ZonedDateTime zonedDateTime)
{
var instant = zonedDateTime.ToInstant();
var zoneInterval = zonedDateTime.Zone.GetZoneInterval(instant);
return zoneInterval.Savings != Offset.Zero;
}
}
我想我已經有了一個正確的Jon Skeet在Noda Time Google Group http://goo.gl/I9unm0上回答了我的問題。儘管如此,這並不會影響這個問題和答案,因爲其他人也可能會使用它。 – vkelman
如果是這種情況,您可以自己回答問題,並在延遲後接受它。 –