How do you preserve a JavaScript date's time zone from browser to server, and back?
例如,使用日期和时间控件,用户选择日期和时间,以便字符串表示如下:
1 | "6-25-2012 12:00:00 PM" |
碰巧这个用户在EST时区。该字符串将传递给服务器,服务器将其转换为.NET DateTime对象,然后将其存储在SQL Server的datetime列中。
当日期稍后返回浏览器时,需要将其转换回日期,但是当上述字符串被送入日期时,它将失去4小时的时间。我相信这是因为在创建JavaScript日期时没有指定时区时,它默认为当地时间,因为EST从格林威治标准时间是-400,它从中午12点减去4小时,即使下午12点意味着指定为EST时用户在EST时区的机器上选择它。
显然,在将原始日期时间字符串传递给要保留的服务器之前,需要将其添加到原始日期时间字符串中。这样做的推荐方法是什么?
不要依赖JavaScript的
如果您必须来自字符串,请尝试使用ISO8601等标准格式。您以该格式提供的日期为
另外,要小心你实际上要表达的意思。现在,您正在传递本地日期/时间,保存本地/日期/时间,并返回本地日期/时间。一路上,什么是"本地"的想法可能会改变。
在许多情况下,日期/时间旨在表示确切的时刻。要使其工作,您需要在客户端上将输入的本地时间转换为UTC。将UTC发送到您的服务器并存储它。稍后,检索UTC并将其发送回客户端,将其作为UTC处理并转换回本地时间。您可以使用moment.js轻松完成所有这些操作:
1 2 3 4 5 6 7 8 9 | // 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中的服务器上:
1 2 3 | 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 |
将其存储在数据库中。稍后检索并发回:
1 2 3 4 5 | // 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:
1 2 3 4 5 6 7 8 | // 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(); |
看 - 这很简单,你不需要考虑时区的任何东西。
在这里,我认为这就是你要找的东西:
如何忽略用户的时区并强制Date()使用特定的时区
在我看来,你可以做这样的事情:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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()...并执行:
1 2 | x = (your_date); x.setHours(x.getHours() - x.getTimezoneOffset() / 60); |
我在将日期发送到服务器之前使用过滤器
vm.dateFormat ='yyyy-MM-dd';
dateToSendToServer = $ filter('date')(dateFromTheJavaScript,vm.dateFormat);