new Date(year, month, date) in node js is automatically getting converted to UTC timezone
Asked Answered
T

6

6
    var dateInCST; //Getting CST date as input.

    /*Triming the time part and retaining only the date.*/
    var onlyDateInCST = new Date(dateInCST.getUTCFullYear(), dateInCST.getUTCMonth(), dateInCST.getUTCDate()); 

    console.log(onlyDateInCST);

I'm in +5:30 i.e IST time zone.

During the date creation by providing year, month and date, the node js is treating it as IST and deducting -5:30 automatically.

Node js is converting the date to UTC automatically by considering the date to be at server timezone. But in browser I'm getting proper CST date without time.

Example :

var today = new Date(2017, 2, 7);
console.log(today);

The date should be 2017-03-07T00:00:00.000Z. But node js deducts the server time zone difference between UTC i.e +5:30 from this date and the date object becomes 2017-03-06T18:30:00.000Z

Why the above code is behaving different in Node js from browser. Any workaround for this?

Edit :

var date = new Date();
function createDateAsUTC(date) {
    return new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds()));
}
console.log(date);
console.log(createDateAsUTC(date));

NodeJs output :

2017-03-08T12:28:16.381Z

2017-03-08T17:58:16.000Z

Browser Output :

Wed Mar 08 2017 17:58:17 GMT+0530 (India Standard Time)

Wed Mar 08 2017 23:28:17 GMT+0530 (India Standard Time)

There is difference between Node js behaviour and browser. The server(local) time was 17:58.

What's the difference between new Date(?,?,?,?,?,?) and new Date(Date.UTC(?,?,?,?,?,?)) ?

Thar answered 6/3, 2017 at 16:44 Comment(7)
What do you get if you do console.log(dateInCST);? Do you get the same date as you send?Thereabouts
It depends on the server timezone, if it is set to UTC it will always shows in date and time in UTC timezone, similarly browser also behaves in same way(gets the timezone from OS)Furtherance
@PavanKumarJorrigala I'm running this in local system. The timezone of my system is IST i.e +5:30. I've given more detail in the question.Thar
You might want to look at Date.UTC().Vendue
One can't create a variable like dateInCST using the Date object alone. The Date object is always UTC internally, and uses the local time zone for conversions... You can do this with moment.js, but not a raw Date.Idocrase
@MattJohnson The dateInCST is nothing but deducting "-06:00" or "-05:00" hour from the dateInUTC. Though the timezone is will not be in CST, but the dateInCST represent the CST hour and date.Thar
That technique is called "epoch shifting". It only works reliably if you are very strict about using only the UTC-based functions. If you try to shift local time, errors will occur around any DST transitions of the local time zone. Be careful - thar be dragons here. :)Idocrase
F
5

Nodejs is representing in ISO 8601 format

Z is the zone designator for the zero UTC offset. "09:30 UTC" is therefore represented as "09:30Z" or "0930Z"

In your case

var today = new Date(2017, 2, 7);

2017-03-06T18:30:00.000Z Its valid, because it is representing in UTC.

May be default date format in nodejs is yyyy-mm-ddThh:mm:ss.fffZ, if you change it to yyyy-mm-ddThh:mm:ss.fffZ+|-hh:mm it will show as 2017-03-07T00:00:00.000+05:30


Update

I ran the same date and timezone as yours, On my machine it is not showing ISO 8601 format, it only showed with toISOString() method

var today = new Date(2017, 2, 7);
console.log(today); --> Tue Mar 07 2017 00:00:00 GMT+0530 (India Standard Time)
console.log(today.toISOString()); --> 2017-03-06T18:30:00.000Z

to replicate I added moment.js

var today = new Date(2017, 2, 7);
console.log(moment(today).format()); --------> 2017-03-07T00:00:00+05:30
console.log(moment(today).utc().format()); --> 2017-03-06T18:30:00Z
Furtherance answered 7/3, 2017 at 19:33 Comment(1)
How to change the default format in Node js to "yyyy-mm-ddThh:mm:ss.fffZ+|-hh:mm" ?Thar
S
5

If yo want exact same as in Browser Just convert it to string by calling toString method like following. Then you will get correct date as you expected.

(new Date()).toString();

Shop answered 3/8, 2017 at 13:9 Comment(0)
L
4

When you create a Date object (regardless of whether in browser or in Node.js), the instance is created with the date being interpreted as local to the current timezone. See the second note in MDN docs.

If you would like to create the date in UTC right away, you must use

new Date(Date.UTC(...))

Date.UTC() has the same input semantics as new Date().

Another thing to note here is that printing the date instance to the console will cause the date to be represented as an ISO timestamp which is always in UTC. You may wish to inspect the date object by printing date.toString() or date.toLocaleString() which will show the date in the current timezone.

Lupercalia answered 7/3, 2017 at 19:44 Comment(2)
Why is it that my NodeJS is always returning UTC when I do new Date()?Auspicious
Most likely because your Node.js thinks it is in the UTC timezone. Maybe your computer is set up that way?Lupercalia
P
1

You can append the string "UTC" at the end of date string passed in new Date() eg:

var date= new Date("2019-2-21 UTC")

now var date will be in local time

var d = new Date();
var date = new Date(d + 'UTC');
console.log(d)// date in UTC 
console.log(date)// date in localtime

`

Pola answered 21/2, 2019 at 5:15 Comment(1)
Returns an invalid date in Safari at least. See Why does Date.parse give incorrect results?Laceylach
D
1
const test = new Date();
const test1 = new Date(test.setUTCHours(0,0,0,0));
Deterioration answered 6/6, 2019 at 5:24 Comment(0)
P
0

Date() is returning you an integral number that represent the ms since epoch, in the timezone of your process.env.

new Date(2017, 2, 27) means "Give me the moment of time of 2017-02-27 00:00:00 in my current timezone". That's how this constructor works. It does not give you the start of date in UTC time and it should not because we only care about own timezone most of the time. Think about this, when I ask you what time it is now, you gonna answer me it's 9:30am (in IST, not UTC time) instead of giving me a UTC time that doesn't make sense to me.

Let's make clear few concepts:

  • Date object in JS represent a moment of time. This can be simply stored as a integer in epoch time.
  • There is no timezone concept in a moment of time. Regardless where you are in the world, the moment of time is all the same. (Although Einstein will not agree with this...)

Timezone represents the same moment of time in different way. Below 2 times are the exact same moment of time:

  • UTC: 2017-02-26T18:30:00.000Z (the ending Z means UTC time)
  • IST: 2017-02-27 00:00:00.000 GMT-5.5

Now let's explain this concept in below code:

process.env.TZ = "Asia/Kolkata";
const date = new Date(2017, 2, 27);

// Epoch: 1490553000000
console.log("Epoch:", date.getTime());

// ISO: 2017-03-26T18:30:00.000Z
console.log("ISO:", date);

// Locale: Mon Mar 27 2017 00:00:00 GMT+0530 (India Standard Time)
console.log("Locale:", date.toString());

Above 3 functions are returning the same moment in time, but in different representation.

What you asking is to get the moment in time of the start of the day in UTC+0. Using date-dns-tz is the easiest way.

import { zonedTimeToUtc } from "date-fns-tz";

// Given the date (2017-01-27) of time zone (UTC), return me a Date object of a moment of time.
// This function name is confusing.  Should just be named as zonedTime.
const date = zonedTimeToUtc("2017-01-27", "UTC");

// Epoch: 1485475200000
// Again, no timezone is involved in this pure epoch time.
// Epoch converter websites will tell you this time is 2017-01-27 12:00:00 AM UTC and 2017-01-27 05:30:00 AM India Time
console.log("Epoch:", date.getTime());

// ISO: 2017-01-27T00:00:00.000Z
// This is the same moment of time represented in UTC
console.log("ISO:", date);

// Locale: Fri Jan 27 2017 05:30:00 GMT+0530 (India Standard Time)
// This is the same moment of time represented in IST
console.log("Locale:", date.toString());

Now to answer your real question. All the above is not what you are looking for.

I guess what you really want is date, but not moment of time. Timezone is irrelevant to your case. Even time is irrelevant to your case. This is a very common requirement.

Using Date object is conceptually not right and over complicated the whole thing. Date represents the exact moment of time in millisecond level (even smaller actually, can have a philosophical debate here). What you want is probably something like today is 2017-02-27.

You can consider below 2 better options:

  • Store the Date (moment of time) along with the timezone. You need this if it's a global system that involves multiple time zones.
  • Store it as string in YYYY-MM-DD format. I prefer this. Makes things a lot easier.
Prevail answered 29/10, 2023 at 10:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.