javascript - Get offset from datetime string and apply to a new date object - Stack Overflow

I have a datetime string returned from my backend like this:2018-12-30T20:00:00-05:00I am trying to get

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
 |  Show 3 more ments

3 Answers 3

Reset to default 5

If 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条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信