I have a datetime string returned from my backend like this:
2018-12-30T20:00:00-05:00
I am trying to get the offset from this datetime string and apply it to a new Date object.
When I do that... I get the clients timezone date instead of the one I would like.
var time = "2018-12-30T20:00:00-05:00"
new Date(time)
I don't mind leveraging momentjs or any other library in JS but I am trying to do this in my front-end.
UPDATE
if the date returned from my backend has -05:00 as the offset... then when I create a date object in the front end... it should have the same offset
For example:
2018-12-31T10:00:00-05:00
I have a datetime string returned from my backend like this:
2018-12-30T20:00:00-05:00
I am trying to get the offset from this datetime string and apply it to a new Date object.
When I do that... I get the clients timezone date instead of the one I would like.
var time = "2018-12-30T20:00:00-05:00"
new Date(time)
I don't mind leveraging momentjs or any other library in JS but I am trying to do this in my front-end.
UPDATE
if the date returned from my backend has -05:00 as the offset... then when I create a date object in the front end... it should have the same offset
For example:
2018-12-31T10:00:00-05:00
Share
Improve this question
edited Dec 30, 2018 at 23:45
HeelMega
asked Dec 30, 2018 at 23:23
HeelMegaHeelMega
5188 silver badges30 bronze badges
8
- Your question is a little vague because there is more than one way to interpret applying an offset to a date — you could convert it to a new absolute time, you could keep the absolute time the same, but apply a new offset, etc. It would help if you gave an example of a correct before and after date/time. – Mark Commented Dec 30, 2018 at 23:42
- @MarkMeyer added an example – HeelMega Commented Dec 30, 2018 at 23:45
- did you try to use ordinary way? – Julian Commented Dec 30, 2018 at 23:49
- @Jin yes but it goes with the clients offset instead of using the -5 offset jsfiddle/f8hqwb1k – HeelMega Commented Dec 30, 2018 at 23:51
- then what is your expected result? can you write an example? with your above text – Julian Commented Dec 30, 2018 at 23:54
3 Answers
Reset to default 5If you're willing to use moment
you can easily pull the offset from the date/time with utcOffset
. You can use the same function to apply the offset to the new date/time. Here are two moment objects that represent the same time, but with different offsets. This converts the second to the offset of the first without changing the absolute time:
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./ajax/libs/moment.js/2.22.2/moment.min.js"></script>
<script src="https://cdnjs.cloudflare./ajax/libs/moment-timezone/0.5.23/moment-timezone-with-data-2012-2022.min.js"></script>
You need to get the timezone from the string, the convert it to an ECMAScript offset and use it to format a string with the required offset.
There are already answers on SO to do the above, but here's an answer anyway.
E.g.
/* 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));
}
Note that typical ISO 8601 offsets don't have a colon, i.e. they're usually ±HHmm.
Here is a very rough example of how to approach this with pure JS, for those that get here and don't want to use Moment 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+")");
The better way to output would be to implement your own function that displays the date using the getter functions for hours, minutes, etc. I'm not sure if the .toISOString()
is standard but it works in Chrome.
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744191424a4562451.html
评论列表(0条)