Moment TZ - Convert date into another timezone ISO string - javascript

I'm trying to convert a date in GMT to PST. The GMT date is 2022-11-16T00:00:00, therefore the PST date should be 2022-11-15T16:00:00.
My code is as follows:
const startDateGMT = moment(startTime).tz(myTimezone, true);
console.log('START DATE GMT IS', startDateGMT, startDateGMT.toISOString());
This outputs 8AM on the 16th, instead of 4PM on the 15th:
START DATE GMT IS Moment<2022-11-16T00:00:00-08:00> 2022-11-16T08:00:00.000Z
What am I doing wrong?

You can use the moment.tz constructor to parse the input time, using the timezone Etc/GMT as the timezone.
You can then call .tz() on the resulting date to convert to Pacific time.
The example below creates the dates and formats them along with the relevant UTC offset.
const gmtTime = '2022-11-16T00:00:00';
const gmtDate = moment.tz(gmtTime, 'Etc/GMT');
const pstDate = moment.tz(gmtTime, 'Etc/GMT').tz('US/Pacific');
console.log('GMT Date:', gmtDate.format('YYYY-MM-DD HH:mm:ssZ'))
console.log('PST Date:', pstDate.format('YYYY-MM-DD HH:mm:ssZ'))
<script src="https://momentjs.com/downloads/moment.js"></script>
<script src="https://momentjs.com/downloads/moment-timezone-with-data.js"></script>

Related

DayJS: Format and Convert an ISO Date/Time String to Local Timezone's Date/Time

I'm consuming an API which returns timestamps in this format 2023-02-18T14:54:28.555Z which is an ISO string. I need to format this value to the timezone of the user.
I've tried this:
dayjs("2023-02-18T14:54:28.555Z").format('YYYY-MM-DD HH:MM:ss A') // => "2023-02-18 20:02:28 PM"
The above output is incorrect and is 30 minutes behind for +0530 IST Timezone.
But when I input the same string "2023-02-18T14:54:28.555Z" to the JavaScript date constructor, I can see the correct value.
new Date("2023-02-18T14:54:28.555Z").toString() // => 'Sat Feb 18 2023 20:24:28 GMT+0530 (India Standard Time)'
How to get the correct formatted value for my Timezone using DayJS?
Tried feeding the ISO string to the DayJS constructor and expected it'll parse it to the current timezone. But the output value is 30 minutes behind.
you can use toLocaleString() method:
const timestamp = "2023-02-18T14:54:28.555Z";
const date = new Date(timestamp);
const options = { timeZone: 'Asia/Kolkata' };
const formattedDate = date.toLocaleString('en-US', options);
console.log(formattedDate);
Date.toString() displays the Date according to the local time of the OS. If you need the time to display in a zone other than the local time of the OS, then you'll have to use the DayJS Timezone plugin.
const dayjs = require('dayjs');
const utc = require('dayjs/plugin/utc');
const timezone = require('dayjs/plugin/timezone');
const timestamp = '2023-02-18T14:54:28.555Z';
dayjs.extend(utc);
dayjs.extend(timezone);
// Seattle time because my OS is set to America/Los_Angeles time.
const seattleString = Date(timestamp).toString();
const dayjsLocal = dayjs(timestamp);
const dayjsIst = dayjsLocal.tz('Asia/Calcutta');
const istString = dayjsIst.format('YYYY-MM-DDTHH:mm:ss');
console.log(seattleString); // Sun Feb 19 2023 02:43:42 GMT-0800 (Pacific Standard Time)
console.log(istString); // 2023-02-18T20:24:28

Momentjs showing same date for all timezones

I am trying to convert the DateTime by the user's browser using momentjs.
What is happening here:
let timezone = moment.tz.guess();
console.log('timezone:', timezone);
let iso_date = moment('06-04-2020 12:22:05 PM', 'MM-D-YYYY hh:mm:ss A').toISOString();
console.log('iso_date:', iso_date)
console.log('from timezone:', moment(iso_date).tz(timezone).format('lll'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://momentjs.com/downloads/moment.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.31/moment-timezone-with-data.min.js"></script>
I would like to convert the datetime as per user's browser. But no matter what I try, I am getting the same datetime without the change. How do I get different datestimes for different timezones?
Inputted date: 06-04-2020 12:22:05 PM', 'MM-D-YYYY hh:mm:ss A
Inputted timezone: America/Los_Angeles
Expected Output: Jun 4, 2020 12:22 PM
Inputted date: 06-04-2020 12:22:05 PM', 'MM-D-YYYY hh:mm:ss A
Inputted timezone: Asia/Calcutta
Expected Output: Jun 5, 2020 12:52 AM
Here is what is going on.
let iso_date = moment('06-04-2020 12:22:05 PM', 'MM-D-YYYY hh:mm:ss A').toISOString();
Creates a date from '06-04-2020 12:22:05 PM', treating the values as local, then returns an ISO 8601 string for the UTC version of that date, e.g. 2020-06-04T06:52:05Z.
console.log('from var:', moment(iso_date).tz(timezone).format('lll'));
Takes the ISO formatted string and parses it as UTC, then creates a timestamp for the local timezone. So it should produce the same date and time as the original timestamp.
All the code does is parse a timestamp as local, generate an equivalent UTC timestamp, then reverse the process by converting the UTC timestamp to a local timestamp.
How do I get different datestimes for different timezones?
Use a different location for parsing and formatting. If you use the same location for both, or locations with the same offset, then you'll get the same date and time back. It's exactly the same as doing:
let s = 'Fri Jun 05 2020 10:41:25';
let d = new Date(s);
let utc = d.toISOString();
console.log(
'Started with : ' + s +
'\nConverted to : ' + utc +
'\nBack to local: ' + new Date(utc).toString()
);

Create moment.js date from milliseconds in local timezone

A response I'm getting from the server is a 'local' timestamp.
Which would mean my local time expressed as UTC milliseconds, but without the UTC offset.
For example: 1537747200000 is Mon Sep 24 2018 00:00:00 UTC
Mon Sep 24 2018 03:00:00 EEST (my local time), but in my context, this date is actually Mon Sep 24 2018 00:00:00 EEST, so the utc value with my timezone.
I would now like to display this using moment and moment-timezone if needed.
So what I would like to know is how to create a new moment object that takes in "LOCAL milliseconds"? so I'd pass 1537747200000 and my local time zone if needed, and I could display it as Mon Sep 24 2018 00:00:00 EEST
I found that using moment timezone + utcOffset does the trick, but I don't really know if this is a good approach. utc offset docs says this:
Setting the UTC offset by supplying minutes. Note that once you set an offset, it's fixed and won't change on its own (i.e there are no DST rules). If you want an actual time zone -- time in a particular location, like America/Los_Angeles, consider moment-timezone.
Another approach would be to format the moment to ISOString moment(1537747200000).toISOString() and then parse the resulting string, without the timezone information (the 'z'). When parsing a string, you can parse it in another timezone. moment.tz(moment(1537747200000).toISOString().slice(0, -1), tz). But this requires that I parse->format->parse the value, so it's a lot of extra operations.
const [one, two, thr] = ["exp","tr","appr"];
const display = (toAdd, id) => document.getElementById(id).innerHTML += `<br/> ${toAdd}`;
const formatString = "MMM D, YYYY HH:mm z";
const tz = moment.tz.guess();
const millis_24_sep_00_00_utc = moment.utc("24-09-2018", "DD-MM-YYYY", true).valueOf(); //1537747200000
const isoString = moment(millis_24_sep_00_00_utc).toISOString();
//exp
display(tz, one);
display(millis_24_sep_00_00_utc, one);
const ex = moment.tz(millis_24_sep_00_00_utc, tz).utc().format("MMM D, YYYY HH:mm")
display(`${ex} ${moment().tz(tz).zoneAbbr()} <- local tz`, one);
//tr
[
moment(millis_24_sep_00_00_utc).tz(tz),
moment.utc(new Date(millis_24_sep_00_00_utc)).tz(tz),
moment.tz(millis_24_sep_00_00_utc, tz).utc(),
moment.tz(isoString, tz),
]
.forEach(mom => display(mom.format(formatString), two));
//some approaches
[
//setting utcOffset to 0
moment.tz(millis_24_sep_00_00_utc, tz).utcOffset(0),
//iso string to transform millis -> string -> parse the string in another tz
moment.tz(isoString.slice(0, -1), tz),
]
.forEach(mom => display(mom.format(formatString), thr));
<!DOCTYPE html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.19.1/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.21/moment-timezone-with-data.js"></script>
<title>Test</title>
</head>
<body>
<div id="exp">EXPECTED</div>
<hr/>
<div id="tr">TRIES</div>
<hr/>
<div id="appr">APPROACHES</div>
</body>
</html>
It's unusual to provide a millisecond time value that has been offset. But if your time values are offset by +3 hours then you can subtract 3 hours worth of milliseconds (1.08e7) and use it as a UTC time value.
E.g. A time value of 1537747200000 typically represents 2018-09-24T00:00:00.000Z. If that time value actually represents 2018-09-24T00:00:00.000+0300, then the equivalent UTC time value is:
1537747200000 - 1.08e7 = 1537736400000;
Working example:
var d = new Date(1537747200000 - 1.08e7);
console.log(`Zulu: ${d.toISOString()}\nLocal: ${d.toString()}`);

How to specify timestamp format when converting to human readable string in JS

I need to display a formatted date from a timestamp provided by Google Analytics
Standard solution like
var date = new Date(timestamp * 1000);
var formatted = date.toString();
produces wrong value Jan 01 1970. That's because of timestamp format.
In PHP I can specify the timestamp format:
\DateTime::createFromFormat('Ymd', $timestamp);
How to do this in JS?
Since the dates you are receiving are formatted as YYYYMMDD, not as a Unix
timestamp, you can parse it by
extracting the year, month and date using String.prototype.slice.
var timestamp = '20170306',
year = parseInt(timestamp.slice(0, 4), 10),
month = parseInt(timestamp.slice(5, 6), 10),
day = parseInt(timestamp.slice(7, 8), 10);
// - 1 because the Date constructor expects a 0-based month
date = new Date(Date.UTC(year, month - 1, day)),
gmt = date.toGMTString(),
local = date.toString();
console.log('GMT:', gmt); // Mon, 06 Mar 2017 00:00:00 GMT
console.log('Local:', local);
This assumes that the dates you are using are in UTC (which they likely are). Date.UTC creates a timestamp (in milliseconds since Unix epoch) and then feeds it into new Date() which uses it to create a Date object representing that time. .toGMTString() outputs the date formatted for the GMT timezone. To output it formatted in local time, use .toString() instead.
try this type:
var userDate = new Date();
var day = userDate.getDate();
var month = userDate.getMonth() + 1;
var year = userDate.getFullYear();
alert("Date Formate is :"+year+"-"+month + "-" + day);
In javascript you can use an external library like moment.js
var date = moment.unix(timestamp);
date.format("YYYY MM DD");
See detail about .format here https://momentjs.com/docs/#/displaying/format/

UTC date convert to local timezone

I have a date in UTC format.
"2016-10-12 05:03:51"
I made a function to convert UTC date to my local time.
function FormatDate(date)
{
var arr = date.split(/[- :T]/), // from your example var date = "2012-11-14T06:57:36+0000";
date = new Date(arr[0], arr[1]-1, arr[2], arr[3], arr[4], 00);
var newDate = new Date(date.getTime()+date.getTimezoneOffset()*60*1000);
var offset = date.getTimezoneOffset() / 60;
var hours = date.getHours();
newDate.setHours(hours - offset);
return newDate;
}
My Local timezone is GMT +0530.
My code produced this output:
Tue Oct 11 2016 10:33:00 GMT+0530 (IST)
I converted the date with an online tool to get the correct date and time.
Wednesday, October 12, 2016 10:30 AM
My code matches the online tool on time but not on date.
How can I correct my code's output, preferably using moment.js?
UTC is a standard, not a format. I assume you mean your strings use a zero offset, i.e. "2016-10-12 05:03:51" is "2016-10-12 05:03:51+0000"
You are on the right track when parsing the string, but you can use UTC methods to to stop the host from adjusting the values for the system offset when creating the date.
function parseDateUTC(s){
var arr = s.split(/\D/);
return new Date(Date.UTC(arr[0], arr[1]-1, arr[2], arr[3], arr[4], arr[5]));
}
console.log(parseDateUTC('2016-10-12 05:03:51').toLocaleString());
If you want to use moment.js, you can do something like the following. It forces moment to use UTC when parsing the string, then local to write it to output:
var d = moment.utc('2016-10-12 05:03:51','YYYY-MM-DD HH:mm:ss');
console.log(d.local().format());
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.0/moment.js"></script>
Since you have tagged moment, I'm assuming you are using moment.
In such cases, you should keep your approach consistent and not mix moment and date object.
var dateStr = '2016-10-12 05:03:51';
var timeZone = "+0530";
var date = moment.utc(dateStr).utcOffset(dateStr + timeZone)
console.log(date.toString())

Categories

Resources