2015-03-20 18 views
6

Tôi cần đối tượng Ngày js với các giá trị được chỉ định cho ngày và năm. Tôi mong đợi new Date("2000-01-01") để cung cấp cho tôi đối tượng Ngày với 2000 là giá trị cho getFullYear(), nhưng nếu cài đặt thời gian của máy tính được đặt thành múi giờ Chicago, tôi sẽ nhận được Fri Dec 31 1999 18:00:00 GMT-0600 (CST) và đối với Buenos Aires: Fri Dec 31 1999 22:00:00 GMT-0200 (ARST).javascript Vấn đề múi giờ ngày

Có cách nào để tạo đối tượng Ngày, với .getFullYear() trả về ngày chúng tôi đặt trong hàm tạo không, bất kể múi giờ nào được đặt trên máy của người dùng?

Cập nhật:. tôi cần ngày đối tượng này sẽ được sử dụng trong thư viện khác (trong đó kêu gọi phương pháp .getFullYear() của nó, vì vậy sử dụng getters UTC không thực sự giúp

+0

REF cho getfullyear_method http://www.thesstech.com/javascript/date_getfullyear_method

Trả lời

13

Khi phân tích một chuỗi để một Date trong JavaScript, một giá trị đó là ở định dạng YYYY-MM-DD được hiểu như là một UTC giá trị , chứ không phải là một giá trị địa phương thời gian.

Điều quan trọng là các bộ phận được phân cách bằng dấu gạch nối, và rằng không có thông tin múi giờ trong chuỗi. Thông số ECMAScript 5.1 nói trong §15.9.1.15:

... Giá trị chênh lệch múi giờ vắng mặt là “Z”.

Điều đó có nghĩa là, nếu bạn không chỉ định bù trừ, điều đó sẽ giả định bạn có nghĩa là UTC.

Lưu ý rằng vì đây là trái ngược với những gì tiêu chuẩn ISO-8601 cho biết, đây là hành vi đã được thay đổi trong ECMAScript 2015 (6.0), trong đó nói rằng trong §20.3.1.16:

... Nếu múi giờ bù đắp vắng mặt, ngày giờ được hiểu là giờ địa phương.

Do đó, khi quy định này của ES6 được triển khai đúng, giá trị chuỗi của định dạng này được sử dụng để được hiểu là UTC sẽ được hiểu là giờ địa phương thay thế. Tôi đã viết blog về điều này here.

Cách giải quyết đơn giản. Thay thế dấu gạch ngang bằng dấu gạch chéo:

var s = "2000-01-01"; 
var dt = new Date(s.replace(/-/g, '/')); 

Một cách giải quyết khác có thể chấp nhận là gán thời gian buổi trưa thay vì nửa đêm cho đến ngày. Điều này sẽ được phân tích cú pháp là giờ địa phương và đủ xa để tránh xung đột DST.

var s = "2000-01-01"; 
var dt = new Date(s + "T12:00:00"); 

Hoặc, hãy xem xét thư viện như moment.js hợp lý hơn nhiều.

var s = "2000-01-01"; 
var dt = moment(s, 'YYYY-MM-DD').toDate(); 
+0

Cảm ơn bạn! đã cứu ngày của tôi! nhưng mẹo nào có dấu gạch chéo đến từ đâu? – eagor

+1

Sử dụng dấu gạch chéo làm cho chuỗi không tuân thủ ISO, mà hầu hết các triển khai sẽ diễn giải dưới dạng giờ địa phương. Việc lưu giữ định dạng 'yyyy/mm/dd' thay vì' mm/dd/yyyy' hoặc 'dd/mm/yyyy' cũng giúp loại bỏ các vấn đề trong vùng. –

+1

nếu tôi cũng có thời gian, như: '" 2015-06-01T11: 31: 01 "'. Bất kỳ cách nào để làm điều đó mà không sử dụng moment.js? Thanx – eagor

0

Bạn có thể viết phương thức mới vào 'Date.prototype' và sử dụng phương pháp này để lấy ngày sẽ bao gồm chênh lệch múi giờ địa phương.

//return the date with depend of Local Time Zone 
    Date.prototype.getUTCLocalDate = function() { 
    var target = new Date(this.valueOf()); 
    var offset = target.getTimezoneOffset(); 
    var Y = target.getUTCFullYear(); 
    var M = target.getUTCMonth(); 
    var D = target.getUTCDate(); 
    var h = target.getUTCHours(); 
    var m = target.getUTCMinutes(); 
    var s = target.getUTCSeconds(); 

    return new Date(Date.UTC(Y, M, D, h, m + offset, s)); 
    }; 
Các vấn đề liên quan