Convert Javascript date to UTC with timezone information - javascript

I have a UI that allows a user to create an event. When the user creates this event they select a date( and time) and separately they select a timezone (eg. 'America/New_York') for the event location.
I need to use the date (includes time) and the selected timezone (string) to create a UTC date. I'm not sure how to do this.
I thought about using getTimezoneOffset but doesn't this change depending on the time of year ( British Summer Time etc).
Update. I wasn't very clear in my explanation, so here is more detail:
User selects date and time of an event that is 'Jan 01 2017 07:00:00'.
They then select the timeZone of 'America/New_York'. It's happening at 7am in New York but I'm in the UK.
When I do:
const formatDate = moment.tz( new Date('Jan 01 2017 07:00:00'), 'America/New_York' ).format(); //returns '2017-01-01T02:00:00-05:00'
if I convert this date in new york to my local date with:
new Date( formatDate ); // returns 'Sun Jan 01 2017 07:00:00 GMT+0000 (GMT)'
I want it to return a local date and time of 'Sun Jan 01 2017 12:00:00 GMT+0000 (GMT)'.

From docs:
If you want an actual time zone -- time in a particular location, like
America/Los_Angeles, consider moment-timezone.
This suggests the feature is not built-in into Moment.js itself but the other library should get it done:
var newYork = moment.tz("2014-06-01 12:00", "America/New_York");
var losAngeles = newYork.clone().tz("America/Los_Angeles");
var london = newYork.clone().tz("Europe/London");
newYork.format(); // 2014-06-01T12:00:00-04:00
losAngeles.format(); // 2014-06-01T09:00:00-07:00
london.format(); // 2014-06-01T17:00:00+01:00
Beware that you should still store the named time zone in another column, because there's no way to deduct it from the date stored in MySQL.

I did it in the end with the following:
const momentTimezone = require( 'moment-timezone' );
const DateWithOffset = require( 'date-with-offset' );
module.exports = function( date, timezone ) {
const offset = momentTimezone.tz.zone( timezone ).offset( date );
const newDate = new DateWithOffset( date.toUTCString(), ( 0 - offset ) );
return newDate.toISOString();
};
There may be a better way of doing this, but this seems to work. I used the npm module date-with-offset which did the job required.

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

Format Date based on Browser time zone (VueJs/JS)

I have a Date in string Format: 2020-07-13 7:07 AM (which is indian time). I need to change this time based on browser time zone which can be either in US or Africa.
I have tried following ways, but i am not able to convert it correctly.
Attaching my steps:
var d = "2020-07-13 7:07 AM";
var date = new Date(d); //Mon Jul 13 2020 07:07:00 GMT+0530 (India StandardTime)
var date1 = moment(date, 'YYYY-MM-DD HH:mm T'); //undefined
Please help me out. I havee to this in both VueJs and Javascript
You should convert your timestamps to an ISO 8601 format including the UTC-offset. This can be done for instance using new Date().toISOString(). Then you can feed the timestamp into moment or, if you want to display the time for a different timezone, have a look at moment-timezone
I figure out the answer in this way:
var buildDate = "2020-07-13_7:07";
let releaseDate = buildDate .split('_');
let date = moment(date);
let newDate = moment(new Date(date.get('year'), date.get('month'), date.get('date'), date.get('hour'), date.get('minute'))).add(new Date().getTimezoneOffset()*-1, 'm').toDate();
let result = moment(newDate).format('MMM DD YYYY h:mm A');

How to change ISO date to Standard JS Date?

I am trying to change an ISO date to a Standard JS Date format. The JS format I am referring to is:
Mon `Jul 20 2020 14:29:52 GMT-0500 (Central Daylight Time)`
What is the best way to go about doing this? Thanks!
const ISO_DATE = '2020-07-14T23:02:27.713Z';
function formatDate(dateStr) {
const date = new Date(dateStr);
return date.toString();
};
console.log(formatDate(ISO_DATE));
One way is:
let isoDate = "2020-07-20T14:29:52Z";
var myDate = new Date(isoDate);
console.log(myDate.toString()); // Mon Jul 20 2020 17:29:52 GMT+0300 ( (your time zone)
console.log("Back to ISO Date: ", myDate .toISOString());
If you want to convert it back to ISO Date use:
console.log(myDate.toISOString());

Javascript : Increase a Date object by a year

I'm assign a new date object to my object attribute like that :
giftObject.purshasedDate = new Date()
which give a date format :
Date Thu Feb 20 2020 13:36:37 GMT+0100 (heure normale d’Europe
centrale)
I want to increase this date by one year, I tried :
new Date().setFullYear(giftObject.purshasedDate.getFullYear() + 1) but it give a number serial like this : 1613824899244
I do not understand what that number serial mean! it's a date or should a try some thing else ?
By default all dates object are timestamps.
JavaScript Date objects represent a single moment in time in a
platform-independent format. Date objects contain a Number that
represents milliseconds since 1 January 1970 UTC.
Source : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date
I think the default new Date() object can display itself to string by in fact it's also a timestamp.
If you want to display a date as string, you have to use the toLocaleString() method on Date.
I tried by updating the original date and it return the string of the date, don't know why but it's work by updating the original date.
Example :
let giftObject = {};
giftObject.purshasedDate = new Date();
giftObject.purshasedDate.setFullYear(giftObject.purshasedDate.getFullYear() + 1);
console.log(giftObject.purshasedDate)
Result : "20/02/2021 à 13:55:49" for my French browser
const oldDate = new Date("Date Thu Feb 20 2020 13:36:37 GMT+0100")
const newDate = oldDate.setFullYear(oldDate.getFullYear() + 1)
const dateWithPlusOneYear = new Date(newDate)
console.log(new Date(dateWithPlusOneYear))
//Sat Feb 20 2021 13:36:37 GMT+0100 (Central European Standard Time)
Please use this one:
purshasedDate = new Date();
purshasedDate = new Date(purshasedDate.setFullYear(purshasedDate.getFullYear() + 1));

Unable to get the first day of the Month in Angular 2/4

I'm calculating the dates for my application like date,week,month.
First I am defining day,week,month,custom like:
this.reportTypes = [{TypeId: 1, Type: 'Day'}, {TypeId: 6, Type: 'Week'}, {TypeId: 30, Type: 'Month'}, {
TypeId: 10,
Type: 'Custom'
}]
Next I'm defining dates like:
var currdate = new Date();
if(reportType==1){
// this.reportDataFromDate=currdate;
// this.reportDataToDate=currdate;
//This is for setting the current date
this.reportDataFromDate= currdate;
this.reportDataToDate= currdate;
}
else if(reportType==30){
var First = new Date(currdate.getFullYear(),currdate.getMonth(),1);
this.reportDataFromDate=First;
this.reportDataToDate=currdate;
}
else if(reportType!=10){
var last = new Date(currdate.getTime() - (reportType * 24 * 60 * 60 * 1000));
this.reportDataFromDate=last;
this.reportDataToDate=currdate;
}
}
The problem is after selecting reportType == 30 then it has to get the first day of the month.
It is showing the date as 1-Dec-2017 but it is getting the data of till 30th November 2017?
This is screenshot of the SQL server. I'm sending the date as 1st Dec 2017 but it is getting 30-11-2017.
When the Date() constructor is invoked with integers, the result is a date object with that date assumed your systems (read browser/os) timezone.
Example:
let d = new Date(2017);
// returns Thu Jan 01 1970 01:00:02 GMT+0100 (W. Europe Standard Time)
// and with d.toUTCString(): Fri, 30 Dec 2016 23:00:00 GMT
Which may end up in an entire different year when sending to the server
Using the string constructor and specifying timezone will help you overcome this.
Example:
let d = new Date('2017z');
// returns Sun Jan 01 2017 01:00:00 GMT+0100 (W. Europe Standard Time)
// and with d.toUTCString(): Sun, 01 Jan 2017 00:00:00 GMT
The latter which is what you should pass to a server, and normally do calculations on.
However, note that calculations with dates are a complicated matter best left to a library like moment.js. To get a feel of what you are dealing with have a look at this great talk from the WebRebel conference.
So to actually give an answer to your title, try this example which creates the date in a simple string using UTC:
let d = new Date(currdate.getUTCFullYear() + ' ' +(currdate.getUTCMonth() + 1) + ' 1z');
d.getUTCDay(); // returns the day as an integer where Monday is 0.
Note that we add 1 month due to getUTCMonth() returns January as 0.
Why the difference?
The new Date(x,y,z) constructor treats the parameters as local date values.
See MDB Web Docs - Date
Note: Where Date is called as a constructor with more than one argument, the specifed arguments represent local time. If UTC is desired, use new Date(Date.UTC(...)) with the same arguments.
But, under the hood the date is stored as UTC (milliseconds since 1 Jan 1970).
const date = new Date(2017, 11, 29);
console.log('valueOf()', date.valueOf()) // 1514458800000
and the UTC date is different to your local date (see trailing 'Z' indicates UTC)
const date = new Date(2017, 11, 29);
console.log('date', date) // "2017-12-28T11:00:00.000Z" (trailing 'Z' means UTC)
// The difference in minutes between browser local and UTC
console.log('getTimezoneOffset()', date.getTimezoneOffset() )
and when you send it to the server, JSON sends it as UTC
const date = new Date(2017, 11, 29);
console.log('JSON', date.toJSON())
// JSON will yield string version of UTC === 2017-12-28T11:00:00.000Z
How to fix it
Well, you might decide that you actually want the date/time in local, and conclude it's not broken.
But if you want to send UTC to the server, wrap the parameters in Date.UTC()
const date = new Date(Date.UTC( 2017, 11, 29 ))
console.log('date.toJSON()', date.toJSON() ) // 2017-12-29T00:00:00.000Z
What about month parameter === 11?
From the MDB page referenced above,
Note: The argument month is 0-based. This means that January = 0 and December = 11.
If you are using .Net Web API as backend, you can config the timezone in Web API WebApiconfig.cs like below. It will serialize the time in UTC.
public static void Register(HttpConfiguration config)
{
config.Formatters.JsonFormatter.SerializerSettings.DateTimeZoneHandling = Newtonsoft.Json.DateTimeZoneHandling.Utc;
}
Or use
config.Formatters.JsonFormatter.SerializerSettings.DateTimeZ‌​oneHandling = Newtonsoft.Json.DateTimeZoneHandling.RoundtripKind; //Time zone information should be preserved when converting.

Categories

Resources