2016-06-08 71 views
3

我正在開發一個可以指定日期,時間,時區城市的日程安排網站。我想將它保存在UTC時間的後端。所以我必須在服務器上以某種方式轉換它。我也想提供轉換到不同時區的能力。使用時區城市座標和當地時間的時區轉換

在Javascript中,我有日期/時間值以及時區城市(從http://www.citytimezones.info這給了我地理座標)。我沒有UTC時間,只有指定時區的時間。

現在我需要將這個未來的本地時間轉換爲UTC。當然,它必須考慮當時適用的夏令時偏移。

此外,我想使用第二個時區城市轉換爲不同的當地時間。

我曾考慮過使用Google地圖時區API,但這會強制您傳遞UTC時間,這是我沒有的,因爲我正在計算它。

換句話說,最好我需要一個系統,將這些參數:

  • 未來時間/日期
  • 來源時區的城市座標
  • 目的地時區的城市座標(或空= UTC時間)

並且將返回轉換的時間。

任何想法我能做些什麼來實現這一點?

這可能是Web服務或Windows C#庫。

+0

如果未來的時區規則發生變化,那麼未來的UTC時間可能會變得不正確。時區規則經常令人驚訝地發生變化。顯然,這個問題適用於所有多時區調度應用程序,我認爲唯一的解決方案是存儲原始本地時間,以便在將來適用的時區規則發生變化時重新計算UTC時間。 –

+0

@MartinLiversage是的,我打算存儲這樣做。調度還會保存當地時間,以便我們可以重新計算UTC時間。 – Emmanuel

+0

我不知道爲什麼這被標記爲「DateTime vs DateTimeOffset」的重複。這太荒謬了,因爲另一個問題甚至沒有談到時區之間的翻譯。充其量,這可能是「谷歌地圖時區API vs DateTimeOffset」,但這是它的延伸。 – Emmanuel

回答

1

拆分問題分爲兩個部分:

  • 確定從位置cooridnates
  • 的時區的時區之間的轉換時間

你會發現幾種方法來做每個。

對於第1步,您提到了Google時區API和CityTimeZones。這兩個are listed here,以及其他幾種方法。

對於第2步,您對.NET的選擇主要在Noda TimeTimeZoneInfo之間。馬丁給出了幾個很好的例子,每個in his answer

此外,考慮到調度是比大多數情況更困難的情況。您應該閱讀this post瞭解更多詳情。

1

您需要一個時區數據庫來執行所需的日期和時間轉換。時區比單純偏移更復雜,因爲許多時區都包含夏時制規則。

.NET框架允許您通過使用TimeZoneInfo類來使用基礎Windows時區數據庫。但是,您可以考慮Windows時區數據庫專有的。 IANA保留Best Current Practice (BCP) 175中描述的Time Zone Database (TZDB)

Noda Time具有支持TZDB和提供的本地時間戳作爲.NET DateTime和可以計算相應的UTC時間戳的時區標識符:

var localDateTime = LocalDateTime.FromDateTime(dateTime); 
var timeZoneId = "America/New_York"]; 
var timeZone = DateTimeZoneProviders.Tzdb[timeZoneId]; 
var zonedDateTime = timeZone.AtLeniently(localDateTime); 
var utcDateTime = zonedDateTime.ToDateTimeUtc(); 

注意,本地時間戳可以是不明確的或無效。這種情況發生在夏令時轉換期間,當地時鐘向後移動(造成歧義)或轉發(創建無效時間)。 AtLeniently方法對如何處理歧義和無效時間戳做出了一些假設。這可能是您的應用程序中的錯誤來源。

當你有一個UTC時間戳,你可以轉換爲本地時間以同樣的方式時區ID:在http://www.citytimezones.info/

var instant = Instant.FromDateTimeUtc(utcDateTime); 
var timeZone = DateTimeZoneProviders.Tzdb[timeZoneId]; 
var zonedDateTime = instant.InZone(timeZone); 
var localDateTime = zonedDateTime.ToDateTimeUnspecified(); 

服用後一看似乎cities.txt包含Windows時區ID爲最後一列中的每個城市。這使您可以根據城市查找Windows時區ID。

然後,您可以使用此代碼轉換本地DateTime到UTC:

var timeZoneId = "Eastern Standard Time"; 
var timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById(timeZoneId); 
var utcDateTime = TimeZoneInfo.ConvertTimeToUtc(localDateTime, timeZoneInfo); 

注意ConvertTimeToUtc如果本地時間戳是模糊的或無效將拋出ArgumentException

從UTC爲本地時間的逆變換:

var localDateTime = TimeZoneInfo.ConvertTimeFromUtc(utcDateTime, timeZoneInfo);