How to convert zulu time to UTC +01:00 without moment [duplicate] - javascript

This question already has answers here:
How to ISO 8601 format a Date with Timezone Offset in JavaScript?
(21 answers)
Javascript date format like ISO but local
(12 answers)
Closed last year.
Hi i have a date that arrive with this format 2020-05-25T20:11:38Z, and i need to convert to 2020-05-25T21:11:38+01:00.
In my project is not installed moment.js is a big project, and the masters don't use it.
is there some where to make this change?
I have the timeZone for every zone.
I know that there is options like this getTimezoneOffset();
And i did find in stackoverflow, but i didn't find any response in javascript to change zulu to utc with offset.
Thanks for your indications

The format "2020-05-25T20:11:38Z" is a common standard ISO 8601 format, it is also produced by the default Date.prototype.toString method, however it's only with a UTC (+0) offset.
The above ISO 8601 format is reliably parsed by reasonably current built–in parsers (some very old implementations won't parse it correctly), so to get a Date object:
let date = new Date('2020-05-25T20:11:38Z');
Formatting it for a fixed +1 offset can done by adjusting the Date for the offset then formatting it as required by leveraging the default toISOString method, e.g.
// Initial timestamp
let s = '2020-05-25T20:11:38Z'
// Convert s to a Date
let d = new Date(s);
// Show that it's the same date
console.log(`Initial value: ${s}\n` +
`Parsed value : ${d.toISOString()}`);
// Create a new date with 1 hour added as 3,600,000 milliseconds
let e = new Date(d.getTime() + 3.6e6);
// Format and manually modify the offset part
let timestamp = e.toISOString().replace('Z','+01:00');
console.log(`Adjusted timestamp: ${timestamp}`);
// Parse back to date
console.log(`Parsed to a Date : ${new Date(timestamp).toISOString()}`);
The resulting timestamp can be parsed back to a Date that represents the same instant in time as the original string (last line).
Note that the adjusted Date is only created for the sake of formatting the timestamp, it shouldn't be used for anything else.
If, on the other hand, you want a general function to format dates as ISO 8601 with the local offset, there is likely an answer at Javascript date format like ISO but local that suits. If so, then this is a duplicate, e.g. this answer or this one.
Also, there are a number of libraries that will allow specifying the formatting and timezone as separate parameters, so consider using one if you're going to do a lot of date formatting or manipulation.

Related

How to display times in different time zones using the offset value

I am trying to display the current moment in different time zones. I have tried to use native javascript and the moment-js package but it seems you require the time zone name (ex. "America/Toronto") to display the information I want. The problem is that the information I currently have is the timestamp in string format (see below for string format) from the desired timezone, and the city the timestamp belongs to. The problem with using the city to create my tz value is that one of the cities I want to display isn't in the IANA tz database (Calgary).
String timestamp:
2022-04-26T14:19:42.8430964-04:00
As can be seen I do have the time offset and I was hoping there was a way to convert this string in js to a Date object and then display the time using the offset in the correct time zone.
Note what I want to display is the following format:
12:19 pm MT
I know I could just parse out the string but I feel like this isn't the best practice, however I may be wrong.
Also note that I will have to get the time zone (ex. MT, ET it can also be MST, EST) using the offset.
you don't need moment here. JS can do this natively. Also moment is now deprecated.
Your IANA timezone is America/Edmonton. So it's simple to do. That date format is an ISO 8601 date format, so you can just pass it into the new Date constructor and it'll parse it correctly:
const iso8601 = '2022-04-26T14:19:42.8430964-04:00';
const date = new Date(iso8601);
console.log(date.toLocaleString('en-US', { timeZone: 'America/Edmonton' }));
It doesn't matter what timezone your input date is set, so long as it has the correct offset in the ISO date. Once it's a Date, the offset is irrelevant. E.g.:
const iso8601 = '2022-04-26T14:19:42.8430964Z';
const date = new Date(iso8601);
//time will now be 4 hours off above as the input date is UTC
console.log(date.toLocaleString('en-US', { timeZone: 'America/Edmonton' }));

Parsing ISO-8601 date containing TZ offset with seconds

Seems there is a problem with definition of ISO date format in Javascript. As far as I undrerstand ISO-formatted date can include TZ offset that includes hours, minutes and seconds, e.g.:
1919-07-01T00:00:00+04:31:19
Trying to parse such datetime string using JavaScript new Date() object leads to an error:
new Date('1919-07-01T00:00:00+04:31:17').toLocaleDateString('ru-RU') => "Invalid Date"
new Date('1919-07-01T00:00:00+04:31').toLocaleDateString('ru-RU') => "01.07.1919"
The date specified in the example comes from the Java backend client/POSTGRESQL database where representation '1919-07-01T00:00:00+04:31:17' treated as a valid ISO date.
The reason the date contains "seconds" in timezone offset is understood if we look as the following data regaring daylight savings changes:
https://www.timeanddate.com/time/change/russia/moscow?year=1919
Is there any suggestion why it is impossible to overcome this limitation or where is the origin of the problem?
Seems there is a problem with definition of ISO date format in Javascript.
Javascript is based on ECMA-262, which is published by ECMA International. ISO 8601 is published by ISO, a different standards organisation. I don't have a full copy of ISO 8601, however I expect that there are extensions to allow seconds in the offset given they were fairly common prior to 1900.
ECMA-262 defines a couple of formats, one is based on a simplification of ISO 8601, so does not support all of the formats ISO 8601 does (the other is the format produced by toString).
Since the format in the OP is not consistent with one of the formats in ECMA-262, parsing is implementation dependent, see Why does Date.parse give incorrect results?
Your best option is to manually parse the string, either with a simple function or a library that supports seconds in the offset.
An example parse function is below (according to timeanddate the seconds part of the offset in 1919 should have been 19, not 17 so I've modified the original string accordingly):
// Parse format 1919-07-01T00:00:00+04:31:19
function parseWithTZSecs(date) {
let [Y, M, D, H, m, s, oH, om, os] = date.match(/\d+/g);
let sign = date.substring(19,20) == '+'? -1 : 1;
return new Date(Date.UTC(Y, M-1, D, +H + sign*oH, +m + sign*om, +s + sign*os));
}
let date = parseWithTZSecs('1919-07-01T00:00:00+04:31:19');
// 1919-07-01, 12:00:00 AM
console.log(date.toLocaleString('en-CA',{timeZone: 'Europe/Moscow'}));
This is just an example, of course it should do validation of input and deal with unexpected formats and values.

Javascript convert time to epoch format

I have a date sting that looks like this 2016-02-21T02:14:39.000000
would like to convert it to Epoch time using Javascript if possible
Try
var ts = "2016-02-21T02:14:39.000000";
var unix_seconds = ((new Date(ts)).getTime()) /1000;
console.log(unix_seconds);
getTime returns milliseconds, so divide by 1000 to get seconds
https://jsfiddle.net/tbxac0de/
Presumably by "convert it to Epoch time" you mean a number of seconds or milliseconds since the common UNIX and ECMAScript epoch. The time value can be found by converting the string to a Date and getting its internal time value.
By far the best way to convert a string to a Date is to manually parse it. A library can help, but a function isn't difficult to write. E.g. to parse "2016-02-21T02:14:39.000000" as a local date (i.e. ISO 8601 format without a time zone), use something like:
// Parse y-m-dTh:m:s as local date and time
// since there is no timezone
function parseIsoLocal(s) {
var b = s.split(/\D/);
return new Date(b[0],b[1]-1,b[2],b[3],b[4],b[5],
((b[6]||'')+'000').slice(0,3));
}
// Convert string to Date
var d = parseIsoLocal('2016-02-21T02:14:39.000000');
// Show date and milliseconds since epoch
document.write(d + '<br>' + +d);
The above can easily be extended to treat the string as UTC, incorporate time zones and validate the input, but that doesn't seem to be required in this case.
Note that most browsers will parse the format in the OP, however some in use will not and, of those that will, some treat it as local and some as UTC. According to ISO 8601, it should be treated as local so that's what I've done.

Converting date from string with offset to different timezone

I'm wondering on the correct way to convert a string date in a non-ISO format to a different offset/timezone.
I am currently given 3 values:
the date in format MM/DD/YYYY (23/11/2016)
the time in 24h format (23:13)
timezone offset (-07:00)
I would like to convert said date to the user's timezone.
I am trying to convert the format to the format accepted by moment timezone's moment.tz() function ('2016-11-23T23:13-07:00') but I am not sure how to do that without splitting the date array and converting it to said date.
Moment's timezone has the tools I need to convert the date afterwards to the local timezone. For example:
moment.tz('2016-11-23T23:13-07:00', moment.tz.guess());
Any thoughts on how to convert 23/11/2016 23:13 with offset -07:00 to the local date preferably using momentJS?
Why not just format as an ISO 8601 string with offset and give that to moment.js?
function customToISOString(date, time, offset){
return date.split(/\D/).reverse().join('-') + 'T' + time + offset;
}
document.write(customToISOString('23/11/2016','23:13','-07:00')); // 2016-11-23T23:13-07:00
Most modern browsers will also parse that, but don't do it as there are still plenty of older browsers around where it will fail.
I like Rob's answer, but I'll also give you it in moment.js.
First, you don't need moment-timezone, and you definitely don't need to guess the time zone id just to convert to that zone. In ISO format, it would just be like this:
var m = moment('2016-11-23T23:13-07:00');
This will read in the offset during parsing, apply it, then convert to the local time zone, returning a moment object in "local mode". This is the default mode, so it just works.
With the requirements you described it would be like this:
// your inputs
var d = "23/11/2016";
var t = "23:13";
var o = "-07:00";
var m = moment(d + ' ' + t + o, 'MM/DD/YYYY HH:mmZ');
Note that I add the space between the date and time just for safety, so there's no risk of mixing the year and the hour components.
Again it will automatically apply the offset and convert to the local time zone, since that's the default behavior. If you want some other behavior, there are ways to do that as well.

Unabe to parse date of different culture

I want to parse date
var newDateTime = new Date(Date.parse($("#SelctedCalendarDay").val()));
$("#SelctedCalendarDay").val() value is 14-okt-2014 in string.
When the date is 14-Oct-2014 it parses it correctly.
So how can I parse this date 14-okt-2014?
I'm not sure what language you are using (Dutch?) so I'll use English, it's easy to substitute whatever language you like. You can parse a date string like 14-Oct-2014 using:
function parseDMMMY(s) {
// Split on . - or / characters
var b = s.split(/[-.\/]/);
// Months in English, change to whatever language suits
var months = {jan:0, feb:1, mar:2, apr:3, may:4, jun:5,
jul:6, aug:7, sep:8, oct:9, nov:10, dec:11};
// Create a date object
return new Date(b[2], months[b[1].toLowerCase()], b[0]);
}
console.log(parseDMMMY('14-Oct-2014')); // Tue Oct 14 2014 00:00:00
Note that the above will create a local date object. It doesn't do any validation of values so if you give it a string like 31-Jun-2014 you'll get a Date object for 01-Jul-2014. It's easy to add validation (it takes one more line of code), but that may not be required if you know only valid strings will be passed to the function.
From the documentation of Date.parse # Mozilla
The date time string may be in ISO 8601 format. For example,
"2011-10-10" (just date) or "2011-10-10T14:48:00" (date and time) can
be passed and parsed. The UTC time zone is used to interpret arguments
in ISO 8601 format that do not contain time zone information (note
that ECMAScript ed 6 draft specifies that date time strings without a
time zone are to be treated as local, not UTC).
It seems to me the native Date.parse does not convert date strings matching a specific locale. There also seem to be some slight differences between specific browsers.
Maybe you want to use a library like moment.js for that?
Or you may want to wire up some PHP strtotime to your JS.

Categories