Làm thế nào để bạn chuyển đổi một ngày JavaScript sang UTC?


590

Giả sử người dùng trang web của bạn nhập vào một phạm vi ngày.

2009-1-1 to 2009-1-3

Bạn cần gửi ngày này đến một máy chủ để xử lý, nhưng máy chủ hy vọng tất cả các ngày và giờ sẽ ở trong UTC.

Bây giờ giả sử người dùng đang ở Alaska hoặc Hawaii hoặc Fiji. Vì chúng ở múi giờ khá khác so với UTC, nên phạm vi ngày cần được chuyển đổi thành một thứ như thế này:

2009-1-1T8:00:00 to 2009-1-4T7:59:59

Sử dụng đối tượng Ngày JavaScript, bạn sẽ chuyển đổi phạm vi ngày "cục bộ hóa" đầu tiên thành thứ gì đó mà máy chủ sẽ hiểu?


10
đã phục hồi điều này bởi vì đây là lần truy cập hàng đầu của Google đối với tôi và các trình duyệt mới hơn có hỗ trợ tích hợp cho chuỗi ngày UTC.
jcomeau_ictx

4
Tôi đã cập nhật câu trả lời được chấp nhận để làm nổi bật phương thức ECMAscript 5 toISOString () mới. Xem stackoverflow.com/a/11957822/19112
dthrasher

5
Vì vậy, trong năm 2015 tôi phải lộn xộn với ngày xâu chuỗi và phân tích cú pháp? nực cười!
Bộ công cụ

2
Tất nhiên là bạn có. Bạn không bao giờ có thể dựa vào người khác làm việc cho bạn :-P Ít nhất cho đến khi thế giới ngừng sử dụng múi giờ và bắt đầu bỏ qua ngày và giờ.
Erenor Paz

4
"Stardates", tốt nhất là.
Michael Daw

Câu trả lời:


370

Các toISOString()phương thức trả về một chuỗi trong định dạng ISO mở rộng đơn giản hóa ( ISO 8601 ), mà luôn luôn là 24 hoặc 27 ký tự ( YYYY-MM-DDTHH:mm:ss.sssZhoặc ±YYYYYY-MM-DDTHH:mm:ss.sssZ, tương ứng). Múi giờ luôn là độ lệch UTC bằng 0, được biểu thị bằng hậu tố " Z".

Nguồn: tài liệu web MDN

Định dạng bạn cần được tạo bằng .toISOString()phương thức. Đối với các trình duyệt cũ hơn (tức là 8 trở xuống), vốn không hỗ trợ phương pháp này, có thể tìm thấy shim ở đây :

Điều này sẽ cung cấp cho bạn khả năng để làm những gì bạn cần:

var isoDate = new Date('yourdatehere').toISOString();

Đối với công việc múi giờ, múi giờ khoảnh khắc và giây là những công cụ thực sự vô giá ... đặc biệt là để điều hướng múi giờ giữa javascript của máy khách và máy chủ.


81
trên thực tế, điều này chuyển đổi đối tượng ngày thành một chuỗi, sẽ không thể thực hiện các hoạt động ngày tiếp theo trên
chuỗi

2
@TheRebel, trường hợp sử dụng được đưa ra là anh ta cần gửi cho máy chủ một chuỗi được định dạng.
Sẽ nghiêm khắc

28
@ Sẽ, bạn hoàn toàn đúng, nhưng - giống như hầu hết những người xem ở đây tôi giả sử - Tôi đã đến đây dựa trên tiêu đề, tìm kiếm ngày JS chung để chuyển đổi UTC, vì vậy tôi nghĩ thật hữu ích khi đề cập đến nó ở đây :)
orszaczky

4
Hãy cảnh giác khi sử dụng phương pháp này! Nó không tạo ra ngày UTC - nó định dạng dữ liệu ngày hiện tại giống như định dạng UTC và cung cấp cho nó múi giờ "Z". Điều này là sai 99% thời gian! Bạn phải chuyển đổi ngày thành múi giờ GMT trước khi sử dụng phương pháp này!
dùng1944491

5
@ user1944491 Tôi không nghĩ điều này là chính xác. Theo các tài liệu MDN, toISOStringkhông chuyển đổi chính xác sang UTC [toISOString] returns a string in simplified extended ISO format ... The timezone is always zero UTC offsetNgoài ra, trong ví dụ họ hiển thị phần bù được tính khi toISOString được gọi
FFF

560

Đơn giản và ngu ngốc

var date = new Date(); 
var now_utc =  Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(),
 date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds());

 return new Date(now_utc);

85
Tôi thích ý tưởng của bạn và đã thực hiện một phương pháp tôi đã sử dụng nhiều lần. function convertDateToUTC(date) { return new Date(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds()); }
Tim

21
Mã ngắn nhất mà tôi đã đưa ra để có được ngày và thời gian UTC là bằng cách tắt múi giờ:new Date(new Date().toUTCString().substr(0, 25))
joelvh

17
Lưu ý rằng getUTCMonth () trả về các giá trị 0 đến 11. Vì vậy, nếu bạn đang cần tháng theo số thay vì một chuỗi, nó sẽ giúp +1 cho giá trị.
Talvi Watia

19
Thật vô nghĩa. Ngày mới sẽ có một giá trị khác với bạn thực sự muốn. Chỉ cần sử dụng now.toUTCSTring()thay vì (sai) now_utc.toString().
Bergi

22
Tôi sẽ không sử dụng điều này - bằng cách sử dụng Ngày mới (), bạn sẽ có được múi giờ của trình duyệt. trong Chrome 29 và IE10, ngày + giờ dường như là chính xác, nhưng múi giờ được đặt thành múi giờ của trình duyệt, điều này có thể gây ra sự cố ...
Sean

207

Đây là phương pháp của tôi:

var now = new Date();
var utc = new Date(now.getTime() + now.getTimezoneOffset() * 60000);

utcĐối tượng kết quả không thực sự là một ngày UTC, mà là một ngày địa phương được thay đổi để phù hợp với thời gian UTC (xem bình luận). Tuy nhiên, trong thực tế nó làm công việc.


Tôi đã xem xét vấn đề đó khi tôi nhận ra rằng Date.now()mang lại thời gian địa phương chứ không phải thời gian UTC, và giải pháp này có vẻ đơn giản nhất đối với tôi. Ít nhất là trong trường hợp của tôi, nơi tôi muốn có thời gian UNIX và không phải là một chuỗi được định dạng độc đáo. (sự khác biệt duy nhất là tôi đã nhân lên 60 * 1000chỉ để rõ ràng hơn :))
Timothée Boucher

18
Thêm 60000 * Date.getTimezone Offerset () là không chính xác! Trước tiên, bạn phải nghĩ về tất cả các Ngày / Giờ đã là UTC với công cụ sửa đổi múi giờ cho mục đích hiển thị. Các trình duyệt có thể khác nhau, tuy nhiên, Date.getTime () trả về số mili giây kể từ 1970-01-01. Nếu bạn tạo Ngày mới bằng số này, ví dụ: Ngày mới (Date.getTime ()); nó sẽ là UTC , tuy nhiên khi bạn hiển thị nó (ví dụ: thông qua bảng điều khiển công cụ chrome dev), nó sẽ xuất hiện là múi giờ địa phương của bạn.
Aaron Hoffman

15
Trong trình duyệt của tôi, điều này tạo ra một DateTime không phải là UTC. Tuy nhiên, khi được hiển thị trong trình duyệt của tôi, điều này sẽ hiển thị DateTime trong múi giờ địa phương của tôi, đó sẽ là thời gian UTC chính xác nếu thông tin múi giờ bị bỏ qua.
Aaron Hoffman

Gotcha, điểm thú vị. Hãy so sánh now.toString()với utc.toString(): không có thay đổi múi giờ, nhưng thay đổi thời gian, đó là một điều hoàn toàn khác. Tuy nhiên, một giải pháp sạch hơn sẽ phức tạp hơn (tôi đoán vậy) và mã này thực hiện công việc trong phần lớn các trường hợp, miễn là người ta không xử lý thêm các múi giờ. Nó làm tôi nhớ về việc đấm vịt : điều khác biệt nhưng được thực hiện để hành xử giống nhau. Cũng lưu ý mã DrunkCoder có cùng một vấn đề.
Gras Double

4
Câu trả lời này cho thấy một triển khai phổ biến khác của "dịch chuyển kỷ nguyên" rất nguy hiểm khi cô lập, vì nó có thể thất bại trong các trường hợp gần như chuyển tiếp DST. Không được khuyến khích.
Matt Johnson-Pint

25
Date.prototype.toUTCArray= function(){
    var D= this;
    return [D.getUTCFullYear(), D.getUTCMonth(), D.getUTCDate(), D.getUTCHours(),
    D.getUTCMinutes(), D.getUTCSeconds()];
}

Date.prototype.toISO= function(){
    var tem, A= this.toUTCArray(), i= 0;
    A[1]+= 1;
    while(i++<7){
        tem= A[i];
        if(tem<10) A[i]= '0'+tem;
    }
    return A.splice(0, 3).join('-')+'T'+A.join(':');    
}

Điều này hoạt động tốt. Tôi chỉ cần thay thế "-" trong ngày nguồn của mình thành "/" để tạo ngày JavaScript, sau đó tôi có thể gọi hàm toISO () của bạn để có đầu ra chính xác.
dthrasher

công việc này thật tuyệt Bạn cũng có thể cung cấp kết quả vào jQuery $ .parseDate (...) để lấy lại một đối tượng ngày đã được chuyển sang UTC.
Brian Ellis

23

Chuyển đổi sang ISO mà không thay đổi ngày / giờ

var now = new Date(); // Fri Feb 20 2015 19:29:31 GMT+0530 (India Standard Time) 
var isoDate = new Date(now.getTime() - now.getTimezoneOffset() * 60000).toISOString();
//OUTPUT : 2015-02-20T19:29:31.238Z

Chuyển đổi sang ISO với thay đổi ngày / giờ (ngày / giờ sẽ được thay đổi)

isoDate = new Date(now).toISOString();
//OUTPUT : 2015-02-20T13:59:31.238Z 

Liên kết Fiddle


Vì vậy, đây là loại giả mạo UTC? Tôi thay đổi ngày địa phương của mình và tôi thành công để gửi đến máy chủ ngày và giờ mà tôi thực sự thấy trên đồng hồ PC của mình. Ồ Dù sao thì tốt hơn là phân tầng và phân tích cú pháp
Bộ công cụ

Ngoài ra, bạn không cần .toISOString (), bạn chỉ có thể gửi isoDate đến máy chủ
Bộ công cụ

.toISOString () rất đơn giản và dễ hiểu, việc lấy ngày ra khỏi nó sẽ là một bước bổ sung (isoDate không phải là một hàm).
lăn

Bạn không cần phải thêm phần bù thay vì trừ nó? Tham khảo stackoverflow.com/a/11964609/832230
Acumus

@ABB Nếu độ lệch múi giờ hiện tại là + ve thì chúng ta nên trừ nó (trong trường hợp của chúng tôi IST là +5: 30) nếu không thì thêm.
RollerCosta

18

Các trình duyệt có thể khác nhau và bạn cũng nên nhớ không tin tưởng bất kỳ thông tin nào do khách hàng tạo ra, như đã nói, câu lệnh dưới đây hoạt động với tôi (Google Chrome v24 trên Mac OS X 10.8.2)

var utcDate = new Date(new Date().getTime());


chỉnh sửa: "Làm thế nào khác với chỉ này new Date()?" xem tại đây: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date

  • Nếu không có đối số nào được cung cấp, hàm tạo sẽ tạo một đối tượng Ngày JavaScript cho ngày và giờ hiện tại theo cài đặt hệ thống.
  • Lưu ý: Trong đó Date được gọi là hàm tạo với nhiều hơn một đối số, các đối số được chỉ định biểu thị giờ địa phương. Nếu muốn UTC, hãy sử dụng Ngày mới ( Date.UTC (...) ) với cùng các đối số. (lưu ý: Date.UTC () trả về số mili giây kể từ 1970-01-01 00:00:00 UTC)

Thêm 60000 * Date.getTimezone Offerset () như các câu trả lời trước đã nêu là không chính xác. Trước tiên, bạn phải nghĩ về tất cả các Ngày / Giờ đã là UTC với công cụ sửa đổi múi giờ cho mục đích hiển thị.

Một lần nữa, các trình duyệt có thể khác nhau, tuy nhiên, Date.getTime () trả về số mili giây kể từ 1970-01-01 UTC / GMT. Nếu bạn tạo một Ngày mới bằng cách sử dụng số này như tôi đã làm ở trên, đó sẽ là UTC / GMT. Tuy nhiên, nếu bạn hiển thị nó bằng cách gọi .toString () thì nó sẽ xuất hiện ở múi giờ địa phương của bạn vì .toString () sử dụng múi giờ địa phương của bạn chứ không phải múi giờ của đối tượng Date mà nó được gọi.

Tôi cũng đã thấy rằng nếu bạn gọi .getTimezone Offerset () vào một ngày, nó sẽ trả về múi giờ địa phương của bạn, chứ không phải múi giờ của đối tượng ngày mà bạn gọi nó (tuy nhiên tôi không thể xác minh đây là tiêu chuẩn).

Trong trình duyệt của tôi, việc thêm 60000 * Date.getTimezone Offerset () sẽ tạo ra DateTime không phảiUTC . Tuy nhiên, khi được hiển thị trong trình duyệt của tôi (ví dụ: .toString ()), nó sẽ hiển thị DateTime trong múi giờ địa phương của tôi, đó sẽ là thời gian UTC chính xác nếu thông tin múi giờ bị bỏ qua.


11
Tôi mới chạy mã này trên Fx và Chrome, nó dường như không hoạt động: kết quả hoàn toàn giống với từ new Date(), cả dấu thời gian và múi giờ đều không thay đổi
Gras Double

3
Đó là bởi vì dấu thời gian là ít múi giờ. new Date().getTime()sẽ luôn trả về dấu thời gian là bất khả tri đối với múi giờ. Không có dấu thời gian liên quan đến nó cho đến khi bạn cố gắng định dạng nó thành một cái gì đó ngoài số mili giây kể từ thời kỳ Unix.
frontendbeauty

7
Theo như tôi có thể nói new Date(new Date().getTime())trả về chính xác cùng giá trị như new Date(). Bạn có thể giải thích theo nghĩa nào câu trả lời của bạn cung cấp một giá trị khác biệt từ new Date()?
Kirk Woll

Tôi đang đăng giá trị này lên máy chủ của tôi new Date("5/19/2014").getTime(). Hàm tạo ngày đã tạo một ngày có độ lệch +7. Trên máy chủ (C #), tôi thêm giá trị được đăng dưới dạng mili giây vào unix epoch new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddMilliseconds(1401087600000). Kết quả là 5/19/2014 7:00:00 AM. Vì vậy, có vẻ như getTime () đưa ra số mili giây bao gồm cả phần bù UTC của tôi.
xr280xr

1
Có rất nhiều ý kiến ​​phàn nàn rằng new Date(new Date().getTime())không hoạt động. Tôi có thể xác nhận rằng new Date(Date.UTC(2019, 8, 27, 0, 0, 0))nó thực sự tạo ra thời gian UTC. Nếu bạn không sử dụng, Date.UTC(...)bạn sẽ nhận được ngày trong UTC bù theo múi giờ của mình.
Alex Barker

15
var myDate = new Date(); // Set this to your date in whichever timezone.
var utcDate = myDate.toUTCString();

1
Đối tượng ngày cần thực sự được đặt thành một ngày. Trên đây chỉ là một ví dụ.
James Skidmore

5
Bây giờ, nó trả về "Thu, 04 tháng 6 năm 2009 04:10:56 GMT", không phải là định dạng ISO được yêu cầu trong OP.
nickf

4
Điều này biến nó thành một chuỗi, không phải là một ngày
Anthony

2
không, thực sự nó phải là một chuỗi đại diện cho một ngày theo OP.
jcomeau_ictx

3
Sau khi chuyển đổi sang UTC, nó sẽ trở lại ở định dạng chuỗi, sau đó làm thế nào để truy cập các phương thức như getMonth (), getDate (), v.v.
Sandeep sand

10

Một giải pháp khác để chuyển đổi sang UTC và giữ nó làm đối tượng ngày: (Nó hoạt động bằng cách xóa phần 'GMT' khỏi cuối chuỗi được định dạng, sau đó đưa nó trở lại vào hàm tạo Ngày)

var now = new Date();
var now_utc = new Date(now.toUTCString().slice(0, -4));

Tôi cần phải làm điều này để giao diện với một thư viện bộ chọn datetime. Nhưng nói chung, đó là một ý tưởng tồi để làm việc với ngày theo cách này.

Người dùng thường muốn làm việc với datetimes trong giờ địa phương của họ, vì vậy bạn hãy cập nhật mã phía máy chủ để phân tích chính xác chuỗi thời gian, sau đó chuyển đổi sang UTC (tùy chọn tốt nhất) hoặc bạn chuyển đổi sang phía máy khách chuỗi UTC trước khi gửi đến máy chủ (như trong câu trả lời của Will Stern)


7

Bạn đang cố gắng chuyển đổi ngày thành một chuỗi như vậy?

Tôi sẽ tạo một chức năng để làm điều đó, và mặc dù nó hơi gây tranh cãi, hãy thêm nó vào nguyên mẫu Date. Nếu bạn không thoải mái với việc đó, thì bạn có thể đặt nó dưới dạng một hàm độc lập, chuyển ngày làm tham số.

Date.prototype.getISOString = function() {
    var zone = '', temp = -this.getTimezoneOffset() / 60 * 100;
    if (temp >= 0) zone += "+";
    zone += (Math.abs(temp) < 100 ? "00" : (Math.abs(temp) < 1000 ? "0" : "")) + temp;

    // "2009-6-4T14:7:32+10:00"
    return this.getFullYear()   // 2009
         + "-"
         + (this.getMonth() + 1) // 6
         + "-"
         + this.getDate()       // 4
         + "T"
         + this.getHours()      // 14
         + ":"
         + this.getMinutes()    // 7
         + ":"
         + this.getSeconds()    // 32
         + zone.substr(0, 3)    // +10
         + ":"
         + String(temp).substr(-2) // 00
    ;
};

Nếu bạn cần nó trong thời gian UTC, chỉ cần thay thế tất cả các hàm get * bằng getUTC *, ví dụ: getUTCFullYear, getUTCMonth, getUTCHours ... và sau đó chỉ cần thêm "nắp: 00" vào cuối thay vì bù múi giờ của người dùng.


1
Đây là ví dụ đầu tiên tôi thấy rằng cố gắng xử lý bù múi giờ, vì vậy +1 cho điều đó. Tuy nhiên, tôi đã tìm thấy một vài điều với nó - temp.substr (-2) gây ra lỗi vì đó là một số, không phải là một chuỗi, vì vậy bạn cần phải làm một cái gì đó như "temp = '' + temp;" đầu tiên, để biến nó thành một chuỗi. Ngoài ra, tôi thích ngày ISO không đệm của mình - Tôi nghĩ rằng điều này làm cho chúng chuẩn hơn.
Mick Sear

@Mick - Tôi đã cập nhật để sửa lỗi đó. Tôi đã sử dụng String(temp)vì cách khác ( "" + temp) được báo cáo là lỗi JSLint những ngày này.
nickf

Điều này hiện được chuẩn hóa như toISOStringphương pháp
Bergi

7
date = '2012-07-28'; stringdate = new Date(date).toISOString();

nên làm việc trong hầu hết các trình duyệt mới hơn. nó trở lại 2012-07-28T00:00:00.000Ztrên Firefox 6.0


7

Đề xuất của tôi khi làm việc với ngày là phân tích ngày thành các trường riêng lẻ từ đầu vào của người dùng. Bạn có thể sử dụng nó như một chuỗi đầy đủ, nhưng bạn đang chơi với lửa.

JavaScript có thể xử lý hai ngày bằng nhau ở các định dạng khác nhau khác nhau.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/parse

Không bao giờ làm bất cứ điều gì như:

new Date('date as text');

Khi bạn đã phân tích ngày của mình vào các trường riêng lẻ từ đầu vào của người dùng, hãy tạo một đối tượng ngày. Khi đối tượng ngày được tạo, chuyển đổi nó thành UTC bằng cách thêm phần bù múi giờ. Tôi không thể nhấn mạnh tầm quan trọng của việc sử dụng phần bù từ đối tượng ngày do DST (tuy nhiên đó là một cuộc thảo luận khác để cho biết lý do tại sao).

var year = getFullYear('date as text');
var month = getMonth('date as text');
var dayOfMonth = getDate('date as text');

var date = new Date(year, month, dayOfMonth);

var offsetInMs = ((date.getTimezoneOffset() * 60)  // Seconds
                 * 1000);                          //  Milliseconds

var utcDate = new Date(date.getTime + offsetInMs);

Bây giờ bạn có thể chuyển ngày đến máy chủ trong thời gian UTC. Một lần nữa tôi rất khuyến khích không sử dụng bất kỳ chuỗi ngày nào. Hoặc chuyển nó đến máy chủ được chia thành mức độ chi tiết thấp nhất bạn cần, ví dụ như năm, tháng, ngày, phút hoặc dưới dạng giá trị như mili giây từ kỷ nguyên unix.


FYI getYear đang bị xóa khỏi tiêu chuẩn web developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/
Kẻ

6

Nếu bạn đang xử lý ngày nhiều, thì đáng để sử dụng khoảnh khắc.js ( http://momentjs.com ). Phương pháp để chuyển đổi sang UTC sẽ là:

moment(yourTime).utc()

Bạn có thể sử dụng định dạng để thay đổi ngày của bạn thành bất kỳ định dạng nào bạn muốn:

moment(yourTime).utc().format("YYYY-MM-DD")

Cũng có các tùy chọn bù trừ nhưng có một thư viện bổ sung để xử lý múi giờ ( http://momentjs.com/timezone/ ). Việc chuyển đổi thời gian sẽ đơn giản như sau:

moment.tz(yourUTCTime, "America/New_York")

sự khác biệt giữa moment(yourTime).utc()moment.utc(yourTime)? Tôi thường sử dụng sau này.
ps0604

5

Giải pháp của tôi giữ cho ngày giống nhau bất kể múi giờ nào được đặt ở phía máy khách. Có lẽ ai đó sẽ thấy nó hữu ích.

Trường hợp sử dụng của tôi:

Tôi đang tạo một ứng dụng việc cần làm, nơi bạn đặt ngày thực hiện nhiệm vụ của mình. Ngày này sẽ không đổi cho dù bạn ở múi giờ nào.

Thí dụ. Bạn muốn gọi cho bạn mình vào lúc 8 giờ sáng ngày 25 tháng Sáu.

Bạn tạo nhiệm vụ này 5 ngày trước (ngày 20 tháng 6) khi bạn ở Trung Quốc.

Sau đó, cùng ngày, bạn bay đến New York trong vài ngày.

Sau đó, vào ngày 25 tháng 6, khi bạn vẫn ở New York, bạn thức dậy lúc 7:30 sáng (có nghĩa là bạn sẽ nhận được thông báo nhiệm vụ trong 30 phút (ngay cả lúc 1:30 chiều tại Trung Quốc, nơi bạn đang ở khi tạo ra bài tập)

Vì vậy, nhiệm vụ là bỏ qua múi giờ. Nó có nghĩa là 'Tôi muốn làm điều đó lúc 8 giờ sáng ở bất kỳ múi giờ nào tôi sẽ ở'.

Những gì tôi làm là hãy nói 'Tôi cho rằng bạn luôn ở múi giờ Luân Đôn - UTC'.

Điều đó có nghĩa là - khi người dùng chọn một số ngày trong Múi giờ của anh ấy / tôi - tôi chuyển đổi ngày này thành cùng một ngày trong UTC. I E. Bạn chọn 8 giờ sáng ở Trung Quốc, nhưng tôi chuyển đổi thành 8 giờ sáng ở UTC.

Sau đó - lần tới khi bạn mở ứng dụng - Tôi đọc ngày được lưu trong UTC và chuyển đổi nó thành cùng ngày trong múi giờ hiện tại của bạn - ví dụ: Tôi chuyển đổi 8 giờ sáng ở UTC sang 8 giờ sáng ở múi giờ New York.

Giải pháp này có nghĩa là ngày có thể có ý nghĩa khác tùy thuộc vào vị trí của bạn khi đặt nó và nơi bạn đang đọc nó, nhưng nó vẫn không đổi theo cách mà nó "cảm thấy" giống như bạn luôn ở trong cùng múi giờ.

Hãy viết một số mã:

Đầu tiên - chúng tôi có 2 chức năng chính để chuyển đổi từ / sang UTC bỏ qua múi giờ:

export function convertLocalDateToUTCIgnoringTimezone(date: Date) {
  const timestamp = Date.UTC(
    date.getFullYear(),
    date.getMonth(),
    date.getDate(),
    date.getHours(),
    date.getMinutes(),
    date.getSeconds(),
    date.getMilliseconds(),
  );

  return new Date(timestamp);
}

export function convertUTCToLocalDateIgnoringTimezone(utcDate: Date) {
  return new Date(
    utcDate.getUTCFullYear(),
    utcDate.getUTCMonth(),
    utcDate.getUTCDate(),
    utcDate.getUTCHours(),
    utcDate.getUTCMinutes(),
    utcDate.getUTCSeconds(),
    utcDate.getUTCMilliseconds(),
  );
}

Sau đó, tôi lưu / đọc ngày này như:

function saveTaskDate(localDate: Date) {
  // I convert your local calendar date so it looks like you've picked it being in UTC somewhere around London
  const utcDate = convertLocalDateToUTCIgnoringTimezone(localDate);
  api.saveTaskDate(utcDate);
}

function readTaskDate(taskUtcDate: Date) {
  // I convert this UTC date to 'look in your local timezone' as if you were now in UTC somewhere around london
  const localDateWithSameDayAsUTC = convertUTCToLocalDateIgnoringTimezone(taskUtcDate);

  // this date will have the same calendar day as the one you've picked previously
  // no matter where you were saving it and where you are now
}

4

Tôi mới phát hiện ra rằng phiên bản 1.2.3 của date.format.js của Steven Levithan thực hiện đúng như những gì tôi muốn. Nó cho phép bạn cung cấp một chuỗi định dạng cho một ngày JavaScript và sẽ chuyển đổi từ giờ địa phương sang UTC. Đây là mã tôi đang sử dụng:

// JavaScript dates don't like hyphens!    
var rectifiedDateText = dateText.replace(/-/g, "/");
var d = new Date(rectifiedDateText);

// Using a predefined mask from date.format.js.
var convertedDate = dateFormat(d, 'isoUtcDateTime'); 

9
Đây dường như không phải là câu trả lời tốt nhất cho câu hỏi của bạn. Bạn nên xem xét lại một cái gì đó trực tiếp trả lời câu hỏi của bạn hoặc hỏi câu hỏi của bạn khác nhau.
hitautodesturation

1
Tôi tình cờ CỐ ĐỊNH tập lệnh chính xác này (và phiên bản) vì nó không đủ cho IE7 và Firefox.
Barbarrosa

4

Tôi đã tìm thấy Plugin Toàn cầu hóa jQuery phân tích cú pháp ngày để hoạt động tốt nhất. Các phương thức khác có vấn đề về trình duyệt chéo và những thứ như date.js đã không được cập nhật trong một thời gian dài.

Bạn cũng không cần datePicker trên trang. Bạn chỉ có thể gọi một cái gì đó tương tự như ví dụ được đưa ra trong các tài liệu:

$.parseDate('yy-mm-dd', '2007-01-26');

1
Chỉ vì thứ gì đó chưa được cập nhật, không có nghĩa là bạn không nên sử dụng nó. Date.js đã hoạt động rất hoàn hảo trong nhiều năm, do đó không cần cập nhật. Đối tượng ngày JS và các định dạng ngày được sử dụng không thay đổi trong vài năm qua, vậy tại sao tập lệnh thao túng chúng? Date.JS hoàn toàn là thư viện JS Date tốt nhất hiện có. Có một vài vấn đề cho nó trong github, nhưng nếu không, nó hoàn hảo. github.com/datejs/Datejs
thussb

3

Chức năng này hoạt động rất đẹp đối với tôi.

function ParseDateForSave(dateValue) {
    // create a new date object
    var newDate = new Date(parseInt(dateValue.substr(6)));

    // return the UTC version of the date
    return newDate.toISOString();
}


2
var userdate = new Date("2009-1-1T8:00:00Z");
var timezone = userdate.getTimezoneOffset();
var serverdate = new Date(userdate.setMinutes(userdate.getMinutes()+parseInt(timezone)));

Điều này sẽ cung cấp cho bạn Ngày và Giờ UTC thích hợp.
Đó là bởi vìgetTimezoneOffset() nó sẽ cung cấp cho bạn sự khác biệt múi giờ trong vài phút. Tôi khuyên bạn không nên sử dụng toISOString()vì đầu ra sẽ nằm trong chuỗi Do đó trong tương lai bạn sẽ không thể thao tác ngày


2

Đây là những gì tôi đã làm trong quá khứ:

var utcDateString = new Date(new Date().toUTCString()).toISOString();

2

Nếu bạn cần đối tượng ngày

Chỉ vượt qua chuỗi ngày Ngày giả định thời gian là 00:00 được thay đổi theo múi giờ:

new Date('2019-03-11')
Sun Mar 10 2019 18:00:00 GMT-0600 (Central Standard Time)

Nếu bạn thêm giờ và phút hiện tại, bạn sẽ có được ngày thích hợp:

new Date('2019-03-11 ' + new Date().getHours() + ':' + new Date().getMinutes())
Mon Mar 11 2019 04:36:00 GMT-0600 (Central Standard Time)

1

Nhìn vào câu hỏi của bạn rõ ràng rằng bạn chỉ muốn gửi phạm vi ngày đến phụ trợ của bạn để xử lý bài tiếp theo.

Tôi giả sử rằng bạn đang tuân thủ các nguyên tắc dữ liệu tiêu chuẩn dự kiến ​​dữ liệu sẽ ở một định dạng cụ thể. Ví dụ: tôi sử dụng ODATA là API RESTfull dự kiến ​​các đối tượng thời gian ngày có định dạng: -

YYYY-MM-DDT00: 00: 00.

Điều đó có thể dễ dàng đạt được thông qua đoạn trích được đăng dưới đây (Vui lòng thay đổi định dạng theo yêu cầu của bạn).

var mydate;//assuming this is my date object which I want to expose var UTCDateStr = mydate.getUTCFullYear() + "-" + mydate.getUTCMonth() + "-" + mydate.getUTCDate() + "T00:00:00";

Mặt khác, nếu bạn ở trong tình huống của tôi, trong đó bạn đã nhận được một ngày từ phụ trợ của mình và trình duyệt chuyển đổi nó thành ngày địa phương của bạn. Mặt khác, bạn quan tâm đến ngày UTC thì bạn có thể thực hiện như sau: -

var mydate;//assuming this is my date object which I want to expose var UTCDate = new Date(mydate);/*create a copy of your date object. Only needed if you for some reason need the original local date*/ UTCDate.setTime(UTCDate.getTime() + UTCDate.getTimezoneOffset() * 60 * 1000);

Đoạn mã trên về cơ bản thêm / bớt thời gian được thêm / bớt bởi trình duyệt dựa trên múi giờ.

Ví dụ: nếu tôi ở EST (GMT-5) và Dịch vụ của tôi trả về một đối tượng thời gian ngày = Thứ tư 17 tháng 8 năm 2016 00:00:00 GMT-0500 trình duyệt của tôi sẽ tự động trừ phần bù múi giờ (5 giờ) để lấy giờ địa phương. Vì vậy, nếu tôi cố gắng lấy thời gian tôi nhận được Thứ tư ngày 16 tháng 8 năm 2016 19:00:00 GMT-0500. Điều này gây ra rất nhiều vấn đề. Có rất nhiều thư viện ngoài kia chắc chắn sẽ làm cho việc này dễ dàng hơn nhưng tôi muốn chia sẻ cách tiếp cận thuần túy của JS.

Để biết thêm thông tin xin vui lòng xem tại: http://praveenlobo.com/blog/how-to-convert-javascript-local-date-to-utc-and-utc-to-local-date/ nơi tôi đã nhận cảm hứng.

Hi vọng điêu nay co ich!


1

Phương pháp này sẽ cung cấp cho bạn: 2017-08-04T11:15:00.000+04:30và bạn có thể bỏ qua biến vùng để nhận 2017-08-04T11:15:00.000.

function getLocalIsoDateTime(dtString) {
    if(dtString == "")
        return "";
    var offset = new Date().getTimezoneOffset();
    var localISOTime = (new Date(new Date(dtString) - offset * 60000 /*offset in milliseconds*/)).toISOString().slice(0,-1);
    //Next two lines can be removed if zone isn't needed.
    var absO = Math.abs(offset);
    var zone = (offset < 0 ? "+" : "-") + ("00" + Math.floor(absO / 60)).slice(-2) + ":" + ("00" + (absO % 60)).slice(-2);
    return localISOTime + zone;
}

1

Sử dụng gói khoảnh khắc, bạn có thể dễ dàng chuyển đổi chuỗi ngày của UTC sang đối tượng Ngày mới:

const moment = require('moment');
let b = new Date(moment.utc('2014-02-20 00:00:00.000000'));
let utc = b.toUTCString();
b.getTime();

Điều này đặc biệt hữu ích khi máy chủ của bạn không hỗ trợ múi giờ và bạn muốn lưu trữ ngày UTC luôn trong máy chủ và lấy lại dưới dạng đối tượng Ngày mới. Mã trên đã làm việc cho yêu cầu của tôi về vấn đề tương tự mà chủ đề này là dành cho. Chia sẻ ở đây để nó có thể giúp đỡ người khác. Tôi không thấy chính xác giải pháp trên trong bất kỳ câu trả lời. Cảm ơn.


4
Mặc dù điều này có thể trả lời câu hỏi, không có lời giải thích về mã của bạn. Vui lòng cập nhật câu trả lời của bạn để cung cấp một lời giải thích về những gì bạn đang làm. Cảm ơn!
Miroslav Glamuzina


0

Tôi biết câu hỏi này đã cũ, nhưng đã xem xét vấn đề tương tự này và một tùy chọn sẽ là gửi date.valueOf () đến máy chủ thay thế. hàm valueOf () của Ngày javascript gửi số mili giây kể từ nửa đêm ngày 1 tháng 1 năm 1970 UTC.

giá trị của()


0

Vì vậy, đây là cách tôi phải làm vì tôi vẫn muốn một đối tượng ngày JavaScript thao tác như một ngày và rất tiếc những câu trả lời này yêu cầu bạn phải đi đến một chuỗi.

//First i had a string called stringDateVar that i needed to convert to Date
var newDate = new Date(stringDateVar)

//output: 2019-01-07T04:00:00.000Z
//I needed it 2019-01-07T00:00:00.000Z because i had other logic that was dependent on that 

var correctDate = new Date(newDate.setUTCHours(0))

//This will output 2019-01-07T00:00:00.000Z on everything which allows scalability 

0

sợi thêm khoảnh khắc

import moment from 'moment';

//local Js date to UTC using moment
const utcDate = moment.utc(moment(new date()).format('YYYY-MM-DDTHH:mm:ss')).valueOf();
console.log('UTC Date', utcDate);


// UTC to local date without moment
const localDate = convertUTCDateToLocalDate(new Date(utcDate))
console.log('UTC Date', moment(localDate).format('MMM D, YYYY HH:mm'));


function convertUTCDateToLocalDate(date) {

   let newDate = new Date(date.getTime() + date.getTimezoneOffset()*60*1000);

   const offset = date.getTimezoneOffset() / 60;
   const hours = date.getHours();

   newDate.setHours(hours - offset);

   return newDate;

}


-8

Thậm chí đơn giản hơn

myvar.setTime(myvar.getTime() + myvar.getTimezoneOffset() * 60000);

2
Điều này là không đầy đủ. setTimedựa vào new Date, mà bạn không bao gồm. Hãy làm cho câu trả lời đầy đủ.
Random_user_name

Người đàn ông này còn sống không? Tại sao thậm chí không trở lại với chúng tôi, nói một cái gì đó hoặc chỉnh sửa câu trả lời?
Vô vọng
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.