Why does Javascript show me the wrong date? - javascript

Consider the following date object which is created in JavaScript.
var date = new Date("2017-09-07T16:46:06.000Z");
This date object should be equivalent to Sep 7 2017 4:46:06 PM
However, in the browser console, when I type the following:
console.log(date);
The following is returned:
Fri Sep 08 2017 02:46:06 GMT+1000 (E. Australia Standard Time)
The time is wrong. (It actually is today's date, but the time is completely wrong).
Key points of confusion:
My computer timezone is set to GMT+1000 (Australia/Brisbane)
When I created the date object, I did not specify the timezone, therefore it should conform to my systems timezone
When I log the date object to the console, it is still using GMT+1000 (Australia/Brisbane) but the date is different

When you created the date, you did specify a timezone. That Z at the end means Zulu or Greenwich Mean Time. Your computer is 10 hours off from GMT, so it adjusts to your local timezone for display.
If you want the date to be in your local time zone, remove the Z

var date = new Date("2017-09-07T16:46:06.000Z");
So it looks like the Z at the end of your date string is meant to represent UTC or Zulu time
var date = new Date("2017-09-07T16:46:06.000");
should be the correct solution

Related

Convert date from UK GMT string to local date in JavaScript

I have a situation where I am always returned the date from the server as a UK date time string.
E.g. '2020-07-19 16:40:00'
This would be 4:40PM in UK at +01:00, or 3:40PM UTC.
I want to be able to convert this time from GMT to the local time on the computer;
If I do this when in the UK...
var date = new Date('2020-06-19 16:40:00 GMT');
it returns Fri Jun 19 2020 17:40:00 GMT+0100 (British Summer Time)
Which is an hour out.
If I do the date in winter time (without daylight savings), this is correct.
var date = new Date('2020-01-19 16:40:00 GMT');
returns Sun Jan 19 2020 16:40:00 GMT+0000 (Greenwich Mean Time)
Is there a way I can correctly adjust this to always give the correct time regardless of what timezone the computer is set in, based on UK clock times.
Thanks in advance
As I understand your question, you don't know if the timestamp from the server is GMT or BST as the offset isn't included. You can work it out using plain JS but it's somewhat kludgy and error prone, see Calculate Timezone offset only for one particular timezone.
It would be much better to get the server to use an ISO 8601 format supported by ECMAScript and either send the offset or always use UTC/GMT.
If that isn't an option, you can use a library like Luxon to specify the location (and hence offset rules) to use for parsing, e.g.
let DateTime = luxon.DateTime;
['2020-07-19 16:40:00', // BST +1
'2020-01-19 16:40:00' // GMT +0
].forEach(ts => console.log(
DateTime.fromFormat(ts, 'yyyy-LL-dd HH:mm:ss', {zone: 'Europe/London'}))
);
<script src="https://cdn.jsdelivr.net/npm/luxon#1.24.1/build/global/luxon.min.js"></script>
PS Don't forget to always tell the parser the format to parse.

Start of Day from one timezone to GMT

I am using moment-timezone library to build a UI that needs to be relative to a variety of timezones.
I am taking an input of a timezone, i.e "America/Chicago" and need to get the start of day in GMT.
For instance, if today is March 27th at 9am Chicago time (2pm GMT), I need to get the date in epoch seconds for March 27th, 00:00 AM.
I'm using the moment.tz("America/Chicago").startOf('day') but I keep getting Tue Mar 27 2018 01:00:00 GMT-0400 (EDT) . Any idea how to do this?
Thanks
// This part you are already doing correctly.
// You get back a Moment object representing the start of the current day in Chicago:
var m = moment.tz("America/Chicago").startOf('day');
I need to get the date in epoch seconds
// Ok, so simply now get the associated Unix Time
var timestamp = m.unix();
Also note that the correct terminology is "Unix Time", not "epoch seconds".
See my blog post: "Please don't call it Epoch Time".
... but I keep getting Tue Mar 27 2018 01:00:00 GMT-0400 (EDT)
You are probably either looking at _d or a Date object, or rather the string representation of one. Don't. See this Moment.js documentation for details.
Per your comment:
I need to take the current time in a specific timezone. I then need to convert that time to the corresponding day in GMT. Finally I need to get the midnight epoch timestamp of that GMT day.
That's a little different then you originally asked, but it would be like this:
var timestamp = moment.utc().startOf('day').unix();
Note that there's no purpose in involving another time zone for this operation. Logically, when asking for "Now in time zone A converted to time zone B", it's the same as asking for "Now in time zone B". In other words, you would get the same value even when the time zone was present:
var timestamp = moment.tz('America/Chicago').utc().startOf('day').unix();
So you're better off just leaving the time zone out.

Convert milliseconds into UTC date object with UTC Time Zone

I am trying to convert milliseconds into UTC date object as below -
var tempDate = new Date(1465171200000);
// --> tempDate = Mon Jun 06 2016 05:30:00 **GMT+0530 (India Standard Time)** {}
var _utcDate = new Date(tempDate.getUTCFullYear(), tempDate.getUTCMonth(), tempDate.getUTCDate(), tempDate.getUTCHours(), tempDate.getUTCMinutes(), tempDate.getUTCSeconds());
//--> _utcDate = Mon Jun 06 2016 00:00:00 **GMT+0530 (India Standard Time)** {}
Time is resetting to UTC time but Time Zone is still coming as GMT+0530 (India Standard Time).
Is there any sure shot approach to convert milliseconds into UTC date object with UTC Time Zone?
Quoting from this answer (that I suggest you to read completely):
There is no time zone or string format stored in the Date object itself. When various functions of the Date object are used, the computer's local time zone is applied to the internal representation.
As time zone is not stored in the Date object there is no way to set it.
I see two options:
the first is to make use of a library (as suggested in the answer above). Quite popular now is Moment.js
the second (pure JavaScript - if it's a viable solution in your context):
Do the "time math" in your local timezone.
When you're ready to switch to UTC use toUTCString() method.
Of course you'll end up with a string as this let you store the time zone as long as the date time value.
As you won't be able to manipulate the date time as a Date object from now on this must be the last step.
var tempDate = new Date(1465171200000);
// Mon Jun 06 2016 05:30:00 GMT+0530
// Do your date time math here
// using the Date object's methods
var utcDateAsString = tempDate.toUTCString();
// Mon Jun 06 2016 00:00:00 GMT
You say:
Time is resetting to UTC time but Time Zone is still coming as GMT+0530 (India Standard Time). Is there any sure shot approach to convert milliseconds into UTC date object with UTC Time Zone?
But I think you misunderstand what is occurring. When you pass a number to the Date constructor as in:
new Date(1465171200000)
is it assumed to be milliseconds since the ECMAScript epoch (1970-01-01T00:00:00Z), so a Date object is created with that value as its internal time value. So Date objects are inherently UTC.
When you write that to a string, internally a human readable date string is generated based on the host timezone setting, which is why you see a date for GMT+0530 (that is your host system timezone setting). The Date object itself does not have a timezone, it's always UTC.
When you then use UTC values to create a "local" Date using:
new Date(tempDate.getUTCFullYear(), tempDate.getUTCMonth(), ...)
then the host timezone is used to generate a UTC time value equivalent to a "local" date for the associated values. You've effectively subtracted your timezone offset from the original time value so it now represents a different moment in time. You can get exactly the same result doing:
var d = new Date(1465171200000);
d.setMinutes(d.getMintues() + d.getTimezoneOffset());
which just shows a bit more clearly what's going on. Note that ECMAScript timezone offsets are in minutes and have the opposite sense to UTC, that is, they are negative (-) for east and positive (+) for west. So an offset of UTC+05:30 it is represented as -330 and you need to add it to "shift" a Date rather than subtract it.
var tempDate = new Date(1465171200000);
var _utcDate = new Date(tempDate.getUTCFullYear(), tempDate.getUTCMonth(), tempDate.getUTCDate(), tempDate.getUTCHours(), tempDate.getUTCMinutes(), tempDate.getUTCSeconds());
console.log('Direct conversion to Date\ntempDate: ' + tempDate.toString());
console.log('Adjusted using UTC methods\n_utcDate: ' + _utcDate.toString());
tempDate.setMinutes(tempDate.getMinutes() + tempDate.getTimezoneOffset());
console.log('Adjusted using timezoneOffset\ntempDate: ' + tempDate.toString());
However, I can't understand why you want to do the above. 1465171200000 represents a specific moment in time (2016-06-06T00:00:00Z), adjusting it for every client timezone means it represents a different moment in time for each client with a different timezone offset.
If you create a Date from a Number, the local timezone is the one considered. But if you want to see what a timestamp would mean with the hours corrected for UTC, you could use a helper as such:
Number.prototype.toUTCDate = function () {
var value = new Date(this);
value.setHours(value.getHours() - (value.getTimezoneOffset() / 60));
return value;
};
The usage would be:
var date = (1465171200000).toUTCDate();

Javascript Parsed Date [duplicate]

This question already has an answer here:
HTML Input type datetime-local setting the wrong time-zone
(1 answer)
Closed 7 years ago.
I'm writing a MVC 5 web application. Into this, I have multiple lists that I propagate and manage through javascript and jquery (one dataset, dependent select controls, and adding ajax callbacks would complicate it unnecessarily.)
The issue I have is: I have a hidden for field formatted to ISO 8601. I run into issues when I display the date in the user's local time, I get a shifted date.
So if the date were stated as: 01-01-2009 (in iso 8601 format: 2009-01-01), the user sees: 12-31-2008.
When I parse the date I'm using:
this.date = new Date(Date.parse(originalString));
/* ^- Date.parse is giving me a number. */
To display the text of the date I am using:
admin.date.toLocaleDateString().Concat(...
Do I need to do any sort of patch-up to adjust things to the proper time-zone? The date, when using console.log(admin.date); shows the original 2009-01-01
I'm thinking there's some parameter I'm not specifying correctly in the toLocaleDateString, but my familiarity level with it is low.
Edit: The goal is to prevent the date shift. All we store is the date, the time aspect is dropped. We have multiple time-zones posting to this database, and the goal is: We use the date of the person who posted it, time dropped. Were the date May 01, 2015, I want anyone who sees that date to see May 01, 2015, the 'toLocaleDateString' is merely a means to get it to appear format correct for their region. So someone who views dates as yyyy-mm-dd will see it properly.
Based on the documentation for Date.parse:
The Date.parse() method parses a string representation of a date, and returns the number of milliseconds since January 1, 1970, 00:00:00 UTC.
You are getting back the epoch time in UTC for your parsed date string hence why the date is off for local times. So, you would need to know the time difference between the local time and UTC which Date.getTimezoneOffset provides (in minutes) in order to set the correct date for the local time:
> var date = new Date(Date.parse('2009-01-01'));
undefined
> date;
Wed Dec 31 2008 19:00:00 GMT-0500 (EST)
> date.getTimezoneOffset();
300
> date.setMinutes(date.getTimezoneOffset());
1230786000000
> date;
Thu Jan 01 2009 00:00:00 GMT-0500 (EST)
One thing to note though is:
...the offset is positive if the local timezone is behind UTC and negative if it is ahead.
So you might need to take care for locales where the value is negative if this applies to your application. If so maybe just omitting negative values would be enough since the date should be the same if a locale's timezone is ahead of midnight UTC.
EDIT: To compensate for possible issues with daylight savings time:
> var dateVals = String.prototype.split.call('2009-01-01', '-');
undefined
> var date = new Date(dateVals[0], dateVals[1] - 1, dateVals[2]);
undefined
> date
Thu Jan 01 2009 00:00:00 GMT-0500 (EST)

How to update the date to the current date for UTC -8

I want to display a UTC date using this JavaScriptcode on my webpage.
<script>
function myDate()
{
var now = new Date();
var d = new Date(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate());
var x = document.getElementById("demo");
x.innerHTML=d;
}
</script>
With this code I am getting UTC date displayed as a local string as follows: "Thu Jul 04 2013 00:00:00 GMT+0530 (India Standard Time)"
I do not want display the string with a local time offset (GMT+0530 (IST)), instead I want the time to appear as UTC string format
The date returned by different browser are of different format
to remove GMT OFFSET from date you can use replace
var d = new Date(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate());
d = d.toString().replace(/GMT.+/,"");
Firstly, the problem is that you are instantiating a local Date object by passing in the UTC year, month and day. This then creates a local Date with the values provided. by doing this you might be creating an incorrect date based on whether you want it to be UTC or local. IN your case, if you want var now as UTC, the way you are currently instantiating is incorrect as its in local time.
Anyway, dates can be tricky in in JavaScript, so I would consider using Moment.js for this
It's a fantastic library that provides all of the functions for manipulating and converting JavaScript dates that you could ever need.
For example with moment you can just do the following:
var now = moment(); // current date and time in local format
var nowAsUTC = now.utc(); // current local date and time converted to UTC
var alsoNowAsUTC = moment.utc() // same as the line above, but staring in UTC
console.log(nowUTC.format("DD/MM/YYYY, hh:mm:ss"))// prints a pretty UTC string
Hmmm.. Are you sure you want to display UTC-8? I will take a guess that you are really wanting to convert the time to US Pacific time zone. That is not always UTC-8. Sometimes it is UTC-8, and sometimes it is UTC-7.
If you're not actually in the US Pacific Time zone, the only way to do this reliably in JavaScript is with a library that implements the TZDB database. I list several of them here.
For example, using walltime-js library, you can do the following:
var date = new Date();
var pacific = WallTime.UTCToWallTime(date, "America/Los_Angeles");
var s = pacific.toDateString() + ' ' + pacific.toFormattedTime();
// output: "Fri Apr 26 2013 5:44 PM"
You can't just add or subtract a fixed number, because the target time zone may use a different offset depending on exactly what date you're talking about. This is primarily due to Daylight Saving Time, but also because time zones have changed over time.

Categories

Resources