javascript toISOString() 忽略时区偏移

IT技术 javascript datetime timezone-offset
2021-01-28 05:24:05

我正在尝试将 Twitter 日期时间转换为本地 iso 字符串(对于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", "");
}

在 newdate 中一切正常,但 toISOString() 再次将其扔回原来的时间...谁能帮我从 Twitterdate 中获取 ISO 中的当地时间,格式为:2012 年 5 月 31 日星期四 08:33:41 +0000

6个回答

moment.js 很棒,但有时您不想为简单的事情拉大量依赖项。

以下也有效:

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

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

简短而简单 - 太棒了!为了让它更易读,我把 .toISOString().slice(0,-5).replace("T", " "); 在您的解决方案结束时。
2021-03-14 05:24:05
您的解决方案不会显示您的当地时间。它欺骗日期认为您的 UTC 日期是您的本地日期。你不应该改变你的日期你应该添加你的时区偏移
2021-03-17 05:24:05
为什么是“-”(现在是 tzoffset)?
2021-03-28 05:24:05
时间以 UTC(协调世界时)表示,并带有一个特殊的 UTC 指示符(“Z”)。
2021-03-31 05:24:05
太好了,谢谢。这是一个带有可选日期参数的函数:function localISOTime(d) { if (!d) d = new Date() var tzoffset = d.getTimezoneOffset() * 60000; //以毫秒为单位的偏移量 return (new Date(Date.now() - tzoffset)).toISOString().slice(0, -1); }
2021-04-02 05:24:05

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

var date = new Date(); // Or the date you'd like converted.
var isoDateTime = new Date(date.getTime() - (date.getTimezoneOffset() * 60000)).toISOString();
@betoharres 将时区偏移量转换为毫秒,这就是 getTime 所在的位置。
2021-03-23 05:24:05
不使用库的很好的解决方案,谢谢!
2021-04-02 05:24:05
我喜欢这种方法。您的示例无法按原样工作,因为您尚未定义日期。如果你在前面加上 var date = new Date(); 以你的例子来说,它有效。
2021-04-03 05:24:05
有用!但我不明白你为什么乘以 60000 ?:s
2021-04-12 05:24:05
很漂亮也很简单。谢谢你。请注意:它确实在字符串的末尾保留了“Z”,这在技术上是错误的,但很容易编辑掉。
2021-04-12 05:24:05

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

http://momentjs.com/docs/

我在离线多年后登录只是为了注意这个答案允许格式化日期以便 .NET API 接收带有时区的日期并正确反序列化它。在 js 项目中使用 moment.js 并没有那么糟糕,知道来自 ECMAScript 的 Date API 有多少缺乏功能。
2021-03-20 05:24:05
这不是一个正确的答案......你能用 Moment.js 给出正确的答案吗?如果这是一个真实的答案,我每次都可以回答“x86 FTW !!! intel.com/content/dam/www/public/us/en/documents/manuals/... ”并说祝你好运...
2021-03-30 05:24:05
我在离线多年后登录只是为了注意答案中提供的解决方案允许在 ISO8601 中正确序列化本地小时。moment.js 的存在是因为 ECMAScript 的 Date API 很烂。
2021-04-10 05:24:05

下面这个日期函数在没有额外的脚本库的情况下达到了预期的效果。基本上它只是一个简单的日期组件以正确的格式连接,并增加了 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));
}

用法:

var d = new Date();
console.log(d.dateToISO8601String());

希望这对其他人有帮助。

编辑

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

那是错误的,而且不起作用,我害怕
2021-03-18 05:24:05
当您获得正确的当地时间时,您通过添加“Z”代替时区错误地将该时间与祖鲁时间相关联。如果您将由此创建的时间投入到任何符合 ISO 的应用程序中,您将不会得到正确的时间作为回报。您应该打电话.getTimezoneOffset(),然后将分钟计算为小时格式来代替,以便您的 ISO 日期符合要求。
2021-03-24 05:24:05
这对我有帮助,我认为这是一个更好的答案。
2021-04-01 05:24:05
由于当前的代码,这不会输出符合 ISO8601 的字符串,并且会为除 UTC 时区中的字符串之外的所有字符串输出错误的时间。ISO8601 兼容偏移的形式+HH:MM不是+HH00. 如果您要使用+/-NN:NN本地时区来自的偏移小时/分钟的后缀,则Z需要使用本地月份、日期、小时、分钟、秒和毫秒,而不是 UTC 版本。应该调用这个函数Date.prototype.toLocalISOString,它更符合标准Date函数。 dateFromISO8601是不必要的new Date()
2021-04-04 05:24:05
现在您正在获取 UTC 值,但将它们与本地时区偏移量结合起来?
2021-04-11 05:24:05

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

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