javascript new Date() or moment.js parse date wrong - javascript

I have a DateTime value that comes from server in the following format:
2015-08-16T01:29:00.000Z
However when I do
new Date('2015-08-16T01:29:00.000Z')
the result is this:
Sun Aug 16 2015 04:29:00 GMT+0300 (FLE Daylight Time)
please notice the hour is wrong, instead of 01:29 AM is 04:29 AM
Same for moment.js it get's the wrong hour.
How can I solve this?

It's the same time -- the server gives it to you as UTC (hence the Z at the end) and Javascript then helpfully shows it in the local timezone of the browser, FLE Daylight Time. Given that both times clearly state which timezone they are, nothing is going wrong, strictly speaking.
What to do depends on what you want exactly. By doing
moment.utc('2015-08-16T01:29:00.000Z');
You put moment.js in UTC mode, showing everything in UTC (if I understand the docs correctly).

Related

When formatting date object - does it matter that the T and the 000Z will be removed when storing to db?

Sorry if its a very basic question but I dont understand the following:
When I format the Date object (no matter what library I used), I get a string.
from this: 2022-11-28T16:55:44.000Z (new Date object)
I get this: 2022-11-28 16:55:44 (or other formats obviously depending how I format it)
Even if I turn it back into an object it, the T and 000Z will never be there anymore. Do I just ignore that (seems like it as any library or date methods are ignoring the T and the string ending when formatting) or do I add it 'back' Isnt it a problem if dates stored in my db are different (for later queries etc.)?
The Z indicates UTC (Coordinated Universal Time, also known as Greenwich Meridian Time), dropping that changes the meaning - unless your browser or server lives in the Greenwich time zone and it is winter (no daylight saving time).
You can convert back and forth between a Date object and a UTC string as follows (my browser lives in the Central European time zone):
> utc = '2022-11-28T16:55:44.000Z'
'2022-11-28T16:55:44.000Z'
> d = new Date(utc)
Mon Nov 28 2022 17:55:44 GMT+0100 (Central European Standard Time)
> d.toISOString()
'2022-11-28T16:55:44.000Z'
Alternatively, you can convert back and forth between a Date object and a formatted string in your browser's or server's time zone (the last line shows that my browser's format differs from yours):
> formatted = '2022-11-28 17:55:44'
'2022-11-28 17:55:44'
> d = new Date(formatted)
Mon Nov 28 2022 17:55:44 GMT+0100 (Central European Standard Time)
> d.toLocaleString()
'11/28/2022, 5:55:44 PM'
But you should not store the Date objects in this format in a database, unless you can guarantee that they are always read and written in the same time zone. For example, if you format a Date object with your browser (in CET) and store it, then someone else who reads it and converts it back to a Date object with their browser in the New Zealand time zone will see a wrong value. Also, dates like 9/11/2022 are ambiguous if the formatting rules are not clear (September 11th or November 9th?).
That's why I would prefer UTC strings when storing Date objects and use formatted strings only for outputting them to the user and for parsing user input.
I see it even stronger: You should never store dates as strings, it's a design flaw. Store always proper Date objects. Here on SO you can find hundreds of questions, where people have problems, because they stored date values as (localized) strings. It is not limited to MongoDB, it applies to any database.
Date objects in MongoDB are UTC times - always and only! Usually the client application is responsible to display the date/time in local time zone and local format.
What do you mean by "turn it back", i.e. how do you do it?
You should not rely on new Date(<string>) without time zone. Some browsers/environments may apply UTC time, others may use current local time zone, see Differences in assumed time zone
Have a look at 3rd party date libraries, e.g. moment.js, Luxon, or Day.js. Usually they provide better control how to parse strings and time zones.

String to date converter issue in js

My local machine in EST timezone.
I'm trying to convert date string to date object in js but getting an day before from date string in date object.
new Date('2020-04-03') for this i'm getting Thu Apr 02 2020 20:00:00 GMT-0400 (Eastern Daylight Time) this output.
new Date('2020/04/03') for this i'm getting Fri Apr 03 2020 00:00:00 GMT-0400 (Eastern Daylight Time) this output.
console.log(new Date('2020-04-03'))
console.log(new Date('2020/04/03'))
I don't know what is the difference between these can anyone explain that?
How i fix this issue?
The reason why the two date parsings give you different results is because it's triggering two different date handling modes.
In one case, 2020-04-03, it's treating the date as an simplified version of ISO 8601 format, for which JavaScript creates a date in the UTC time zone if no time zone is specified.
The second date, 2020/04/03, is not in an officially supported format, so JavaScript falls back to an implementation-specific parsing of the date, so it may not even be consistent across browsers. In that case, it's choosing to use your local time zone.
The MDN article on Date.parse() offers a detailed explanation of how date parsing works in the JavaScript standard and how non-standard behaviors exist among browsers in some cases.
In short, it's a good idea to stick with ISO 8601 dates whenever possible, not only because JavaScript handles them in a consistent way, but they're also easily sorted, and they're widely supported across many programming systems.
Try new Date('2020-04-03 00:00:00')
By default, the date string is parsed in UTC timezone. When you output a date, by default it converts it to your local timezone set by your browser.
To solve, you can enter your date as the UTC equivalent, or simply do as the others have stated here and include the timezone in your date string
let date = new Date('2020-04-03 EST');

convert local timezone timestamp to UTC timestamp

My server returns date data as local timezone timestamps.
On the client-side, I want to display those dates as local date strings. If I do the following, I got the wrong date ("6/30/2014" instead of "7/01/2014")
var ts = 1404172800;
new Date(1404172800*1000).toLocaleDateString()
>>>"6/30/2014"
To prevent this problem, I suppose I have to convert the local timezone timestramp I receive from the server to UTC timestamp before creating the new Date() object.
Am I right? What is the best way to achieve that that will work in most browsers?
Edit:
I confirm that the real date in local time zone should be 7/01/2014. That's local Eastern time UTC -5(-4). but the new Date() object thinks this is UTC but it's not. I suppose it's because the date is returned as a timestamp without having been converted to UTC.
Isn't that right already? Timestamps are always in UTC.
You're seeing 30th June and not 1st of July because when that event happened, in the local time zone, it was still 30th of June. For example, for me it is showing as 1st of July in IST.
Also, this timestamp represents an event which occurred at 1st July 2014 at 00:00:00 GMT exactly. India is GMT+05:30, as you can see in the screenshot - so if the local timezone, even if it is GMT minus one minute, it would still be 30th of June there.

Does JavaScript's Date object automatically handle daylight savings?

I am investigating an issue involving the conversion of serialized UTC dates in to JavaScript date objects; I have read a few questions on this topic already but I am still unclear.
Firstly let me say that I am in the UK. If I take for example the UTC epoch 1473805800000, which is Tue, 13 Sep 2016 22:30:00 GMT, then use that value to create a JavaScript date:
var date = new Date(1473805800000);
console.log(date);
The console logs:
Tue Sep 13 2016 23:30:00 GMT+0100 (GMT Summer Time)
I.e. the browser has recognised that an extra hour needs to be added for DST.
My question is, if I were to run this same code again after the 30th October when the clocks have gone back, would I still get the same result of 23:30, or would it be 22:30 as if it were GMT? In other words, has the browser added an hour because the subject date is DST or because we are currently in DST?
I'm prevented from altering my work station's system clock by group policy, otherwise I would skip it forward in time and test this myself.
Javascript Date objects use a time value that is an offset in milliseconds since 1970-01-01T00:00:00Z. It is always UTC.
If the Date constructor is given a single number argument, it is treated as a UTC time value, so represents the same instant in time regardless of system time zone settings.
When you use console.log(date), the built–in toString method is called which generates an implementation dependent string, generally using the current time zone setting of the host system to create a convenient, human readable string.
The current daylight saving rules in the system are used to determine the offset to use for "local" time, so if the date changes from a time when daylight saving applies to one when it doesn't, the time zone offset will be similarly adjusted (note that daylight saving offsets aren't always 1 hour). It does not matter what the current system offset is, the one used is based on the setting for the date and time that the time value represents.
Also, Date objects are very simple, they're just a time value. The time zone offset comes from system settings, it's not a property of the Date itself.
So, given:
My question is, if I were to run this same code again after the 30th
October when the clocks have gone back, would I still get the same
result of 23:30, or would it be 22:30 as if it were GMT?
the answer is "yes", it will still be 23:30 since on 13 September BST applies. It doesn't matter when the code is run, only what the system offset setting is for that date.
In your case, the Date was created using epoch 1473805800000 and converted to your timezone GMT+0100. Epoch is always UTC time, therefore it was read as UTC and converted to your current timezone.
On September 13 2016, GMT+01 had summer time, therefore it was considered in the calculus.
In my case, I get the following, running the same code as yours:
Thu Sep 15 2016 14:13:14 GMT-0300 (E. South America Standard Time)

Moment.JS using timezone

I'm using momemt.js and moment-timezone.js to output time in the browser. Now I'm working with epoch time sent from the server this epoch has been converted to central. Now I want to display the time in EST/EDT. I have moment().tz("America/New_York").format(); and moment.unix(val.departure_time).format("h:mm a"); to format my time. The problem is that the times in the client are in central (1 hour behind eastern time). What am I doing wrong?
I'm not very familiar when working with dates so please be gentle :)
When you call moment() - that is getting the current time. You don't appear to be assigning it to anything.
It's hard to tell from the wording of your question, but I assume val.departure_time is the Unix Epoch-based time, as an integer number of seconds since Jan 1, 1970 UTC. If so, you probably want to do this:
moment.unix(val.departure_time).tz("America/New_York").format("h:mm a")

Categories

Resources