Javascript日期字符串,ISO格式(带时区)

Javascript日期字符串,ISO格式(带时区),javascript,date,timezone,Javascript,Date,Timezone,我一直在使用MomentJS,但我正在开始一个新项目,我不想包括这个库,因为我只玩过几次日期 所以我要做的是以类似ISO的格式获取日期的字符串表示形式('YYYY-MM-DDZHH:MM:ss'或'yyy-MM-DD HH:MM:ss')。我不希望它是UTC格式的:我希望它是在给定的时区(我可以通过编程提供) 例如,目前的表述为“2017-04-11 11:20:00”(法国时区-eq至“2017-04-11 09:22:00Z”。) 我想要本地Javascript。我一直在玩toLocaleS

我一直在使用MomentJS,但我正在开始一个新项目,我不想包括这个库,因为我只玩过几次日期

所以我要做的是以类似ISO的格式获取日期的字符串表示形式('YYYY-MM-DDZHH:MM:ss'或'yyy-MM-DD HH:MM:ss')。我不希望它是UTC格式的:我希望它是在给定的时区(我可以通过编程提供)

例如,目前的表述为“2017-04-11 11:20:00”(法国时区-eq至“2017-04-11 09:22:00Z”。)

我想要本地Javascript。我一直在玩
toLocaleString
,但没有成功

谢谢

[编辑] 在一个完美的世界中,我正在寻找一个函数,它采用日期格式、时区并返回我想要的字符串。比如:

function magicDateFormatter(format, tz) {
  /* ... */
}

var now = new Date();
console.log(magicDateFormatter('YYYY-MM-DD HH:mm:ss', 'Europe/Paris'));
// print "2017-04-11 11:20:00"

您不能使用内置方法来执行要求,因为ECMAScript实现不需要存储所有(甚至任何)时区的历史数据。他们只需要访问主机的当前时区偏移量

此外,ECMA-402国际化API也不够。虽然它允许指定时区,但并非所有实现都支持ECMA-402,也并非所有实现都支持除“UTC”以外的时区值(UTC是唯一一个ECMA-402需要支持的,其他都是可选的)。仅使用ECMA-402很难精确地指定格式

我认为您最好使用现有的库,比如moment.js和moment-timezone.js。相对于网页的一般大小(最近看起来至少是1MB),下载量并没有那么大。如果你试图自己写一些东西,你最终只会得到一些像这样的东西

为了减少下载量,您可以只获取2012年至2022年的时区数据

如果您想使用简化的调用,那么一个小型magicDateFormatter可以利用moment.js的功能:

/*返回所需时区和格式的日期的日期字符串
**@param{string}时区:IANA时区标识符,例如亚洲/萨哈林
**@param{Date}[Date]:要使用的日期,默认为当前日期
**@param{string}[format]:使用矩.js标记的输出格式,
**默认值为“YYYY-MM-DDTHH:MM:ssZZ”
**@returns{string}:格式化字符串
**
**magicDateFormatter(时区[,日期[,格式]])
*/
函数magicDateFormatter(时区、日期、格式){
//验证时区是否受支持
如果(!时刻时区(时区)){
返回“未知时区:”+“时区+”;
}
//如果未提供,请使用当前日期
日期=日期| |新日期();
//如果未提供,请使用默认格式
格式=格式| |“YYYY-MM-DDTHH:MM:ssZZ”
返回时间(日期).tz(时区).格式(格式)
}
console.log(magicDateFormatter(“欧洲/巴黎”);
console.log(magicDateFormatter(“亚洲/萨哈林”,新日期(2016年1月29日),“Do-MM,YYYY”);
log(magicDateFormatter('foo/bar')

类似的东西可能适合您:

function formatDateWithZone(date, tz) {
    var s = date.toLocaleString('en-GB', { timeZone: tz });
    var a = s.split(/\D/);
    return a[2] + '-' + a[1] + '-' + a[0] + ' ' + a[4] + ':' + a[5] + ':' + a[6];
}
用法:

formatDateWithZone(new Date(), 'Europe/Paris')  // "2017-04-12 03:37:59"

这将适用于通过ECMA-402实现时区支持的环境。通过展开
DateTimeFormat
部分,并查看标有
接受IANA时区名称的行,兼容性表将显示哪些支持IANA时区名称,您可能需要这样的内容:
首先根据需要格式化时间戳,包括时区偏移,然后根据需要更改数字项的位置,使用regex指定replace函数:

const timeStamp = new Date().toLocaleString('de-DE', {
                    timeZone: 'Europe/Berlin',
                    hour12: false,
                    year: "numeric",
                    month: "2-digit",
                    day: "2-digit",
                    hour: "2-digit",
                    minute: "2-digit",
                    second: "2-digit",
                }).replace(/(\d+)\.(\d+)\.(\d+),\s(\d+):(\d+):(\d+)/, "$3$2$1_$4$5$6");

为什么您不想包含一些可以解决问题的内容呢?因为加载一个库来执行两个操作是过度的,这取决于您通过尝试实现这些“两个方法”而产生的技术债务的数量。如果你不想要一个库,为什么不只查看你想要的摘录呢?内置的日期对象方法没有能力满足你的要求。您最终将编写一些与当前做同样事情的库几乎相同的东西。实现依赖于此,因此虽然可以指定部件和语言,但无法精确指定格式。此外,它还指定语言,而不是位置,即使语言参数被错误地称为“locale”。仅包含所需时区信息的数据组件为205kb。ECMA-402确实支持时区,大多数新浏览器现在都可以使用它了。@MattJohnson很高兴知道,但仍然是UTC,可以选择支持其他时区。Firefox38支持ECMA-402,但忽略了“UTC”以外的时区选项。精确指定格式仍然不实用。但并非所有实现ECMA-402的浏览器都实现了UTC以外的值的时区选项。对于上述情况,Firefox38返回“RangeError:无效时区”。此外,对于上述内容,IE 10的toLocaleString返回一个格式为“DDDD,d MMMM YYYY h:mm:ss a”的字符串(使用矩.js标记),因此重新格式化也不会起作用:-(这个不错但缺少日期填充的零填充应该已经存在于
tolocalString
的输出中了,注意——并非所有的环境都支持您正在使用的区域设置,例如在本例中的
de
。这意味着
tolocalString
不会输出您期望的格式,因此正则表达式会重新显示。)水泥不起作用。你是对的。更改区域设置也需要更改正则表达式。我的观点是,即使你为指定的区域设置拥有正确的正则表达式,也不能依赖于此。一旦一个访问者没有相同的区域设置可用,代码将无法正常运行。