Create a Date with a set timezone without using a string representation
我有一个网页,每天、每月和每年都有三个下拉列表。如果我使用带数字的javascript
1 | new Date(xiYear, xiMonth, xiDate) |
给出正确的日期,但由于夏令时的原因,它认为日期是格林尼治标准时间+01:00。
这里的问题是,然后我将这个
接受的回答给我指明了正确的方向,但是仅仅使用
1 | Apr 5th 00:00 GMT+01:00 |
到
1 | Apr 4th 23:00 GMT+01:00 |
然后我还必须设置UTC日期、月份和年份,以
1 | Apr 5th 01:00 GMT+01:00 |
这就是我想要的。
使用
但是,除非指定日期字符串,否则不能在构造函数中使用UTC进行设置。
使用
1 2 | var d = new Date(xiYear, xiMonth, xiDate); d.setTime( d.getTime() + d.getTimezoneOffset()*60*1000 ); |
这个答案是专门针对原始问题而设计的,不会给出你所期望的答案。特别是,有些人希望减去时区偏移量而不是添加它。请记住,尽管这个解决方案的要点是为了特定的反序列化而对javascript的日期对象进行黑客攻击,但在所有情况下都不正确。
我相信您需要createdateasutc函数(请与convertdateoutc比较)
1 2 3 4 5 6 7 | 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()); } |
我不相信这是可能的-在创建日期对象之后,无法对其设置时区。
在某种程度上,这是有意义的——概念上(如果可能不在实现中);根据http://en.wikipedia.org/wiki/unix_timestamp(emphasis mine):
Unix time, or POSIX time, is a system for describing instants in time, defined as the number of seconds elapsed since midnight Coordinated Universal Time (UTC) of Thursday, January 1, 1970.
一旦您构建了一个,它将在"实时"中表示某个点。只有当您想将抽象时间点转换为人类可读的字符串时,时区才是相关的。
因此,您只能够更改日期在构造函数中表示的实际时间是有意义的。遗憾的是,似乎没有办法在显式时区中传递消息,而您所调用的构造函数(可以说是正确的)将您的"本地"时间变量转换为规范存储时的gmt,因此没有办法在gmt时间中使用
从好的方面来说,只使用接受字符串的构造函数是很简单的。您甚至不需要将数字月份转换成字符串(至少在Firefox上),所以我希望简单的实现可以工作。但是,在尝试之后,它在Firefox、Chrome和Opera中成功运行,但在Konquerror("无效日期")、Safari("无效日期")和IE("NaN")中失败。我想您只需要一个查找数组来将月份转换为字符串,如下所示:
1 2 3 4 5 | var months = [ '', 'January', 'February', ..., 'December']; function createGMTDate(xiYear, xiMonth, xiDate) { return new Date(months[xiMonth] + ' ' + xiDate + ', ' + xiYear + ' 00:00:00 GMT'); } |
我知道这是旧的,但如果它能帮助你使用时刻和时刻时区。如果你没看见他们,看看。
http://momentjs.com/timezone/时区/
网址:http://momentjs.com/
两个非常方便的时间操作库。
如果您想处理从年、月、日……创建一个javascript日期对象(包括时区)的稍微不同但相关的问题,也就是说,如果您想将一个字符串解析成一个日期,那么显然您必须进行一个极其复杂的舞蹈:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | // 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; } |
也就是说,您可以使用不带时区的日期创建一个"UTC时间"(这样您就知道它在哪个地区,即UTC的"地区",而不是默认为本地地区),然后手动应用指定的时区偏移量。
如果有人真的考虑了javascript日期对象超过了,哦,五分钟,那不是很好吗?
1 2 3 4 5 6 7 8 | 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 |
对于所有位置偏移wiki UTC时间偏移列表
一线解决方案
1 | new Date(new Date(1422524805305).getTime() - 330*60*1000) |
使用时间戳(毫秒),而不是142524805305而不是330,请使用以分钟为单位的时区偏移。格林尼治标准时间(例如印度+5:30是5*60+30=330分钟)
这可能有助于某些人,将UTC放在传递给新构造函数的内容的末尾。
至少在Chrome中,你可以说是
只需设置时区,然后根据
1 | new Date().toLocaleString("en-US", {timeZone:"America/New_York"}) |
对于UTC+Z,GetTimeZoneOffset为负。
1 2 3 4 | var d = new Date(xiYear, xiMonth, xiDate); if(d.getTimezoneOffset() > 0){ d.setTime( d.getTime() + d.getTimezoneOffset()*60*1000 ); } |
我发现获得正确日期的最简单方法是使用datejs。
网址:http://www.datejs.com/
我通过Ajax以字符串形式获取日期:"2016-01-12t00:00:00"
1 2 3 4 5 6 7 | 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,所以我找到了一种方法来使用它来获得正确的日期。
我想这可能对某人有帮助…
1 2 3 4 5 6 7 8 | // My clock 2018-07-25, 00:26:00 (GMT+7) let date = new Date(); // 2018-07-24:17:26:00 (Look like GMT+0) const myTimeZone = 7; // my timeZone // my timeZone = 7h = 7 * 60 * 60 * 1000 (millisecond); // 2018-07-24:17:26:00 = x (milliseconds) // finally, time in milliseconds (GMT+7) = x + myTimezone date.setTime( date.getTime() + myTimeZone * 60 * 60 * 1000 ); // date.toISOString() = 2018-07-25, 00:26:00 (GMT+7) |
此代码将返回用浏览器时区格式化的日期对象。
1 2 3 4 | Date.prototype.timezone = function () { this.setHours(this.getHours() + (new Date().getTimezoneOffset() / 60)); return this; } |
里程里程
1 | var d = new Date(xiYear, xiMonth, xiDate).toLocaleString(); |
我从中看到的最佳解决方案来自
http://www.codingforums.com/archive/index.php/t-19663.html网站
打印时间函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | <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) Banff, Canada: <script language="JavaScript">document.write(printTime("-7")) |
完整代码示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | <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) </head> <body> Banff, Canada: <script language="JavaScript">document.write(printTime("-7")) Michigan: <script language="JavaScript">document.write(printTime("-5")) Greenwich, England(UTC): <script language="JavaScript">document.write(printTime("-0")) Tokyo, Japan: <script language="JavaScript">document.write(printTime("+9")) Berlin, Germany: <script language="JavaScript">document.write(printTime("+1")) </body> </html> |
我使用了时区JS包。
1 2 | var timezoneJS = require('timezone-js'); var tzdata = require('tzdata'); |
::
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 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()); }, |
这对我很有效。但不确定这是否是个好主意。
1 2 3 4 5 6 7 8 | var myDate = new Date(); console.log('myDate:', myDate); // myDate:"2018-04-04T01:09:38.112Z" var offset = '+5'; // e.g. if the timeZone is -5 var MyDateWithOffset = new Date( myDate.toGMTString() + offset ); console.log('MyDateWithOffset:', MyDateWithOffset); // myDateWithOffset:"2018-04-03T20:09:38.000Z" |
这是最好的解决方案
使用:
1 2 3 4 5 | // TO ALL dates Date.timezoneOffset(-240) // +4 UTC // Override offset only for THIS date new Date().timezoneOffset(-180) // +3 UTC |
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | 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)); |
咖啡版:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | 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 |