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".
Related
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.
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>
I've been trying to display the local date and time after parsing ISO string to local timestamp based on navigator.language.
let sampleDate = new Date('2018-11-29T09:54:46.863207Z').toLocaleString(navigator.language);
So when I change the browser language preferences it reflects the date format in proper locale, but this doesn't seem to work with time part of the ISO string.
Result with browser locale en-AU--
Data Last Updated at 29/11/2018, 3:24:46 pm
Result with browser locale en-US -- Data Last Updated at 11/29/2018, 3:24:46 pm
See how only the date format changes based on the locale.It doesn't seem to affect the time component of the ISO 8601 string.
I've tried using moment.js to get the display the date and time in browser locale format but didn't find much success.
Am I missing something here?
It looks like you are trying to take a UTC date string, convert it to the client browser's local date and time, and format the date based on locale. You may be overthinking it a bit as JavaScript does most of this for you as long as you correctly create the Date object.
It is not recommended to parse date strings with the new Date() constructor, so the code example below uses a little regex and unpacking to parse the date string, then you can create the date in UTC with new Date(Date.UTC(...)). At that point, JavaScript will represent the date object in the client browser's local date and time automatically, then you can use toLocaleString() to apply formatting for the client browser's locale. For example:
const s = '2018-11-29T09:54:46.863207Z';
const [y, m, d, hh, mm, ss, ms] = s.match(/\d+/g);
const date = new Date(Date.UTC(y, m - 1, d, hh, mm, ss, ms));
const formatted = date.toLocaleString();
console.log(formatted);
If you need the Date for a particular time zone:
date.toLocaleDateString('en-AU', {timeZone: 'Australia/Sydney'})
date.toLocaleDateString('en-US', {timeZone: 'America/New_York'})
You can try this
console.log(
(new Date).toLocaleString('en-AU', {timeZone: 'Australia/Sydney'}) + "\n" +
(new Date).toLocaleString('en-US', {timeZone: 'America/New_York'})
)
18/10/2021, 10:05:25 pm
10/18/2021, 7:05:25 AM
I'm getting a date as a string, in the following format (for example):
"11/10/2015 10:00:00"
This is UTC time.
When I create Date from this string, it consider it as local time:
let time = "11/10/2015 10:00:00";
let date = new Date(time);
console.log(date);
it prints:
"Tue Nov 10 2015 10:00:00 GMT+0200"
(instead of considering it as UTC: "Tue Nov 10 2015 10:00:00")
I also tried moment.js for that.
is there a good way to make Date() consider the string a UTC, without adding "Z"/"UTC"/"+000" in the end of the string?
You can use the built-in Date.UTC() function to do this. Here's a little function that will take the format you gave in your original post and converts it to a UTC date string
let time = "11/10/2015 10:00:00";
function getUTCDate(dateString) {
// dateString format will be "MM/DD/YYYY HH:mm:ss"
var [date, time] = dateString.split(" ");
var [month, day, year] = date.split("/");
var [hours, minutes, seconds] = time.split(":");
// month is 0 indexed in Date operations, subtract 1 when converting string to Date object
return new Date(Date.UTC(year, month - 1, day, hours, minutes, seconds)).toUTCString();
}
console.log(getUTCDate(time));
Your date is parsed by the date constructor, in MM/DD/YYYY format, applying the local timezone offset (so the output represents local midnight at the start of the day in question). If your date really is MM/DD/YYYY, all you need to do is subtract the timezone offset and you'll have the UTC date...
var myDate = new Date("11/10/2015 10:00:00");
myDate = new Date( myDate.getTime() - (myDate.getTimezoneOffset()*60*1000));
console.log(myDate.toLocaleString([],{timeZone:'UTC'}))
Here's everything I know about managing timezone when serializing and deserializing dates. All the timezone handling is static! JS dates have no intrinsic timezone.
You can use Date.UTC for this but you will have to parse your string and put every part of it as args by yourself as it can't parse such string. Also you could use moment.js to parse it: Convert date to another timezone in JavaScript
Also, seems like new Date("11/10/2015 10:00:00 GMT") parses date as a GMT and only after that converts it to PC local time
Easy answer is to append a "Z" at the end without changing the variable:
let time = "11/10/2015 10:00:00";
let date = new Date(time + "Z");
console.log(date);
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)