2011-11-10 39 views
1

我目前正在以UTC存儲所有時間,以便在開始將多個站點和服務器聯機時更容易。時區和本地化

datedatetime對象翻譯爲我的模板中的字符串以及接受用戶輸入時出現問題。下午6:00 UTC對於在PST中的人來說並不意味着很多。同樣,要求用戶輸入UTC時間就是要求災難。

我該如何正確地將這些值以一種智能且不易出錯的方式進行轉換?有沒有一種方法可以從HTTP請求中確定用戶所在的時區?我真的需要一種儘可能少的努力來確定用戶的時區。

回答

1

與依賴於客戶端,以自我的問題 - 報告他們的時區是,總是有機會(有多大的機會是可辯論的),你真正得到的是一個UTC抵消。如果您獲得UTC抵消,您的邏輯大部分時間都可以正常工作,但實際上只適用於客戶端生成的確切時間戳。任何過去或未來的時間可能都有不同的UTC偏移量,而且如果沒有適當的時區數據庫,則無法預測這種偏移量。在夏令時邊界附近,使用UTC偏移可能會導致災難性的錯誤結果。除此之外,一些不識字的用戶(即奶奶)可能不知道如何設置他們本地系統的時區;但是,有些非識字用戶(即奶奶)可能不知道如何設置他們的本地系統的時區。或隧道會話或虛擬機上的用戶可能有一個「本地」時區,而這些時區並未根據其實際偏好進行設置。

根據你對該客戶端的知識(IP等)推測客戶端的政治時區可能是錯誤的,如果用戶沒有辦法覆蓋猜測,那麼可能會很煩人。但是對於匿名用戶或新用戶註冊,我認爲使用這種方法作爲初始猜測沒有任何問題,只要您給用戶一些方法來更改它,如果它是錯誤的。

我的建議是明確:

  • 包括奧爾森時區以任何用戶配置文件的一部分。時區可以由國家查找,這應該使用戶選擇他們的時區相對無痛。給予直接使用UTC選擇的用戶的0.01%:-)
  • 如果使用基於IP的猜測來填充用戶配置文件中的默認值,如果您使用的是大多數時間一個很好的查詢服務。但是如果它錯了,讓用戶改變它。
  • 對於匿名用戶,可以在顯示或輸入本地時間的任何頁面上提供某種小部件,以便讓用戶選擇他們的Olson時區,方式與用戶配置文件非常相似。將他們選擇的值存儲在cookie中。默認爲UTC或如上所述的猜測值。

在實現以前需要在本地時間顯示時間戳的基於Web的應用程序時,我發現並非所有客戶端都將UTC正確地轉換爲當地時間以用於過去和未來的日期。我不得不在服務器端執行所有轉換。這可能需要採用本地時間和奧爾森時區並返回UTC時間的Web服務。

+0

也許我在這裏問錯了問題。也許我應該問:「StackExchange如何進行日期轉換?」我從來不必在網站的任何地方輸入日期,日期似乎只是出現在正確的時區,即使是網站的公共用戶。這真的很複雜嗎?你能總結一下我應該在你的回答中做什麼嗎? –

+0

嗯,我有一個'usr' cookieover,裏面有一個變量't'。不知道如何解碼它,但如果我的時區存儲在客戶端的任何地方,可能是它。我的桌面是UTC,所以這個網站顯示我的時間。我不記得我是否明確設置了TZ。 – wberry

+0

我剛剛註銷並更改了我的桌面時區,然後訪問了該網站。我看到了UTC時間。因此它可能在cookie中,或者我的瀏覽器沒有更新其「本地」的想法,或者匿名用戶在本網站上總是看到UTC。 – wberry

0

您無法可靠地從請求標頭獲取用戶的時區。這就是大多數網站要求用戶在個人資料設置中設置其時區的原因。但是,您可以使用各種技巧嘗試獲取。一個竅門是使用Google的IP到位的API來找出用戶來自哪裏,然後嘗試從地理位置猜測時區。這也不是100%可靠的,但會讓你更接近事實。

剛剛意識到這已經至少一次在這裏問:get user timezone

0

我不會做IP地理定位。它可能非常不準確,特別是免費服務。只需要詢問用戶的郵政編碼或狀態,並將其存儲在cookie中即可。

+0

愛爾蘭和其他一些國家沒有郵政編碼。我將在任何一天對郵政細節進行地理位置定位。 –

1

我已經這樣做了。您可能需要easy_install時區對象的pytz。

import pytz 
import time 
import datetime 
d = time.time() 

print datetime.datetime.fromtimestamp(d, pytz.timezone('US/Eastern')) 
print datetime.datetime.fromtimestamp(d, pytz.timezone('US/Central')) 
print datetime.datetime.fromtimestamp(d, pytz.timezone('US/Mountain')) 
print datetime.datetime.fromtimestamp(d, pytz.timezone('US/Pacific')) 

這裏的d變量存儲UTC時間作爲unix時間戳。

+0

這並不能解決用戶所處時區的問題。 –

+0

你說得對,我沒有仔細閱讀過去提出的網站和服務器。從Web瀏覽器獲取時間信息通常是使用Javascript完成的。這不應該被信任,但是沒有標準的HTTP響應頭來傳達用戶當前的時區,這是最好的猜測。 – bigendian

+0

根據我的經驗,代表客戶執行轉換的Web服務是最可靠的解決方案,並不是太令人頭疼的事情。該服務應該一次接受/返回多個值以減少請求的數量。 – wberry

0

您可以使用JavaScript(知道當地時間)將用戶輸入的時間更改爲UTC,然後再將數據發送到您的服務器。然後,以一種格式發送UTC,javascript可以將它從UTC轉換爲當地時間。

例如,日期爲UTC發送到服務器:

(new Date("November 11, 2011 23:13:42")).toUTCString() 

和UTC爲本地時間,渲染:

(new Date("October 17, 1986 15:29:13 UTC")).toLocaleString() 
+0

除非您的JavaScript VM中有可用的Olson數據庫,否則您無法在Web服務中實現本地化,這是行不通的。 – wberry

+0

@wberry我添加了一些例子。你的瀏覽器知道它在什麼時區。我想我沒有看到問題。 –

+0

許多客戶端實施都存在缺陷,並且不會針對過去和未來日期正確應用夏令時/夏令時政策。例如,如果是夏令時結束的一天,並且用戶明天輸入某個時間,則在某些客戶端,UTC時間將爲一個小時。 Windows上的Adobe Flash執行此操作。而作爲前端作者,這不是你的錯,這是你的問題。 – wberry