問題描述
假設美國加利福尼亞州的用戶選擇了日期、時間和時區:
Let's say user in CA, US picks up a date, time and timezone:
全球啤酒馬拉松將于 2013 年 8 月 15 日上午 10:00,UTC-08:00
中歐的另一位用戶打開顯示此日期和時間的頁面.他不想計算時間(啤酒已經很少了).他只想看看這個日期和時間:
Another user, in Central Europe opens the page where this date and time is displayed. He doesn't want to do time calculations (had few beers already). He just wants to see this date and time:
8/15/2013 19:00
鑒于瀏覽器接收到日期和時間信息,如加利福尼亞用戶輸入的那樣:
Given the browser receives the date and time information, as entered by user in California:
有沒有辦法,在 javascript,沒有外部網絡服務,進行正確的轉換?也就是說,要檢測到 UTC-08:00 上午 10 點實際上應該是 UTC-07:00 上午 10 點,因為它是夏令時.
Is there a way, in javascript, without external web services, to do a correct conversion? That is, to detect that 10am UTC-08:00 should actually be 10am UTC-07:00, since it is Daylight Saving.
也許我從一開始就理解錯了,但我不想讓進入的用戶思考他應該選擇UTC-08:00(PST)還是UTC-07:00(PDT).我假設由于 CA 的標準時區是 PST,因此人們不會在夏季轉向思考 PDT.還是他們?!
Maybe I got wrong understanding of this from the beginning, but I don't want to let the entering user to think whether he should choose UTC-08:00 (PST) or UTC-07:00 (PDT). I assume that since the standard timezone in CA is PST, people don't switch to thinking in PDT in summer time. Or do they?!
在中歐,標準日期為 UTC+01:00,夏令時日期為 UTC+02:00.因此,CA 和歐洲之間的差異應該是 9 小時,一年中的兩個時段除外,當一個或另一個區域在標準模式和夏令時模式之間切換時.
In central Europe, standard date is UTC+01:00, Daylight Saving date is UTC+02:00. So that difference between CA and Europe should be 9 hours, except for two periods in a year, when one or the other area switches between Standard and Daylight Saving modes.
更新:
經過更多思考和閱讀評論,我最需要的是:
After some more thinking and reading the comments, what I would ideally need is this:
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"
到目前為止,Guido Preite 建議的 moment.js/timezone 插件似乎能夠做到這一點(更多或少).
So far, it looks like the moment.js/timezone plugin, suggested by Guido Preite is capable of doing this (more or less).
任何其他方式,使用瀏覽器 API?
Any other way, using browser APIs?
推薦答案
有沒有辦法在沒有外部網絡服務的情況下在 javascript 中進行正確的轉換?也就是說,要檢測到 UTC-08:00 上午 10 點實際上應該是 UTC-07:00 上午 10 點,因為它是夏令時.
Is there a way, in javascript, without external web services, to do a correct conversion? That is, to detect that 10am UTC-08:00 should actually be 10am UTC-07:00, since it is Daylight Saving.
10:00-8 和 10:00-7 是兩個不同的時間點.它們分別等于 18:00Z 和 17:00Z (Z = UTC).當您根據偏移量進行測量時,夏令時不會進入圖片.永遠.
10:00-8 and 10:00-7 are two different moments in time. They are equal to 18:00Z and 17:00Z respectively (Z = UTC). When you are measuring in terms of an offset, daylight saving time does not enter the picture. Ever.
我假設由于 CA 的標準時區是 PST,因此人們不會在夏季轉而思考 PDT.還是他們?!
I assume that since the standard timezone in CA is PST, people don't switch to thinking in PDT in summer time. Or do they?!
一般來說,人們只會想到太平洋時間",這意味著冬季的 PST 和夏季的 PDT.但計算機更精確.當您看到 PST 時,它表示 UTC-8.當您看到 PDT 時,它表示 UTC-7.使用一種形式標注同時引用另一種形式的偏移量是無效的.
In general, people just think in "Pacific Time", and that means both PST in the winter, and PDT in the summer. But computers are more precise. When you see PST, it means UTC-8. When you see PDT, it means UTC-7. It would be invalid to label using one form while simultaneously referring to the offset of the other.
時區縮寫可能不明確.理想情況下,以編程方式引用區域時,您應該使用 IANA 區域名稱,例如 America/Los_Angeles
.但是,目前這在所有沒有庫的 JavaScript 運行時中是不可能的.(他們正在為此努力.)
Time zone abbreviations can be ambiguous. Ideally, when referencing the zone programmatically, you should use the IANA zone name, such as America/Los_Angeles
. However, this is not currently possible in all JavaScript runtimes without a library. (They are working on this though.)
在中歐,標準日期為 UTC+01:00,夏令時日期為 UTC+02:00.因此,CA 和歐洲之間的差異應該是 9 小時,一年中的兩個時段除外,當一個或另一個區域在標準模式和夏令時模式之間切換時.
In central Europe, standard date is UTC+01:00, Daylight Saving date is UTC+02:00. So that difference between CA and Europe should be 9 hours, except for two periods in a year, when one or the other area switches between Standard and Daylight Saving modes.
正確.它們可能相隔 8、9 或 10 小時.不過,它們切換的時間完全不同,所以不要試圖自己管理.
Correct. They could be either 8, 9, or 10 hours apart. They switch at completely different times though, so don't try to manage this yourself.
到目前為止,Guido Preite 建議的 moment.js/timezone 插件似乎能夠做到這一點(或多或少).
So far, it looks like the moment.js/timezone plugin, suggested by Guido Preite is capable of doing this (more or less).
Moment-timezone 是一個很棒的庫.但是,從您描述的情況來看,我認為您不需要像您想的那樣擔心時區轉換.看看你能不能遵循這個邏輯:
Moment-timezone is a great library. However, from the scenario you described, I don't think you need to worry about time zone conversion as much as you are thinking. See if you can follow this logic:
- 加利福尼亞的用戶在文本框中輸入日期和時間.
您將該文本框的值讀入字符串,然后將其解析為日期:
- The user in California enters a date and time into a textbox.
You read that textbox value into a string, and parse it into a date:
var dt = new Date("8/15/2013 10:00");
或使用 moment.js:
or using moment.js:
var m = moment("8/15/2013 10:00", "M/D/YYYY HH:mm");
因為這是在用戶的計算機上完成的,所以 JavaScript 會自動假定這是一個本地日期和時間.您無需提供任何偏移量或時區信息.
Because this is being done on the user's computer, JavaScript will automatically assume that this is a local date and time. You do not need to provide any offset or time zone information.
這確實意味著由于 DST 轉換,輸入的時間可能無效或不明確.事實上,JavaScript 在處理這個問題方面做得并不好——你會在不同的瀏覽器上得到不同的結果.如果你想明確,那么你會提供一個偏移量.
This does mean that because of the DST transitions that the time entered might be invalid or ambiguous. JavaScript doesn't do such a great job at handling that, in fact - you will get different results on different browsers. If you want to be unambiguous, then you would provide an offset.
// 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");
一旦你有了一個 Date
(或一個 moment
),你就可以評估它的 UTC 等效值:
Once you have a Date
(or a moment
), then you can evaluate its UTC equivalent:
var s = dt.toISOString(); // 2013-08-15T17:00:00Z
moment.js 也是一樣,但是你會有更好的瀏覽器支持:
it's the same with moment.js, but you will have better browser support:
var s = m.toISOString(); // 2013-08-15T17:00:00Z
您將該 UTC 值存儲在數據庫中.
You store that UTC value in your database.
另一個中歐用戶過來加載數據.
The other user in Central Europe comes along and loads the data.
您將其輸入到 JavaScript 中的 Date
或 moment
:
You feed it in to a Date
or moment
in JavaScript:
var dt = new Date("2013-08-15T17:00:00Z");
或者使用 moment.js(同樣,更好的瀏覽器支持)
or with moment.js (again, better browser support)
var m = moment("2013-08-15T17:00:00Z")
由于 JavaScript 知道本地計算機的時區規則,您現在可以顯示此日期,它將與中歐時區一起呈現:
Because JavaScript knows the time zone rules of the local computer, you can now display this date and it will be presented with the Central Europe time zone:
var s = dt.ToString(); // browser specific output
// ex: "Thu Aug 15 2013 19:00:00 GMT+0200 (Central Europe Daylight Time)"
或者配合moment.js,可以更好的控制輸出格式
or with moment.js, you can control the output format better
var s = m.format("DD/MM/YYYY HH:mm"); // "15/08/2013 19:00"
你也可以讓 moment.js 決定應該輸出什么本地化格式:
you could also let moment.js decide what localized format should be output:
var s = m.format("llll"); // "Thu, 15 Aug 2013 19:00"
總而言之 - 如果您只想在本地時區(可能是任何時區)之間進行轉換,那么您只需 Date
即可完成所有操作.Moment.js 將使解析和格式化變得更容易,但這不是絕對必需的.
To summarize - if you are only interested in converting to and from the local time zone (whatever zone that may be), then you can do it all with just Date
. Moment.js will make things easier for parsing and formatting, but it isn't absolutely required.
只有少數場景需要時區庫(例如 moment-timezone 或其他).
There are only a few scenarios that require a time zone library (such as moment-timezone or others).
您希望與非本地時區或 UTC 的區域進行轉換.
You want to convert to or from a zone that is not the local time zone or UTC.
您正在使用過去的日期,并且從那時起,時區規則或夏令時規則發生了變化,并且 您的日期在新規則下的解釋與舊規則不同.這有點技術性,但確實會發生.閱讀更多這里和這里.
You are working with dates that are in the past, and there has been a change to the time zone rules or daylight saving time rules since then, and you have dates that would be interpreted differently under the new rules than with the old ones. This is a bit technical, but it does happen. Read more here and here.
這篇關于如何跨時區正確轉換時間?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!