javascript toISOString()忽略时区偏移量

Cyr*_*rom 123 javascript datetime timezone-offset

我正在尝试将Twitter日期时间转换为本地iso-string(对于prettyDate),现在为期2天.我只是没有让当地时间正确..

即时通讯使用以下功能:

function getLocalISOTime(twDate) {
    var d = new Date(twDate);
    var utcd = Date.UTC(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours(),
        d.getMinutes(), d.getSeconds(), d.getMilliseconds());

    // obtain local UTC offset and convert to msec
    localOffset = d.getTimezoneOffset() * 60000;
    var newdate = new Date(utcd + localOffset);
    return newdate.toISOString().replace(".000", "");
}
Run Code Online (Sandbox Code Playgroud)

在newdate一切都很好,但toISOString()再次将它重新回到原来的时间......任何人都可以帮我从Twitter日期中获取当地时间格式为:星期四,2012年5月31日08:33:41 +0000

use*_*097 221

moment.js 很棒,但有时候你不想为简单的东西拉大量的依赖.

以下工作原理:

var tzoffset = (new Date()).getTimezoneOffset() * 60000; //offset in milliseconds
var localISOTime = (new Date(Date.now() - tzoffset)).toISOString().slice(0, -1);
// => '2015-01-26T06:40:36.181'
Run Code Online (Sandbox Code Playgroud)

slice(0, -1)摆脱了拖尾的Z代表祖鲁时区,可以通过自己的所取代.

  • 简短而简单 - 辉煌!为了使它更具人性化,我把.toISOString().slice(0,-5).replace("T",""); 在解决方案的最后. (7认同)
  • 时间以UTC(协调世界时)表示,带有特殊的UTC指示符("Z"). (5认同)
  • 非常好,谢谢.这是一个函数,它接受一个可选的日期参数:function localISOTime(d){if(!d)d = new Date()var tzoffset = d.getTimezoneOffset()*60000; //以毫秒为单位的偏移量返回(new Date(Date.now() - tzoffset)).toISOString().slice(0,-1); } (3认同)
  • @NicoDurand你的函数有一个错误,它总是返回当前日期。应该是“d - tzoffset” (2认同)
  • 您的解决方案不会显示您的当地时间。它欺骗日期,认为您的 UTC 日期是您的本地日期。你不应该改变你的日期你应该添加你的时区偏移 (2认同)

Dus*_*ilk 73

我没有使用时刻的解决方案是将其转换为时间戳,添加时区偏移量,然后转换回日期对象,然后运行toISOString()

var date = new Date(); // Or the date you'd like converted.
isoDate = new Date(date.getTime() - (date.getTimezoneOffset() * 60000)).toISOString();
Run Code Online (Sandbox Code Playgroud)

  • 我喜欢这种方法.您的示例不能按原样运行,因为您尚未定义日期.如果你在前面添加var date = new Date(); 举个例子,它有效. (2认同)
  • 有用!但我不明白你为什么乘以 60000 ?:s (2认同)
  • @betoharres 将时区偏移量转换为毫秒,这就是 getTime 所在的位置。 (2认同)

Ome*_*lan 13

使用moment.js,您可以使用keepOffset以下参数toISOString

toISOString(keepOffset?: boolean): string;

moment().toISOString(true)

  • 令人震惊的是,与所有其他答案相比,这个答案要好得多。谢谢。 (2认同)
  • 仅供参考 moment.js 团队不再推荐:https://momentjs.com/docs/#/-project-status/ (2认同)

小智 8

moment.js FTW !!!

只需将您的日期转换为片刻并按照您的要求操纵它:

var d = new Date(twDate);
var m = moment(d).format();
console.log(m);
// example output:
// 2016-01-08T00:00:00-06:00
Run Code Online (Sandbox Code Playgroud)

http://momentjs.com/docs/

  • 这不是一个正确的答案......你能用Moment.js给出正确的答案吗?如果这是一个真正的答案,我每次都可以回答"x86 FTW !!! https://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures- software-developer-instruction-set-reference-manual-325383.pdf"并祝你好运...... (6认同)
  • [*何时“使用 jQuery”不是 JavaScript 问题的有效答案?*](https://meta.stackoverflow.com/questions/335328/when-is-use-jquery-not-a-valid-answer- to-a-javascript-question) (3认同)

Jam*_*mes 7

下面的日期函数无需额外的脚本库即可实现所需的效果.基本上它只是一个简单的日期组件连接,格式正确,并增加了Date对象的原型.

 Date.prototype.dateToISO8601String  = function() {
    var padDigits = function padDigits(number, digits) {
        return Array(Math.max(digits - String(number).length + 1, 0)).join(0) + number;
    }
    var offsetMinutes = this.getTimezoneOffset();
    var offsetHours = offsetMinutes / 60;
    var offset= "Z";    
    if (offsetHours < 0)
      offset = "-" + padDigits(offsetHours.replace("-","") + "00",4);
    else if (offsetHours > 0) 
      offset = "+" + padDigits(offsetHours  + "00", 4);

    return this.getFullYear() 
            + "-" + padDigits((this.getUTCMonth()+1),2) 
            + "-" + padDigits(this.getUTCDate(),2) 
            + "T" 
            + padDigits(this.getUTCHours(),2)
            + ":" + padDigits(this.getUTCMinutes(),2)
            + ":" + padDigits(this.getUTCSeconds(),2)
            + "." + padDigits(this.getUTCMilliseconds(),2)
            + offset;

}

Date.dateFromISO8601 = function(isoDateString) {
      var parts = isoDateString.match(/\d+/g);
      var isoTime = Date.UTC(parts[0], parts[1] - 1, parts[2], parts[3], parts[4], parts[5]);
      var isoDate = new Date(isoTime);
      return isoDate;       
}

function test() {
    var dIn = new Date();
    var isoDateString = dIn.dateToISO8601String();
    var dOut = Date.dateFromISO8601(isoDateString);
    var dInStr = dIn.toUTCString();
    var dOutStr = dOut.toUTCString();
    console.log("Dates are equal: " + (dInStr == dOutStr));
}
Run Code Online (Sandbox Code Playgroud)

用法:

var d = new Date();
console.log(d.dateToISO8601String());
Run Code Online (Sandbox Code Playgroud)

希望这有助于其他人.

编辑

更正了评论中提到的UTC问题,并将此功能归功于AlexdateFromISO8601.

  • 虽然您获得了正确的当地时间,但您通过添加“Z”代替时区,错误地将该时间与祖鲁时间关联起来。如果您要将由此创建的时间放入任何符合 ISO 的应用程序中,您将*不会*获得正确的时间作为回报。您应该调用`.getTimezoneOffset()`,然后将分钟计算为小时格式来代替小时格式,以便您的 ISO 日期保持一致。 (2认同)
  • 正如当前代码所示,这不会输出符合 ISO8601 的字符串,并且会输出除 UTC 时区之外的所有时间的错误时间。符合 ISO8601 的偏移量的形式为“+HH:MM”,而不是“+HH00”。如果您打算使用“+/-NN:NN”后缀表示本地时区从“Z”开始的偏移小时/分钟,则需要使用本地月份、日期、小时、分钟、秒和毫秒,而不是UTC 版本。该函数应称为“Date.prototype.toLocalISOString”,它更符合标准“Date”函数。`dateFromISO8601` 是不必要的,因为 `new Date()` 可以工作。 (2认同)

小智 6

获取当前日期和时间将非常有帮助。

var date=new Date();
  var today=new Date(date.getTime() - (date.getTimezoneOffset() * 60000)).toISOString().replace(/T/, ' ').replace(/\..+/, '');  
Run Code Online (Sandbox Code Playgroud)