在JavaScript/moment中解释(而不是转换!)其他时区中的日期

在JavaScript/moment中解释(而不是转换!)其他时区中的日期,javascript,date,momentjs,Javascript,Date,Momentjs,这个问题似乎与相同的警告相似。然而,这个警告不是这个问题的焦点,所描述的解决方案并不适合我的用例。我编辑了下面适当的段落来解释为什么会这样 考虑一个web应用程序,其中用户可以选择由固定相机拍摄的图像的时间范围。 显然,这架相机可能不在他自己的时区。 除此之外,提供图像的REST-API在UTC中完成所有工作 我使用的是angular4、moment.js和moment时区 因此,他可以选择是否要在本地时区、相机所在时区或UTC中查看带有时间戳的图像。到目前为止,一切都进展顺利 我遇到的麻烦是设

这个问题似乎与相同的警告相似。然而,这个警告不是这个问题的焦点,所描述的解决方案并不适合我的用例。我编辑了下面适当的段落来解释为什么会这样

考虑一个web应用程序,其中用户可以选择由固定相机拍摄的图像的时间范围。 显然,这架相机可能不在他自己的时区。 除此之外,提供图像的REST-API在UTC中完成所有工作

我使用的是angular4、moment.js和moment时区

因此,他可以选择是否要在本地时区、相机所在时区或UTC中查看带有时间戳的图像。到目前为止,一切都进展顺利

我遇到的麻烦是设置时间范围时。显然,用户设置的开始时间和结束时间应该被解释为在他选择显示的时区内,因此我可以在将请求发送到服务器之前将它们转换为UTC。 我从日期选择器(在本例中为日历打底,但这并不重要)获得的日期对象当然是在浏览器本地时间

所以我需要做的是,在相机的时区中读取日期并解释它,就像现在一样,而不需要转换它。因此,如果用户在时区UTC-2中设置“从10:00到17:00”,并且相机位于UTC+2,我需要获得“UTC+2中的10:00到17:00”,而不是“UTC+2中的14:00到21:00”

我尝试了几种方法,其中一些甚至有效,但每种方法似乎都有自己的注意事项,它们都很丑陋,因为它们进行了不必要的字符串转换。例如:

moment.tz(date.toLocaleString, cameraTimezone)
这可以工作,但会抛出一个弃用警告:

提供的值不是公认的RFC2822或ISO格式。即时构造回到js
Date()
,这在所有浏览器和版本中都不可靠

我可以通过指定传递的日期字符串的格式来消除该警告,但我面临的问题是toLocalString()和toString()都不一致。toLocaleString()显然会根据区域设置为我提供另一种格式,而toString()会在不同的浏览器中产生不同的结果,那么我怎么知道我得到了什么呢

因此,我尝试使用适当的格式,但如果我直接使用
Date::toIsoString
,我得到的时刻已经转换为UTC,这也不是我所需要的:

let datestring = date.toISOString();   //datestring will be in utc
const mom = moment.tz(datestring, cameraTimezone);  //moment will therefore be the wrong time.

有一种显而易见的方法,就是自己创建一个日期对象字符串(在javascript中非常难看),然后通过指定该格式将其解析为瞬间。但所有这些字符串转换感觉更像是一种黑客行为,而不是一个合适的解决方案,我真的很想彻底摆脱它们,告诉大家“你们有一个日期,它应该在这个时区,即使它说它不是”。有没有办法做到这一点?

它可能适合根据本地日期和用户选择的时间和时区构造符合ISO 8601的字符串,例如:

window.onload=function(){
var form=document.getElementById('cameraTimeDetail');
表格.addEventListener('submit',getPicISO,false);
}
函数getPicISO(e){
//演示
e、 预防默认值();
函数z(n){return('0'+n).slice(-2)}
变量日期=新日期();
var form=此;
//使用本地日期部件
var s=date.getFullYear()+'-'+
z(date.getMonth()+1)+'-'+
z(date.getDate())+'T'+
//使用输入时区和时间
form.pictureTime.value+
form.cameraTimezone.value;
//构造的ISO字符串
form.timeString.value=(s);
//转换为UTC ISO字符串
form.timeStringUTC.value=新日期.toISOString();
返回false;
}
输入,按钮{
宽度:15em;
}

输入时区(例如-08:00、+05:30)
输入时间(小时:毫米)
拍照片
所选日期和时间:
等效UTC:

这个答案应该会帮助你,我相信Matt Johnson(momentjs“所有者”和日期/时间专家之一)对我的答案发表了评论,实际上,因为输入包含
Z
,它确实会被视为UTC,并用
矩.tz(输入,区域)
进行转换。我想你也遇到了同样的情况(
date.toISOString()
Z
结尾)。我建议您解析指定格式和时区的非ISO字符串。谢谢。这就是我最终解决问题的方式。它很丑陋,而且会消耗不必要的资源。我希望有更好的方法,但如果没有,至少它是有效的。