例如,使用日期和时间控件,用户选择日期和时间,使得字符串表示如下:
"6-25-2012 12:00:00 PM"
碰巧这个用户在EST时区。该字符串被传递给服务器,服务器将其转换为.NET DateTime对象,然后将其存储在SQL server的日期时间列中。
当日期稍后返回到浏览器时,需要将其转换回日期,但当将上面的字符串输入到日期时,将损失4个小时的时间。我相信这是因为当在创建JavaScript日期时不指定时区时,它默认为本地时间,并且由于EST是GMT的-400,它从下午12点减去了4个小时,尽管当用户在EST时区的机器上选择它时,下午12点本应指定为EST。
显然,在将原始日期时间字符串传递给服务器进行持久化之前,需要向其添加一些内容。建议的方法是什么?
Date
构造函数来解析字符串。行为和支持的格式因浏览器和区域设置而异。如果您直接使用Date
对象,这里只是一些默认行为。
如果必须来自字符串,请尝试使用标准化格式,如ISO8601。您以该格式给出的日期为"2012-06-25T12:00:00"
。在JavaScript中处理这些问题的最简单方法是使用moment.js.
此外,要小心你真正想要代表的是什么。现在,您正在传递一个本地日期/时间,保存一个本地/日期/时间并返回一个本地的日期/时间。一路走来,什么是"本地"的观念可能会改变。
在许多情况下,日期/时间旨在表示精确的时刻。要实现这一点,您需要在客户端上将输入的本地时间转换为UTC。将UTC发送到服务器并存储。稍后,检索UTC并将其发送回客户端,将其处理为UTC并转换回本地时间。你可以用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"
在.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
将其存储在数据库中。稍后取回并发回:
// 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.
将其传递回moment.js:中的javascript
// 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();
看,这很容易,你不需要进入任何与时区有关的花哨的东西。
在这里,我认为这就是您想要的:如何忽略用户';s时区并强制Date()使用特定时区
在我看来,你可以做这样的事情:
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(',','');
指责JSON.Stringfy()…并执行:
x = (your_date);
x.setHours(x.getHours() - x.getTimezoneOffset() / 60);
在将日期发送到服务器之前,我使用了一个过滤器:
vm.dateFormat = 'yyyy-MM-dd';
dateToSendToServer = $filter('date')(dateFromTheJavaScript, vm.dateFormat);