2013-08-12 23 views
10

Ví dụ, sử dụng một ngày và thời gian kiểm soát, người sử dụng chọn một ngày và thời gian, như vậy mà đại diện chuỗi như sau:Làm thế nào để bạn duy trì múi giờ của ngày JavaScript từ trình duyệt đến máy chủ và ngược lại?

"6-25-2012 12:00:00 PM" 

Nó như vậy xảy ra mà người dùng này nằm ở múi giờ EST. Chuỗi được chuyển đến máy chủ, dịch nó thành một đối tượng .NET DateTime, và sau đó lưu nó trong SQL Server trong một cột datetime.

Khi ngày được trả về sau đó cho trình duyệt, nó cần phải được chuyển đổi trở lại thành ngày, tuy nhiên khi chuỗi trên được đưa vào ngày mất 4 giờ. Tôi tin rằng điều này là do khi không chỉ định múi giờ khi tạo ngày JavaScript, mặc định là giờ địa phương và kể từ EST là -400 từ GMT, nó trừ 4 giờ từ 12 giờ tối, mặc dù 12 giờ đó được định nghĩa là EST khi người dùng đã chọn nó trên máy trong múi giờ EST.

Rõ ràng một thứ gì đó cần phải được thêm vào chuỗi ngày giờ ban đầu trước khi nó được chuyển đến máy chủ để được duy trì. Cách được khuyến nghị để làm điều này là gì?

+0

Bạn có thể muốn xử lý ngày của mình dưới dạng số giây d.getTime()/1000 có thể dễ dàng được chuyển đổi về ngày bằng hầu hết các ngôn ngữ. – Serge

+0

Ok, nhưng nếu ngày ban đầu được xây dựng từ các phần chuỗi (hai điều khiển khác nhau, một từ bộ chọn ngày, bảng điều khiển còn lại tại công cụ chọn thời gian), sau đó một lần nữa làm cách nào để nói ngày JavaScript mà tôi xây dựng múi giờ của nó, nếu không thì d.getTime()/1000 sẽ được thực hiện dựa vào thời gian tôi cho nó, trừ đi 4 giờ. – brushleaf

+0

Bạn có chạy thử nghiệm với múi giờ khác nhau để đảm bảo vấn đề đến từ đó chứ không phải từ chuyển đổi không? – Serge

Trả lời

18

Đừng dựa vào JavaScript của Date hàm tạo để phân tích chuỗi. Hành vi và định dạng được hỗ trợ thay đổi một cách dữ dội trên mỗi trình duyệt và ngôn ngữ. Here chỉ là một số hành vi mặc định nếu bạn sử dụng đối tượng Date trực tiếp.

Nếu bạn phải đến từ một chuỗi, hãy thử sử dụng định dạng được chuẩn hóa như ISO8601. Ngày bạn đưa vào định dạng đó sẽ là "2012-06-25T12:00:00". Cách dễ nhất để làm việc với những thứ này trong JavaScript là với moment.js.

Ngoài ra, hãy cẩn thận về những gì bạn thực sự có ý nghĩa đại diện. Ngay bây giờ, bạn đang chuyển ngày/giờ địa phương, lưu địa phương/ngày/giờ và trả về ngày/giờ địa phương. Trên đường đi, ý tưởng về những gì "địa phương" có thể thay đổi.

Trong nhiều trường hợp, ngày/giờ được thiết kế để đại diện cho một thời điểm chính xác chính xác. Để thực hiện công việc đó, bạn cần phải chuyển đổi từ giờ địa phương được nhập thành UTC trên máy khách. Gửi UTC đến máy chủ của bạn và lưu trữ nó. Sau đó, truy xuất UTC và gửi lại cho khách hàng của bạn, xử lý nó dưới dạng UTC và chuyển đổi về giờ địa phương. Bạn có thể làm tất cả điều này một cách dễ dàng với moment.js:

// I'll assume these are the inputs you have. Adjust accordingly. 
var dateString = "6-25-2012"; 
var timeString = "12:00:00 PM"; 

// Construct a moment in the default local time zone, using a specific format. 
var m = moment(dateString + " " + timeString, "M-D-YYYY h:mm:ss A"); 

// Get the value in UTC as an ISO8601 formatted string 
var utc = m.toISOString(); // output: "2012-06-25T19:00:00.000Z" 

Trên máy chủ trong Net:

var dt = DateTime.Parse("2012-06-25T19:00:00.000Z", // from the input variable 
         CultureInfo.InvariantCulture, // recommended for ISO 
         DateTimeStyles.RoundtripKind) // honor the Z for UTC kind 

cửa hàng đó trong cơ sở dữ liệu. Sau đó lấy nó và gửi nó trở lại:

// when you pull it from your database, set it to UTC kind 
var dt = DateTime.SpecifyKind((DateTime)reader["yourfield"], DateTimeKind.Utc); 

// send it back in ISO format: 
var s = dt.ToString("o"); // "o" is the ISO8601 "round-trip" pattern. 

đèo nó trở lại javascript trong moment.js:

// construct a moment: 
var m = moment("2012-06-25T19:00:00.000Z"); // use the value from the server 

// display it in this user's local time zone, in whatever format you want 
var s = m.format("LLL"); // "June 25 2012 12:00 PM" 

// or if you need a Date object 
var dt = m.toDate(); 

Xem - đó là dễ dàng, và bạn không cần phải nhận được vào bất cứ điều gì ưa thích với múi giờ.

+0

Để lưu trữ chuỗi ISO đó trong cơ sở dữ liệu, không phải cột phải là trường datetimeoffset (so với trường SQL datetime)? Giả sử tất nhiên chúng tôi không chỉ lưu trữ một chuỗi. Hoặc là nó thích hợp hơn để chỉ lưu trữ chuỗi? – brushleaf

+0

Không, không lưu trữ chuỗi. Nếu bạn đang lưu trữ UTC, bạn có thể sử dụng datetime hoặc datetime2. Bạn không cần một datetimeoffset cho kịch bản cụ thể này. Bạn * có thể * sử dụng nó, nhưng có thể bạn không cần phải trừ khi bạn quan tâm đến múi giờ địa phương của người dùng. Xem câu trả lời của tôi trên [DateTime vs DateTimeOffset] (http://stackoverflow.com/questions/4331189/datetime-vs-datetimeoffset). –

+0

Chỉ cần thêm vào bình luận trước đây của tôi - nhiều người thực sự thích sử dụng 'DateTimeOffset' cho UTC. Mặc dù họ biết bù trừ luôn bằng 0, theo dõi rằng trong 'DateTimeOffset' thay vì' DateTime' là một cách hay để ngăn không cho nó vô tình được diễn giải sai. Nhược điểm duy nhất của việc này là nó sẽ được tuần tự hóa với 'số: 00' thay vì' Z', nhưng điều đó thường được chấp nhận. –

2

Ở đây, tôi nghĩ rằng đây là những gì bạn đang tìm kiếm: How to ignore user's time zone and force Date() use specific time zone

Dường như với tôi rằng bạn có thể làm một cái gì đó như thế này:

var date = new Date("6-25-2012 12:00:00 PM"); 

var offset = date.getTimezoneOffset(); // returns offset from GMT in minutes 

// to convert the minutes to milliseconds 
offset *= 60000; 

// the js primitive value is unix time in milliseconds so this retrieves the 
// unix time in milliseconds and adds our offset. 
// Now we can put this all back in a date object 
date = new Date(date.valueOf() + offset); 

// to get back your sting you can maybe now do something like this: 
var dateString = date.toLocaleString().replace(/\//g,'-').replace(',',''); 
0

Tôi đang sử dụng một bộ lọc trước khi gửi ngày tới máy chủ vm.dateFormat = 'yyyy-MM-dd'; dateToSendToServer = $ filter ('date') (dateFromTheJavaScript, vm.dateFormat);

Các vấn đề liên quan