2014-01-07 40 views
2

我需要確定給定的事件的Olson TZID和事件的日期時間的時間偏移確定給定Olson TZID和本地DateTime的時間偏移?

我想我可以在野外時間的幫助下做到這一點,但我是新來的,需要幫助 - 一個實際的API調用序列來執行這個任務的例子。

我們正在使用和做的一些更多細節。

  1. 我們正在運行基於ASP.NET + SQL Server的網站。我們網站的用戶輸入並保存在不同地點發生的事件。對於具有時間偏移(該事件)的每個事件Lat/Long和DateTime是必填字段之一。
  2. 數據輸入有多種情況,有時首先輸入緯度/長度,有時候是DateTime。系統允許從地址或地圖點確定緯度/經度。我們希望時間偏移在大多數情況下與Lat/Long保持一致,因爲我們通常希望DateTime作爲該事件的本地輸入。
  3. 我們使用SQL Server DateTimeOffset字段來存儲數據。
  4. 我們不希望依賴第三方Web服務來確定偏移量,但更希望我們的系統能夠這樣做。

我可以自由下載和使用任何必要的工具或數據。我已經從http://efele.net/maps/tz/下載了shapefile,並使用Shape2SQL http://goo.gl/u7AUy將它們轉換爲帶有TZID和GEOM的SQL Server表。
我知道如何從Lat/Long通過查詢該表獲取TZID。
我還需要的是從TZID和日期時間確定時間偏移量。

+0

我想我已經有了一個正確的Jon Skeet在Noda Time Google Group http://goo.gl/I9unm0上回答了我的問題。儘管如此,這並不會影響這個問題和答案,因爲其他人也可能會使用它。 – vkelman

+0

如果是這種情況,您可以自己回答問題,並在延遲後接受它。 –

回答

1

感謝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; 
    } 
} 
相關問題