如何在不使用string表示的情况下使用设置的时区创buildJavaScript Date对象
我有一个网页,有三个日历,月份和年份的下拉菜单。 如果我使用带数字的JavaScript Date构造函数,那么我得到当前时区的Date对象:
new Date(xiYear, xiMonth, xiDate)
给出正确的date,但由于夏令时,它认为date是GMT + 01:00。
这里的问题是,然后我给这个date一个Ajax方法,当date是在服务器上反序列化它已被转换为GMT,所以失去了一个小时,这一天移回一天。 现在我可以将日,月,年分别传递给Ajax方法,但似乎应该有更好的方法。
被接受的答案指出了我正确的方向,但是仅仅使用setUTCHours
本身就改变了:
Apr 5th 00:00 GMT+01:00
至
Apr 4th 23:00 GMT+01:00
然后,我也必须设置UTCdate,月份和年份结束
Apr 5th 01:00 GMT+01:00
这是我想要的
使用.setUTCHours()
可以实际设置UTC时间的date,这将允许您在整个系统中使用UTC时间。
除非您指定datestring,否则您不能在构造函数中使用UTC进行设置。
使用new Date(Date.UTC(year, month, day, hour, minute, second))
您可以从特定的UTC时间创buildDate对象。
var d = new Date(xiYear, xiMonth, xiDate); d.setTime( d.getTime() + d.getTimezoneOffset()*60*1000 );
当这个date对象被反序列化时,你可能会得到你所期望的信息。
我相信你需要createDateAsUTC函数(请与convertDateToUTC比较)
function createDateAsUTC(date) { return new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds())); } function convertDateToUTC(date) { return new Date(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds()); }
我不相信这是可能的 – 没有能力创build一个Date对象后设置时区。
从某种意义上讲,这在概念上是可行的(如果可能还没有实施)。 per http://en.wikipedia.org/wiki/Unix_timestamp (重点是我的):
Unix时间或POSIX时间是用于描述时间的系统,定义为从1970年1月1日星期四协调世界时(UTC)开始经过的秒数。
一旦你构build了一个,它将代表一个“真实”的时间点。 只有当您想将该抽象时间点转换为可读的string时,该时区才是相关的。
因此,只有在构造函数中才能更改Date所表示的实际时间才有意义。 可悲的是,似乎没有办法通过一个明确的时区 – 并且你正在调用的构造函数(可以说是正确的)将它们的“本地”时间variables转换成GMT,当它将它们存储到规范时 – 所以没有办法使用int, int, int
GMT时间的构造函数。
从好的一面来看,仅仅使用带String的构造函数是微不足道的。 你甚至不需要将数字月份转换成一个string(至less在Firefox上),所以我希望一个天真的实现工作。 然而,试用后,它在Firefox,Chrome和Opera中成功运行,但在Konqueror(“无效date”),Safari(“无效date”)和IE(“NaN”)中失败。 我想你只是有一个查找数组将月份转换为string,如下所示:
var months = [ '', 'January', 'February', ..., 'December']; function createGMTDate(xiYear, xiMonth, xiDate) { return new Date(months[xiMonth] + ' ' + xiDate + ', ' + xiYear + ' 00:00:00 GMT'); }
如果你想要处理从年,月,日,…, 包括时区创build一个Javascriptdate对象稍有不同,但相关的问题,也就是说,如果你想parsing一个string到一个date – 那么你显然必须做一个令人非常复杂的舞蹈:
// parseISO8601String : string -> Date // Parse an ISO-8601 date, including possible timezone, // into a Javascript Date object. // // Test strings: parseISO8601String(x).toISOString() // "2013-01-31T12:34" -> "2013-01-31T12:34:00.000Z" // "2013-01-31T12:34:56" -> "2013-01-31T12:34:56.000Z" // "2013-01-31T12:34:56.78" -> "2013-01-31T12:34:56.780Z" // "2013-01-31T12:34:56.78+0100" -> "2013-01-31T11:34:56.780Z" // "2013-01-31T12:34:56.78+0530" -> "2013-01-31T07:04:56.780Z" // "2013-01-31T12:34:56.78-0330" -> "2013-01-31T16:04:56.780Z" // "2013-01-31T12:34:56-0330" -> "2013-01-31T16:04:56.000Z" // "2013-01-31T12:34:56Z" -> "2013-01-31T12:34:56.000Z" function parseISO8601String(dateString) { var timebits = /^([0-9]{4})-([0-9]{2})-([0-9]{2})T([0-9]{2}):([0-9]{2})(?::([0-9]*)(\.[0-9]*)?)?(?:([+-])([0-9]{2})([0-9]{2}))?/; var m = timebits.exec(dateString); var resultDate; if (m) { var utcdate = Date.UTC(parseInt(m[1]), parseInt(m[2])-1, // months are zero-offset (!) parseInt(m[3]), parseInt(m[4]), parseInt(m[5]), // hh:mm (m[6] && parseInt(m[6]) || 0), // optional seconds (m[7] && parseFloat(m[7])*1000) || 0); // optional fraction // utcdate is milliseconds since the epoch if (m[9] && m[10]) { var offsetMinutes = parseInt(m[9]) * 60 + parseInt(m[10]); utcdate += (m[8] === '+' ? -1 : +1) * offsetMinutes * 60000; } resultDate = new Date(utcdate); } else { resultDate = null; } return resultDate; }
也就是说,你使用没有时区的date创build一个“UTC时间”(所以你知道它所在的区域,即UTC的区域设置),然后手动应用指定的时区偏移量。
如果有人真正考虑了Javascriptdate对象超过五十分钟,那么这不是很好吗….
我知道这是旧的,但如果它可以帮助你可以使用瞬间和时间的时区。 如果你还没有看到他们看看。
两个非常方便的时间操作库。
d = new Date(); utc = d.getTime() + (d.getTimezoneOffset() * 60000); nd = new Date(utc + (3600000*offset)); offset value base on which location time zone you would like to set For India offset value +5.5, New York offset value -4, London offset value +1
所有位置偏移量维基UTC时间偏移列表
这可能会帮助某人,把UTC传递给新的构造函数
至less在铬你可以说var date = new Date("2014-01-01 11:00:00 UTC")
一线解决scheme
new Date(new Date(1422524805305).getTime() - 330*60*1000)
而不是1422524805305,以毫秒为单位使用时间戳而不是330,使用您的时区偏移量以分钟为单位。 GMT(例如印度+5:30是5 * 60 + 30 = 330分钟)
getTimeZoneOffset是UTC + z的负数。
var d = new Date(xiYear, xiMonth, xiDate); if(d.getTimezoneOffset() > 0){ d.setTime( d.getTime() + d.getTimezoneOffset()*60*1000 ); }
任何里程
var d = new Date(xiYear, xiMonth, xiDate).toLocaleString();
我发现获取正确date的最简单的方法是使用datejs。
我以string的格式通过Ajax获取我的date:'2016-01-12T00:00:00'
var yourDateString = '2016-01-12T00:00:00'; var yourDate = new Date(yourDateString); console.log(yourDate); if (yourDate.getTimezoneOffset() > 0){ yourDate = new Date(yourDateString).addMinutes(yourDate.getTimezoneOffset()); } console.log(yourDate);
控制台将读取:
周一2016年1月11日19:00:00 GMT-0500(东部标准时间)
星期二2016年1月12日00:00:00 GMT-0500(东部标准时间)
https://jsfiddle.net/vp1ena7b/3/
'addMinutes'来自于datejs,你可以自己做纯js,但是我已经在我的项目中有了datejs,所以我find了一个使用它来获取正确date的方法。
我以为这可能会帮助别人…
我从这里看到的最佳解决scheme来自于
http://www.codingforums.com/archive/index.php/t-19663.html
打印时间function
<script language="javascript" type="text/javascript"> //borrowed from echoecho //http://www.echoecho.com/ubb/viewthread.php?tid=2362&pid=10482&#pid10482 workDate = new Date() UTCDate = new Date() UTCDate.setTime(workDate.getTime()+workDate.getTimezoneOffset()*60000) function printTime(offset) { offset++; tempDate = new Date() tempDate.setTime(UTCDate.getTime()+3600000*(offset)) timeValue = ((tempDate.getHours()<10) ? ("0"+tempDate.getHours()) : (""+tempDate.getHours())) timeValue += ((tempDate.getMinutes()<10) ? ("0"+tempDate.getMinutes()) : tempDate.getMinutes()) timeValue += " hrs." return timeValue } var now = new Date() var seed = now.getTime() % 0xfffffff var same = rand(12) </script> Banff, Canada: <script language="JavaScript">document.write(printTime("-7"))</script>
完整的代码示例
<html> <head> <script language="javascript" type="text/javascript"> //borrowed from echoecho //http://www.echoecho.com/ubb/viewthread.php?tid=2362&pid=10482&#pid10482 workDate = new Date() UTCDate = new Date() UTCDate.setTime(workDate.getTime()+workDate.getTimezoneOffset()*60000) function printTime(offset) { offset++; tempDate = new Date() tempDate.setTime(UTCDate.getTime()+3600000*(offset)) timeValue = ((tempDate.getHours()<10) ? ("0"+tempDate.getHours()) : (""+tempDate.getHours())) timeValue += ((tempDate.getMinutes()<10) ? ("0"+tempDate.getMinutes()) : tempDate.getMinutes()) timeValue += " hrs." return timeValue } var now = new Date() var seed = now.getTime() % 0xfffffff var same = rand(12) </script> </head> <body> Banff, Canada: <script language="JavaScript">document.write(printTime("-7"))</script> <br> Michigan: <script language="JavaScript">document.write(printTime("-5"))</script> <br> Greenwich, England(UTC): <script language="JavaScript">document.write(printTime("-0"))</script> <br> Tokyo, Japan: <script language="JavaScript">document.write(printTime("+9"))</script> <br> Berlin, Germany: <script language="JavaScript">document.write(printTime("+1"))</script> </body> </html>
这段代码将返回用浏览器时区格式化的Date对象 。
Date.prototype.timezone = function () { this.setHours(this.getHours() + (new Date().getTimezoneOffset() / 60)); return this; }
我使用了timezone-js软件包。
var timezoneJS = require('timezone-js'); var tzdata = require('tzdata');
::
createDate(dateObj) { if ( dateObj == null ) { return null; } var nativeTimezoneOffset = new Date().getTimezoneOffset(); var offset = this.getTimeZoneOffset(); // use the native Date object if the timezone matches if ( offset == -1 * nativeTimezoneOffset ) { return dateObj; } this.loadTimeZones(); // FIXME: it would be better if timezoneJS.Date was an instanceof of Date // tried jquery $.extend // added hack to Fiterpickr to look for Dater.getTime instead of "d instanceof Date" return new timezoneJS.Date(dateObj,this.getTimeZoneName()); },
这是最好的解决scheme
使用:
// TO ALL dates Date.timezoneOffset(-240) // +4 UTC // Override offset only for THIS date new Date().timezoneOffset(-180) // +3 UTC
码:
Date.prototype.timezoneOffset = new Date().getTimezoneOffset(); Date.setTimezoneOffset = function(timezoneOffset) { return this.prototype.timezoneOffset = timezoneOffset; }; Date.getTimezoneOffset = function() { return this.prototype.timezoneOffset; }; Date.prototype.setTimezoneOffset = function(timezoneOffset) { return this.timezoneOffset = timezoneOffset; }; Date.prototype.getTimezoneOffset = function() { return this.timezoneOffset; }; Date.prototype.toString = function() { var offsetDate, offsetTime; offsetTime = this.timezoneOffset * 60 * 1000; offsetDate = new Date(this.getTime() - offsetTime); return offsetDate.toUTCString(); }; ['Milliseconds', 'Seconds', 'Minutes', 'Hours', 'Date', 'Month', 'FullYear', 'Year', 'Day'].forEach((function(_this) { return function(key) { Date.prototype["get" + key] = function() { var offsetDate, offsetTime; offsetTime = this.timezoneOffset * 60 * 1000; offsetDate = new Date(this.getTime() - offsetTime); return offsetDate["getUTC" + key](); }; return Date.prototype["set" + key] = function(value) { var offsetDate, offsetTime, time; offsetTime = this.timezoneOffset * 60 * 1000; offsetDate = new Date(this.getTime() - offsetTime); offsetDate["setUTC" + key](value); time = offsetDate.getTime() + offsetTime; this.setTime(time); return time; }; }; })(this));
咖啡版本:
Date.prototype.timezoneOffset = new Date().getTimezoneOffset() Date.setTimezoneOffset = (timezoneOffset)-> return @prototype.timezoneOffset = timezoneOffset Date.getTimezoneOffset = -> return @prototype.timezoneOffset Date.prototype.setTimezoneOffset = (timezoneOffset)-> return @timezoneOffset = timezoneOffset Date.prototype.getTimezoneOffset = -> return @timezoneOffset Date.prototype.toString = -> offsetTime = @timezoneOffset * 60 * 1000 offsetDate = new Date(@getTime() - offsetTime) return offsetDate.toUTCString() [ 'Milliseconds', 'Seconds', 'Minutes', 'Hours', 'Date', 'Month', 'FullYear', 'Year', 'Day' ] .forEach (key)=> Date.prototype["get#{key}"] = -> offsetTime = @timezoneOffset * 60 * 1000 offsetDate = new Date(@getTime() - offsetTime) return offsetDate["getUTC#{key}"]() Date.prototype["set#{key}"] = (value)-> offsetTime = @timezoneOffset * 60 * 1000 offsetDate = new Date(@getTime() - offsetTime) offsetDate["setUTC#{key}"](value) time = offsetDate.getTime() + offsetTime @setTime(time) return time