2013-08-02 35 views
12

比方說,用戶在CA,美國拿起一個日期,時間和時區:如何正確跨時區轉換時間?

全球啤酒馬拉松的起點上2013年8月15日上午10:00,UTC-08:00

另一個用戶,在中歐打開顯示此日期和時間的頁面。他不想做時間計算(已經很少有啤酒)。他只是希望看到此日期和時間:

2013年8月15日19:00

鑑於瀏覽器接收的日期和時間信息,在加州進入了用戶:

是有沒有辦法,在javascript,沒有外部網絡服務,要做一個正確的轉換?也就是說,爲了發現上午10點UTC-08:00實際上應該是UTC-07:00上午10點,因爲這是夏令時。

也許我從一開始就錯誤地理解了這一點,但我不想讓輸入的用戶考慮是否應該選擇UTC-08:00(PST)還是UTC-07:00(PDT)。我假設由於CA中的標準時區是PST,所以夏季時人們不會轉而思考PDT。或者他們?!

在中歐,標準的日期是UTC + 01:00,夏令時間爲UTC + 02:00。因此,CA和歐洲之間的差異應該是9小時,除了一年中的兩個時段,其中一個或另一個區域在標準模式和夏令時模式之間切換。

更新:

後一些更多的思考和閱讀的意見,我會非常需要的是這樣的:

var utcOffset = f('2013-08-15T10:00', 'America/Los_Angeles'); 
// utcOffset == "-07:00" 
var utcOffset = f('2013-11-15T10:00', 'America/Los_Angeles'); 
// utcOffset == "-08:00" 

到目前爲止,它看起來像moment.js/timezone plugin,由Guido Preite建議是能夠做到這一點(或多或少)。

任何其他方式,使用瀏覽器API?

+1

check'Moment。js'和'Moment Timezone' http://momentjs.com/timezone/ –

+0

我已經使用了moment.js。時區擴展看起來很有希望。生成的時區文件包含夏令時轉換數據。經過快速測試後,它能夠正確調整輸入的時間。因此,這看起來像瀏覽器不能告訴「嘿,爲了這個日期,你必須使用這個UTC抵消,因爲在那個日期,有夏令時」? – rdamborsky

回答

19

有沒有一種方法,在JavaScript中,沒有外部Web服務,做正確的轉換?也就是說,爲了發現上午10點UTC-08:00實際上應該是UTC-07:00上午10點,因爲這是夏令時。

10:00-8和10:00-7是兩個不同的時刻。它們分別等於18:00Z和17:00Z(Z = UTC)。在按照偏移量進行測量時,夏令時不會輸入圖片。永遠。

我假設由於CA中的標準時區是PST,因此人們在夏令時並不轉換到PDT思維。或者他們?!

一般而言,人們只是在「太平洋時間」中思考,這意味着冬季PST和夏季PDT。但電腦更精確。當你看到PST時,意味着UTC-8。當你看到PDT時,意味着UTC-7。使用一種形式進行標籤並同時提及另一種形式的偏移量將是無效的。

時區縮寫can be ambiguous。理想情況下,以編程方式引用區域時,應使用IANA區域名稱,如America/Los_Angeles。但是,這在目前沒有庫的所有JavaScript運行時都是不可能的。 (They are working on this though

在中歐,標準日期是UTC + 01:00,夏令時是UTC + 02:00。因此,CA和歐洲之間的差異應該是9小時,除了一年中的兩個時段,其中一個或另一個區域在標準模式和夏令時模式之間切換。

正確。他們可能會相隔8,9或10個小時。儘管它們在完全不同的時間切換,所以不要試圖自己管理它。

到目前爲止,它看起來像是由Guido Preite建議的moment.js/timezone插件能夠做到這一點(或多或少)。

Moment-timezone是一個偉大的圖書館。然而,從你描述的情景來看,我認爲你不必擔心時區轉換就像你想的那樣多。看看你是否可以遵循這個邏輯:

  1. 加利福尼亞州的用戶在文本框中輸入日期和時間。
  2. 你看的文本框的值轉換成字符串,並將其解析爲一個日期:

    var dt = new Date("8/15/2013 10:00"); 
    

    或使用moment.js:

    var m = moment("8/15/2013 10:00", "M/D/YYYY HH:mm"); 
    
  3. 因爲這是正在用戶的計算機上完成,JavaScript會自動假定這是一個本地日期和時間。您不需要提供任何偏移或時區信息。

  4. 這確實意味着由於DST轉換,輸入的時間可能無效或不明確。 JavaScript在處理這件事上做得並不好,事實上 - 在不同的瀏覽器上你會得到不同的結果。如果你想明確,那麼你會提供一個偏移量。

    // PST 
    var dt = new Date("3/11/2013 1:00 UTC-08:00"); 
    
    // PDT 
    var dt = new Date("3/11/2013 1:00 UTC-07:00"); 
    
  5. 一旦你有一個Date(或moment),那麼你就可以評估其UTC相當於:

    var s = dt.toISOString(); // 2013-08-15T17:00:00Z 
    

    它與moment.js相同,但你將有更好的瀏覽器支持:

    var s = m.toISOString(); // 2013-08-15T17:00:00Z 
    
  6. 您將該值存儲在數據庫中。

  7. 中歐的其他用戶出現並加載數據。

  8. 你在餵它一個Datemoment在JavaScript:

    var dt = new Date("2013-08-15T17:00:00Z"); 
    

    或moment.js(再次,更好的瀏覽器支持)

    var m = moment("2013-08-15T17:00:00Z") 
    
  9. 因爲JavaScript知道時區本地計算機的規則,您現在可以顯示該日期,並且將顯示中歐時區:

    var s = dt.ToString(); // browser specific output 
    // ex: "Thu Aug 15 2013 19:00:00 GMT+0200 (Central Europe Daylight Time)" 
    

    或moment.js,你可以控制輸出格式更好

    var s = m.format("DD/MM/YYYY HH:mm"); // "15/08/2013 19:00" 
    

    ,你也可以讓moment.js決定什麼本地化的格式應該是輸出:

    var s = m.format("llll"); // "Thu, 15 Aug 2013 19:00" 
    

要總結 - 如果你只在轉換和從本地時區(無論區域可能)感興趣,那麼你可以只用Date做這一切。 Moment.js會使分析和格式化變得更容易,但並非絕對必需。

需要時區庫(如時刻時區或其他)只有幾個場景。

  • 你要轉換,或是從本地時區或UTC的區域。

  • 您的日期是在過去的工作,出現了變化,因爲隨後的時區規則和夏令時規則,你必須將不同下進行解釋日期新的規則比舊的規則。這有點技術性,但確實發生了。更多herehere

+0

感謝馬特,瞭解詳盡的信息,鏈接和指南。我的場景恰好是您指出的第一個場景:轉換不是來自本地時區。也就是說,輸入日期和時間的用戶也會輸入與該時間相關的時區。這並不一定是用戶所在的時區。我想我應該在問題中更清楚地說明這一點。 – rdamborsky

+0

我會說,JavaScript,「萬維網」的語言編程沒有內置時間轉換/時區工具 –

1

默認的構造函數創建的本地時間實例

var localDate = new Date(); 

我現在不能測試,但你應該能夠提供您的日期時間(作爲參數構造函數)..

var eventDate = [SOMEDATE]; 
var localDate = new Date(eventDate); 

..和,那麼你應該能夠調用Date對象的功能,如得到月,這在當地時區返回的數據。 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date

注1:截至書面無服務器=沒有服務器|數據庫呢?如果有的話,日期應該保存爲UTC的分貝數據,並將其作爲每個用戶的本地時間加載......這樣您就不必擔心轉換。

注2:這個問題有一些代碼展示瞭如何獲取時區差異:How to get the exact local time of client?

+0

是的,這通常工作正常。問題在於用戶輸入明確的時區以用於保存的日期。想象一下,您在提交07/20/2013 10:00 UTC-08:00的同時將其視爲CA中的時間。但是這個信息是不正確的,因爲在給定的日期-07:00應該用於utc偏移量。這就是我需要檢測和解決的問題。一旦日期正確保存,存儲/檢索部分就很容易。我想避免在進入階段的標準/夏令時之間做出決定。 – rdamborsky

0

我開發了一個基於其他例子這種解決方案希望這對你的作品!可在jsfiddle上獲得。

/* 
* Author: Mohammad M. AlBanna 
* Website: MBanna.me 
* Description: Get the current time in different time zone 
*/ 

//Check daylight saving time prototype 
Date.prototype.stdTimezoneOffset = function() { 
    var jan = new Date(this.getFullYear(), 0, 1); 
    var jul = new Date(this.getFullYear(), 6, 1); 
    return Math.max(jan.getTimezoneOffset(), jul.getTimezoneOffset()); 
} 

Date.prototype.dst = function() { 
    return this.getTimezoneOffset() < this.stdTimezoneOffset(); 
} 

var today = new Date(); 
var isDST = today.dst() ? true : false; 
var pstOffset = isDST ? 7 : 8; 
var cstOffset = isDST ? 5 : 6; 
var estOffset = isDST ? 4 : 5; 
var gmtOffset = 1; 

pstOffset = pstOffset * 60 * 60 * 1000; 
cstOffset = cstOffset * 60 * 60 * 1000; 
estOffset = estOffset * 60 * 60 * 1000; 
gmtOffset = gmtOffset * 60 * 60 * 1000; 

var todayMillis = today.getTime(); 
var timeZoneOffset = (today.getTimezoneOffset() * 60 * 1000); 

var curretPST = todayMillis - pstOffset; 
var curretCST = todayMillis - cstOffset; 
var curretEST = todayMillis - estOffset; 
var curretGMT = todayMillis - gmtOffset; 

addP("PST Time : " + new Date(curretPST).toUTCString()); 
addP("CST Time : " + new Date(curretCST).toUTCString()); 
addP("EST Time : " + new Date(curretEST).toUTCString()); 
addP("GMT Time : " + new Date(curretGMT).toUTCString()); 
addP("Local Time : " + new Date(today.getTime() - timeZoneOffset).toUTCString()); 

function addP(value){ 
    var p = document.createElement("p"); 
    p.innerHTML = value; 
    document.body.appendChild(p); 
}