我有一个从后端返回的datetime字符串,如下所示:
2018-12-30T20:00:00-05:00
我正在尝试从此datetime字符串获取偏移量并将其应用于新的Date对象。
这样做的时候...我得到的是客户的时区日期,而不是我想要的日期。
var time = "2018-12-30T20:00:00-05:00"
new Date(time)
我不介意利用momentjs或JS中的任何其他库,但我正在尝试在前端进行此操作。
更新
如果从后端返回的日期的偏移量为-05:00,那么当我在前端创建日期对象时,它应该具有相同的偏移量
例如:
2018-12-31T10:00:00-05:00
答案 0 :(得分:3)
如果您愿意使用moment
,则可以使用utcOffset
轻松地从日期/时间获取偏移量。您可以使用相同的功能将偏移量应用于新的日期/时间。这是两个表示相同时间但具有不同偏移量的矩对象。它将第二个转换为第一个的偏移量而不更改绝对时间:
var time = "2018-12-30T10:00:00-05:00"
let m = moment.parseZone(time)
let offset = m.utcOffset()
console.log("original: ", m.format(), "Offset:", offset)
// same time as m but -1 ofset
let m2 = moment.parseZone("2018-12-30T14:00:00-01:00")
console.log("m2 original: ", m2.format())
// change offset
m2.utcOffset(offset)
console.log("m2 converted: ", m2.format())
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.23/moment-timezone-with-data-2012-2022.min.js"></script>
答案 1 :(得分:1)
对于那些不愿使用Moment JS的人,这是一个非常粗糙的示例,说明了如何使用纯JS进行处理:
const d = new Date("2018-12-30T20:00:00-05:00");
const epochTimeDate = d.getTime(); // Get milliseconds since Unix Epoch
const localTZOffsetMilliseconds = d.getTimezoneOffset() * (60 * 1000); // Convert minutes to milliseconds
const msCoefficient = (60 * 60 * 1000);
const newTZOffsetHours = -3; // UTC -3
const newTZTime = new Date(epochTimeDate - (-1*(newTZOffsetHours*msCoefficient))); // The -1 reverses the confusing behavior of the browser spec which is the opposite of the actual offset
console.log(newTZTime.toISOString().replace(/T|Z/g,' ')+"(UTC "+newTZOffsetHours+")");
更好的输出方式是使用自己的函数,使用getter函数显示日期,以显示小时,分钟等。我不确定.toISOString()
是否为标准,但它可以在Chrome中使用。
答案 2 :(得分:1)
您需要从字符串中获取时区,将其转换为ECMAScript偏移量,然后使用它来格式化具有所需偏移量的字符串。
上面已经有答案可以解决上述问题,但是无论如何这都是答案。
例如
/* Returns offset, uses match to allow for decimal seconds in timestamp
** @param {string} s - ECMAScript formatted datetime string with offset
** in the format YYYY-MM-DDTHH:mm:ss+/-HH:mm or Z
** @returns {string} - offset part of string, i.e. +/-HH:mm or Z
*/
function getOffset(s) {
return offset = (s.match(/z$|[+\-]\d\d:\d\d$/i) || [])[0];
}
/* Convert offset in +/-HH:mm format or Z to ECMAScript offset
** @param {string} offset - in +/-HH:mm format or Z
** @returns {number} - ECMSCript offset in minutes, i.e. -ve east, +ve west
*/
function offsetToMins(offset) {
// Deal with Z or z
if (/z/i.test(offset)) return 0;
// Deal +/-HH:mm
var sign = /^-/.test(offset)? '1':'-1';
var [h, m] = offset.slice(-5).split(':');
return sign * h * 60 + +m;
}
/* Format date with offset
** @param {Date} date - date to format
** @param {string} offset - ECMASCript offset string,
** e.g. -05:00, Z
** @returns {string} ISO 8601 formatted string with
** specified offset
*/
function adjustToOffset(date, offset) {
var o = offsetToMins(offset);
var d = new Date(+date);
d.setUTCMinutes(d.getUTCMinutes() - o);
return d.toISOString().replace('Z', offset);
}
// Source string
var s = '2018-12-30T20:00:00-05:00';
// Get offset
var offset = getOffset(s);
// Make sure it's ok
if (typeof offset == 'undefined') {
console.log('offset not found');
// Otherwise, show current time with specified offset
} else {
console.log(adjustToOffset(new Date(), offset));
}
请注意,典型的ISO 8601偏移量没有冒号,即通常为±HHmm。