46

如何格式化 javascript 日期,如 ISO 格式,但在当地时间?

myDate.toISOString()我得到的时间是:“2012-09-13T19:12:23.826Z ”

但是在这里,现在是 22:13,那么如何以上述格式包含时区?


我最终做了...

pad=function(e,t,n){n=n||"0",t=t||2;while((""+e).length<t)e=n+e;return e}
c = new Date()
c.getFullYear()+"-"+pad(c.getMonth()+1)+"-"+pad(c.getDate()-5)+"T"+c.toLocaleTimeString().replace(/\D/g,':')+"."+pad(c.getMilliseconds(),3)
4

11 回答 11

53

不需要图书馆!对于某些Date对象,例如t = new Date()

  • 将本地时区偏移量从分钟转换为毫秒

    z = t.getTimezoneOffset() * 60 * 1000

  • 从 t 中减去偏移量

    tLocal = t-z

  • 创建移位日期对象

    tLocal = new Date(tLocal)

  • 转换为 ISO 格式字符串

    iso = tLocal.toISOString()

  • 删除毫秒和区域

    iso = iso.slice(0, 19)

  • 用空格替换丑陋的“T”

    iso = iso.replace('T', ' ')

结果是一个不错的 ISO-ish 格式日期时间字符串,例如本地时区的“2018-08-01 22:45:50”。

于 2018-08-01T23:59:26.397 回答
20

有点小技巧,但可以利用瑞典使用非常接近 ISO 的格式这一事实在一行中完成:

// Returns a string like 2021-01-17T01:59:57
function dateToISOButLocal(date) {
    return date.toLocaleString('sv').replace(' ', 'T');
}
于 2021-01-17T07:01:26.410 回答
15

为了方便起见,我按照 Denis Howe 所说的在下面作为现成的功能进行了介绍。

还有一个解决方法:在原始答案中 tz 不起作用,因为 t 是日期,而不是毫秒。

function dateToISOLikeButLocal(date) {
    const offsetMs = date.getTimezoneOffset() * 60 * 1000;
    const msLocal =  date.getTime() - offsetMs;
    const dateLocal = new Date(msLocal);
    const iso = dateLocal.toISOString();
    const isoLocal = iso.slice(0, 19);
    return isoLocal;
}

有了这个,我得到了作为 URL 参数所需的字符串:

"2018-11-16T12:23:50"
于 2018-11-16T10:25:01.170 回答
6

AFAIK 你不能在 javascript 中格式化日期(不使用外部库)。你能做的最好的就是“自己格式化”。我是说:

var date = new Date();
var year = date.getFullYear();
var month = date......


var ISOdate = year + "-" + month + "-" + .... ;

但是有一些很好的库可以让你格式化日期!(阅读“格式”如中library.getDate("YYYY-MM-DD.........");

编辑:

Moment.js 似乎是您正在寻找的东西:http: //momentjs.com/

于 2012-09-13T19:21:12.713 回答
1

我不太明白您需要哪个日期,但我认为您需要

   const ISOLocaleString = d => {
       const pad = n => n < 10 ? '0'+n : n;    
       return d.getFullYear()+'-'
            + pad(d.getMonth()+1)+'-'
            + pad(d.getDate())+'T'
            + pad(d.getHours())+':'
            + pad(d.getMinutes())+':'
            + pad(d.getSeconds())+'Z'
   }

或者

    const ISOUTCLocaleString = d => {
        const pad = n => n<10 ? '0'+n : n;    
        return d.getUTCFullYear()+'-'
             + pad(d.getUTCMonth()+1)+'-'
             + pad(d.getUTCDate())+'T'
             + pad(d.getUTCHours())+':'
             + pad(d.getUTCMinutes())+':'
             + pad(d.getUTCSeconds())+'Z'
    }
于 2020-03-03T15:26:22.203 回答
1

另一种方法是在 Date 对象上定义一个原型,该原型利用内置的toISOString方法(还提供了一个单独的函数):

// Extend Date.prototype
Date.prototype.toLocalISOString = function() {
  // Get the local offset for the date in minutes
  let offsetMins = this.getTimezoneOffset();
  // Get a time value adjusted for the offset
  let localTimeMs = this - offsetMins * 6e4;
  // Make a new Date so don't affect this
  let date = new Date(localTimeMs);
  // Get the local offset sign (ECMAScript sign is opposite to usual)
  let utcOffsetSign = offsetMins > 0? '-' : '+';
  // Remove sign from offsetMins
  offsetMins = Math.abs(offsetMins);
  // Get offset hours and minutes, padd to 2 digits
  let utcOffsetHr = String(offsetMins / 60 | 0).padStart(2,'0');
  let utcOffsetMin = String(offsetMins % 60).padStart(2,'0');
  // Build offset string
  let utcOffsetString = `${utcOffsetSign}${utcOffsetHr}:${utcOffsetMin}`;
  // Return as adjusted ISO 8601 format string with adjusted offset
  return date.toISOString().replace('Z', utcOffsetString);
};

// E.g.
let date = new Date();
// Like 2020-08-04T14:52:38.613-07:00
console.log(`UTC  : ${date.toISOString()}\n` +
            `Local: ${date.toLocalISOString()}`);
            
// Stand alone function
function toISOLocal(date) {
  let offsetMins = date.getTimezoneOffset();
  let d = new Date(date - offsetMins*6e4);
  let offsetSign = offsetMins > 0? '-' : '+';
  offsetMins = Math.abs(offsetMins);
  let offsetHr = String(offsetMins / 60 | 0).padStart(2,'0');
  let offsetMin = String(offsetMins % 60).padStart(2,'0');
  return d.toISOString().replace('Z', `${offsetSign}${offsetHr}:${offsetMin}`);
}

// Like 2020-08-04T14:52:38.613-07:00
console.log(`fn   : ${toISOLocal(date)}`);

于 2020-08-04T21:56:48.793 回答
1

没有直接的方法可以做到这一点。但是,您可以使用toLocaleString创建一个可以轻松解析的字符串以使其成为 ISO 字符串。

这适用于节点:

function getLocalIsoTime(time, timezone) {
        const local = time.toLocaleString("en-US", {timeZone: timezone, hour12: false, year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", second: "2-digit"});
        return `${local.substr(6, 4)}-${local.substr(0, 2)}-${local.substr(3, 2)}T${local.substr(12, 8)}`;
    }

console.log(getLocalIsoTime(new Date(), 'Asia/Kolkata'));

一个更简单的版本适用于 node 15+ 和大多数现代浏览器:

function getLocalIsoTime(time, timezone) {
        return time.toLocaleString("en-CA", {timeZone: timezone, hour12: false}).replace(/, /, "T");
    }
    
console.log(getLocalIsoTime(new Date(), 'Asia/Kolkata'));

于 2020-11-01T09:14:08.700 回答
1

在原始帖子中,当前 ISO 日期为“2012-09-13T 19 :12:23.826Z”

如果想要的是一个尊重 ISO 规范但反映与 UTC 时间的本地偏移的日期,则目标答案应该是“2012-09-13T 22 :12:23.826+03:00”。

以下帖子中的最佳答案,代码片段尊重ISO 8601格式/ RFC 3339

https://stackoverflow.com/a/17415677/1563072

于 2021-10-18T12:12:32.333 回答
0

ISO 8601只是一种格式化日期的方法,因此可以应用于任何时区。

您是否尝试过对象方法的timeZone选项?DatetoLocaleString

这个问题有例子的答案。

于 2020-09-07T01:44:45.143 回答
0

这是我使用的方法。如果日期/月份/小时等是单个数字(例如将“6”变为“06”),请注意添加零

function formatLikeISO (d: Date): string {
    let lengthChecker = (str) => {
        if (str.length == 1) { return '0' + str; }
        return str;
    }

    let theDate = lengthChecker(String(d.getDate()));
    let month = lengthChecker(String(d.getMonth() + 1));
    let mins = lengthChecker(String(d.getMinutes()));
    let hours = lengthChecker(String(d.getHours()));
    let secs = lengthChecker(String(d.getSeconds()));

    let formatted =
        d.getFullYear() + '-' +
        month + '-' +
        theDate + ' ' +
        hours + ':' +
        mins + ':' +
        secs;

    return formatted;
}

这将输出这种格式:

“2021-06-30 11:31:34”

于 2021-06-30T08:55:59.433 回答
0

虽然这里的答案可能有效,但没有什么比简单的单线更简单的了:

new Date(new Date().getTime() - new Date().getTimezoneOffset() * 60 * 1000).toISOString()

给有兴趣的人解释一下:

我们创建一个新的 Date 实例(外部实例)。
我们给它另一个 Date 实例(以毫秒为单位),从中减去时区偏移量(也以毫秒为单位,正或负)。所有这些我们都格式化成 ISO

于 2021-11-14T13:24:22.033 回答