此问题与Deprecation warning: moment construction falls back to js Date类似,因为出现了相同的警告。但是,该警告不是此问题的焦点,并且所描述的解决方案不适合我的用例。我已经编辑了下面的相应段落来解释为什么会这样。
考虑一个Web应用程序,用户可以在其中选择固定摄像机拍摄的图像的时间范围。 显然,这台相机可能不属于他自己的时区。 除此之外,提供图像的REST-API可以完成UTC中的所有操作。
我正在使用angular4,moment.js和moment timezone。
因此,他可以选择是否要在当地时区,相机所在的时区或UTC中查看带有时间戳的图像。到目前为止,一切都在努力达到这一点。
我遇到麻烦的地方是设定时间范围。显然,用户设置的开始和结束时间应该被解释为在他选择显示的时区中,因此我可以在将请求发送到服务器之前将它们转换为UTC。 我从日期选择器获取的Date对象(在这种情况下是primeng日历,但这并不重要)当然是在浏览器本地时间。
所以我需要做的就是拍摄日期并在相机的时区中解释它,而不是转换它。因此,如果用户在时区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()
,这在所有浏览器和版本中都不可靠。
我可以通过指定传递的日期字符串的格式来消除该警告,但我面临的问题是toLocaleString()和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.
有一种显而易见的方法是自己创建一个Date对象的字符串(这在javascript中非常难看),然后通过指定该格式将其解析为片刻。但所有这些字符串转换感觉更像是一个黑客,而不是一个正确的解决方案,我真的想完全摆脱它们,只是告诉时刻“这里你有一个约会,它应该在这个时区,即使它说它不是“。有没有办法做到这一点?
答案 0 :(得分:1)
它可能适合根据本地日期和用户选择的时间和时区构建符合ISO 8601标准的字符串,例如
window.onload = function() {
var form = document.getElementById('cameraTimeDetail');
form.addEventListener('submit', getPicISO, false);
}
function getPicISO(e) {
// For demo
e.preventDefault();
function z(n){return ('0'+n).slice(-2)}
var date = new Date();
var form = this;
// Use local date parts
var s = date.getFullYear() + '-' +
z(date.getMonth()+1) + '-' +
z(date.getDate()) + 'T' +
// Use input timezone and time
form.pictureTime.value +
form.cameraTimezone.value;
// Consructed ISO string
form.timeString.value = (s);
// Convert to UTC ISO String
form.timeStringUTC.value = new Date(s).toISOString();
return false;
}
input, button {
width: 15em;
}
<form id="cameraTimeDetail">
<table>
<tr>
<td>Enter timezone (e.g. -08:00, +05:30)
<td><input name="cameraTimezone" value="+05:30">
<tr>
<td>Enter time (HH:mm)
<td><input name="pictureTime" value="14:37">
<tr>
<td><input type="reset">
<td><button>Get pic</button>
<tr>
<td>Selected date and time:
<td><input name="timeString" readonly>
<tr>
<td>Equivalent UTC:
<td><input name="timeStringUTC" readonly>
</table>
</form>
显然,这是简化的,需要验证输入值,但显示逻辑。您可能还想让用户选择日期,这可以使用相同的逻辑。