Convert GMT to IST (India Standard Time) using javascript? - javascript

I have a date format is GMT or UTC.
var mydate = '2020-01-14T17:43:37.000Z'
I want to convert this date in IST format so according to this date the output I need in this format.
var date = '2020-Jan-15 12:45'

You can specify an IANA time zone identifier in the options passed to toLocaleString. The identifier for India is Asia/Kolkata.
var s = new Date('2020-01-14T17:43:37.000Z').toLocaleString(undefined, {timeZone: 'Asia/Kolkata'});
This will do the correct time zone conversion, as the input is in UTC (as specified by the Z at the end).
undefined means to use the user's locale for the formatting of the date and time. This is usually what you want. If you want a more particular format (like what you specified in your question), you can provide a specific locale string and/or adjust the other options for toLocaleString, as given in the docs.
Also, note that the conversion in your question is incorrect. India is 5 hours an 30 minutes offset from UTC. Thus the correct output is 2020-01-14 23:13:37 (in whatever format you like)

Another option for you is to use the moment and moment timezone modules for timezone conversion, they are very flexible and you can format the resulting date object according to whichever format you wish.
As mentioned by #matt-johnson-pint (thank you!) you can also use the very cool Luxon library for this purpose, I've added an example below.
const mydate = "2020-01-14T17:43:37.000Z"
// Create a UTC date object. The moment constructor will recognize the date as UTC since it includes the 'Z' timezone specifier.
let utcDate = moment(mydate);
// Convert the UTC date into IST
let istDate = moment(mydate).tz("Asia/Kolkata");
console.log("Using Moment.js:");
console.log(`UTC date (iso): ${utcDate.format("YYYY-MM-DD HH:mm:ss")}`);
console.log(`IST date (iso): ${istDate.format("YYYY-MM-DD HH:mm:ss")}`);
const DateTime = luxon.DateTime;
utcDate = DateTime.fromISO(mydate);
istDate = DateTime.fromISO(mydate).setZone("Asia/Kolkata");
console.log(`\nUsing Luxon:`);
console.log(`UTC date (iso): ${utcDate.toFormat("yyyy-LL-dd HH:mm:ss")}`);
console.log(`IST date (iso): ${istDate.toFormat("yyyy-LL-dd HH:mm:ss")}`);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"></script>
<script src="https://momentjs.com/downloads/moment-timezone-with-data-1970-2030.js"></script>
<script src="https://moment.github.io/luxon/global/luxon.min.js"></script>

Related

How to format a string in UTC to the configured timezone on Moment

I have the following string, which is in UTC:
2022-02-01T00:00:00Z
I have already configured my timezone, so I do not want to mess/call .tz()
I know that this string is in UTC, but I am not managing to convert from UTC to the defined timezone, which in this example is pacific/wallis.
I have tried many things, as
const utc = moment.utc('2022-02-01T00:00:00Z').toDate()
const inConfiguredTimeZone = utc.format()
My desire is to get this timestamp 2022-02-01T00:00:00Z and have converted to the defined timezone on Moment
I need to tell moment that "This string is in UTC, please give me the converted timestamp in the defined time zone"
If you just want to format a UTC timestamp in your current timezone (determined by your computer's time settings) just use
let s = moment("2022-02-01T00:00:00Z").format();
This will produce a string like 2022-02-01T12:00:00+12:00 if you are currently in a timezone that has a UTC offset of +12 hours (like pacific/wallis) or 2022-02-01T01:00:00+01:00 if you are currently in a timezone that has a UTC offset of +1 hours (like europe/berlin)
If you want it converted to a specific timezone use
let s = moment("2022-02-01T00:00:00Z").tz("pacific/wallis").format();
This will produce 2022-02-01T12:00:00+12:00, regardless of your current timezone.

Display an Exact Date in JavaScript Regardless of TimeZone

I'm writing some simple code to display birthdays of some friends. I've got the birthdays stored in a JSON file and I'm pulling them in and initializing them as Date objects like so:
birthday: new Date(p.birthday)
Then I display those dates using moment to format them, like so:
let formatted = moment(birthdayDate).format(BirthdayFormat);
This applies an automatic local time zone, probably from when I set up the initial date object, and depending on the time of day might put the date a few hours in the past, thus changing the date to the previous day since it defaults to midnight.
Basically, I just want to display that date unchanging at any time since it's just stating that person's birthday and time zones aren't relevant at all. I use it elsewhere as a Date so I don't really want to store it in the JSON as formatted, so how can I set this up such that it just acknowledges the date and doesn't adjust it for a time zone?
From your comment, the dates are in YYYY-MM-DD format. Unfortunately, ECMAScript parses such dates as UTC.
If the date has already been parsed as UTC, then you just need to display UTC values to your users. You can use momentjs's utc function (I guess this is one of its main uses):
// Built-in parser treats YYYY-MM-DD as UTC
let d = new Date('2020-12-30');
// m inherits the same time value, so is also "UTC"
let m = moment(d);
// Include hour H in format to show effect of utc setting later
let birthdayFormat = 'dddd, D MMMM, YYYY [at] H';
// Default is local timezone, H reflects local offset
// Date might be 29 or 30, depends on whether offset is - or + respectively
console.log('Local: ' + m.format(birthdayFormat));
// Toggle UTC switch, all output will now be UTC, not local
m.utc();
// Values are now UTC, so offset is zero and so is H
// Displays Wednesday, 30 December, 2020 at 0 for all users
console.log('UTC : ' + m.format(birthdayFormat));
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js"></script>
Convert the date to the date string so that the date does not include the timezone specific value.
birthday: new Date(p.birthday).toDateString()
Then display with the momentjs
let formatted = moment(birthdayDate).format(BirthdayFormat);

Update formatted date string to UTC value

Users are able to submit only the date part of a date stamp e.g. 2020-12-01, assuming that the time will be 00:00:00
So, if I have the above value, I want to update the time to its UTC value. So if I am in the EST timezone, I want to convert 2020-12-01 to 2020-12-01 05:00:00 to account for the five hour offset.
Can I do this with date-fns-tz?
const { zonedTimeToUtc, format } = require("date-fns-tz");
const tz = Intl.DateTimeFormat().resolvedOptions().timeZone;
const utcDate = zonedTimeToUtc(new Date("2020-12-01"), tz);
document.getElementById("app").innerHTML = `${format(
utcDate,
"yyyy-MM-dd HH:mm:ss"
)}
`;
The above yields 2020-11-30 19:00:00, which is moving the time 5 hours in the wrong direction.
https://codesandbox.io/s/happy-hoover-dn417?file=/src/index.js:23-301
Given:
const utcDate = zonedTimeToUtc(new Date("2020-12-01"), tz);
The built–in parser will be used to parse the string, so it will be parsed as UTC, then date-fns will apply the offset for the tz. Don't do that, use:
const utcDate = zonedTimeToUtc("2020-12-01", tz);
so that date-fns parses the string using the tz. Now utcDate.toISOString() produces "2020-12-01T05:00:00.000Z", which is the equivalent UTC date and time where tz is America/New_York.
Date-fns seems to always use the host timezone offset for output, the timeZone option just changes the text offset, it doesn't modify the actual timestamp values. Likely you have to use utcToZonedTime first to adjust the Date. I struggle with date-fns, I find the documentation seriously lacking in useful examples.
I'd just use toISOString and remove the "T" and "Z".

Parsing into UTC/GMT time with date-functions.js library

Doing this with the date-functions.js library (used e.g. in datetimepicker jQuery plugin):
Date.parseDate('2018-03-10 12:12', 'Y-m-d H:i')
gives:
Sat Mar 10 2018 12:12:00 GMT+0100 (Paris, Madrid)
How to get the result as Unix timestamp or GMT / UTC time instead?
A string like '2018-03-10 12:12' will usually be parsed as local as there is no timezone offset. It's also not ISO 8601 compliant so using the built-in parser will yield different results in different browsers.
While you can use a library, to parse it as UTC and get the time value is just 2 lines of code:
function toUTCTimeValue(s) {
var b = s.split(/\D/);
return Date.UTC(b[0],b[1]-1,b[2],b[3],b[4]);
}
// As time value
console.log(toUTCTimeValue('2018-03-10 12:12'));
// Convert to Date object and print as timestamp
console.log(new Date(toUTCTimeValue('2018-03-10 12:12')).toISOString());
var date = new Date('2018-03-10 12:12'.replace(' ', 'T'));
// Unix
console.log(Math.floor(date.getTime() / 1000));
// UTC
console.log(date.toUTCString());
As always, please have a look at the documentation at MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date
Use MomentJS instead. You can specify exactly what format the string you're parsing is in. MomentJS can then provide you with the underlying Date object, unix timestamp as well as convert to UTC.
var d = moment('2018-03-10 12:12', 'YYYY-MM-DD HH:mm');
console.log(d.toDate());
console.log(d.unix());
console.log(d.utc().toDate());
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.21.0/moment.min.js"></script>
You could of course also parse the date as UTC too instead of treating it as a local time.
moment.utc('2018-03-10 12:12', 'YYYY-MM-DD HH:mm');
NOTE Bit difficult for me to test UTC as I'm in the UK and GMT and UTC are virtually the same.

moment-timezones.js, how to convert date in spesific timezone to utc, disregarding my local timezone?

my system uses timezone UTC+03:00 ,
im trying to get a date in string format, represented by NY timezone,
and convert it to a Date object in utc
const dateInNY = moment.tz(xlsxDate, "M/D/YYYY h:mm a", "America/New_York")
.tz("Z").toDate();
doesnt work correctly
how am i even suppose to convert to utc time?
-----------edit---------------
i got it to work, using the timezone "Africa/Accra" , where UTC offset is 0, and ther is no daylight savings time:
moment.tz(xlsxDate, "M/D/YYYY h:mm a", "America/New_York").tz("Africa/Accra")
but this solution is a bad workaround, and if the government of Accra decide to change the time laws, will stop working!
is there a way to set the utc offset to 0 in momentjs-timezones?
As Álvaro González mentioned, that Date object does not contain Time zone information.
I do the following:
new Date(moment.tz(date, currentTimezone).tz(newTimezone).format('YYYY/MM/DD HH:mm:ss'))
where date is a date object or a string (e.g. '2017-10-30 16:30:00.0000')
so, I change date from currentTimezone to newTimezone and after that new Date object will be returned
Let's change '2017-10-30 16:30:00.0000' from UTC to America/Toronto (UTC-4)
new Date(moment.tz(date, 'UTC').tz('America/Toronto').format('YYYY/MM/DD HH:mm:ss'))
And I got
Mon Oct 30 2017 12:30:00 GMT+0400
GMT+0400 is my timezone and console.log() just shows it with any
date object and it can mislead you. Please, don't look at the this
timezone.
Let's change '2017-10-30 16:30:00.0000' from Europe/Samara (UTC+4) to America/Toronto (UTC-4)
new Date(moment.tz('2017-10-30 16:30:00.0000', 'Europe/Samara').tz('America/Toronto').format('YYYY/MM/DD HH:mm:ss'))
Firstly, moment.tz undertands that date has no timezone information and associate with Europe/Samara (UTC+4)
timezone. After that computes difference between new and old
timezone (it's -8 hours in this case)
And returns result
Mon Oct 30 2017 08:30:00 GMT+0400
And answer on your question
If xsltDate is a date object or string which do not contain timezone information
dateUTC = new Date(moment.tz(xlsxDate, "America/New_York").tz("UTC").format('YYYY/MM/DD HH:mm:ss'));
If xsltDate contain timezone information (e.g.'2013-06-01T00:00:00-04:00'), then no need to tell moment.tz which timezone xlsxDate has, just mention a new timezone
dateUTC = new Date(moment.tz(xlsxDate, "UTC").format('YYYY/MM/DD HH:mm:ss'));
Short answer is that you cannot.
The .toDate() method of the Moment library returns a native Date object. Such objects do not keep memory of any specific time zone (that's one of the reasons to use Moment in the first place), they just keep track of the exact time moment represented and merely pick a time zone when formatting to string, which is either UTC or the browser's time zone (not an arbitrary one).
The long answer is that you're probably getting correct results but are printing them with a method that uses the browser's time zone.
i found a function that does what i was trying to do, it belongs to the momentjs library itself: utcOffset(n) sets the offset to n.
(i also had to explicitly write the date string format correctly, thanks VincenzoC)
this is the code i was trying to write:
const dateInNY = moment.tz(xlsxDate, "M/D/YYYY h:mm a", "America/New_York");
const dateUTC = dateInNY.utcOffset(0).toDate();
however, the toDate function changes the timezone to my local timezone anyway, so .utcOffset(0) is redundat, and i can just use moment this way:
const dateInNY = moment.tz(xlsxDate, "M/D/YYYY h:mm a", "America/New_York");
const dateUTC = dateInNY.toDate();
and change the Date objects date to utc time later (in my case, the JSON.stringify stuff i use later does that for me)

Categories

Resources