Javascript date toISOSstring/toJSON one day backwards - javascript

I store two dates. First date is the current day and the second one is a future date. To convert those dates into format year-month-day I use toISOSstring function. However usually (but not always) the current date is changed one day backwards.
I also tried to use toJSON function instead. But nothing has changed.
season.from = "Sun Apr 02 2017 18:29:52 GMT+0200 (CEST)"
season.to = "Fri Apr 21 2017 18:29:52 GMT+0200 (CEST)"
var date1 = new Date(season.from);
var date2 = new Date(season.to);
season.from = date1.toISOString().slice(0,10);
season.to = date2.toISOString().slice(0,10);
console.log(season.from); // one day backwards (e.g. 2017-04-01 not 2017-04-02)
console.log(season.to); // proper date somewhere in the future

Your original time strings are in local time, or at least they have a time zone specification. But toISOString returns the UTC time:
The timezone is always zero UTC offset, as denoted by the suffix "Z"
In the case of your GMT+02 time zone, this means the date/time returned by toISOString is two hours "earlier" than the local time. In some cases this can be a time before midnight, and this can render a different date as well.
The implementation of the toJSON method depends on toISOString, so it has the same behaviour.
Work-around
You could use toLocaleDateString('se'), which uses your local time, and formats according to Swedish standards, i.e. YYYY-MM-DD, so you don't even need to slice it. There are some other country codes you could specify to have the same.

Related

momentjs date comparison with timezone

I have been using momentjs and moment-timezone for a while. While using date comparison using isAfter method today, I discovered strange behaviour.
Suppose one moment date is configured with timezone value and other isn't then what should be the behaviour of date comparison?
In my case, we are converting an epoch time to specific timezone value for one date. Other date is in format yyyy-mm-dd without any timezone value. When I am comparing these two days, it is failing for same day value.
//Wed Sep 27 2017 01:13:04 GMT-0700
var localtime = moment(1506499984924).tz("America/Los_Angeles");
//Wed Sep 27 2017 00:00:00
var date = moment('2017-09-27');
//returns true
var value = localtime.isAfter(date, 'day');
Ideally since both dates are Sept 27 2017, it should return false.
Using diff method instead isAfter returns 0 which is true.
Any help is appreciated to solve this issue.
I have created a pen with this code: Moment
In your code:
var date = moment('2017-09-27');
This create a value at midnight local time. How that relates to a specific instant in time is highly dependent on which local time zone your computer is set to.
Moment objects are always compared as moments - that is, instantaneous values based on UTC.
I see false when I run your code pen because I am in a time zone that is behind UTC. If you see true, it's because you are in a local time zone that is ahead of UTC (by over an hour, given the time of the other value).

Why does Javascript show me the wrong date?

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

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();

Match the dates in jQuery with different formats

I have div in which I am providing date and time like this
<div class="timing">
<div id="count-down" data-date="2016-08-31 14:21:00"> </div>
</div>
How would I match or compare with current date, because I am getting current date in this format Wed Aug 31 2016 14:34:58 GMT+0500 (Pakistan Standard Time)
I want to redirect a page to new location if current date is greater than provided date
var currentDate = new Date();
var providedDate = $('#count-down').attr('data-date')
if (currentDate.getDate().toString > providedDate)
{
window.location.href = 'Promo';
$('.timing').css("display", "none");
$('.website-loading').css("display", "block");
}
I have div in which I am providing date and time like this
<div id="count-down" data-date="2016-08-31 14:21:00"> </div>
The string in the data- attribute is not consistent with the format specified in ECMA-262 (the "T" separator between the date and time is missing), so you should manually parse it by either writing a parsing function or use a library and provide the format to parse.
If you use the Date constructor (or Date.parse, they are equivalent for parsing) to parse the string, you may get an invalid date (e.g. in Safari, new Date('2016-01-01 12:00:00') produces an invalid date) since parsing of non–standard strings is entirely implementation dependent.
There are many suitable libraries, some suggestions:
moment.js does parsing, formatting, timezones and arithmetic and has a CDN
fecha.js just does parsing and formatting is very much smaller than moment.js
When you create a Date object, it only has one internal value (called its time value), which is milliseconds since 1970-01-01T00:00:00Z (the javascript epoch, which is the same as the UNIX epoch). When you call the toString method, the result is an implementation dependent string that differs between implementations (in your case you see something like "Wed Aug 31 2016 14:34:58 GMT+0500 (Pakistan Standard Time)", a different implementation may produce something else.
How would I match or compare with current date, because I am getting
current date in this format Wed Aug 31 2016 14:34:58 GMT+0500 (Pakistan Standard Time)
When comparing dates, you really just want to compare the time value. If you compare using the relational operators > or <, they will coerce the dates to their time value so you can compare the dates directly, e.g.:
var providedDate = fecha.parse($('#count-down').attr('data-date'), 'YYYY-MM-DD HH:mm:ss');
if (Date.now() > providedDate) {
// providedDate is in the past
}
Note that since no time zone information is provided in the string to parse, it's treated as a "local" date and time and the host system's current settings are used to determine the offset from UTC, which is then used when calculating the time value. The same system works in reverse when generating a local date and time string from the Date using the default toString method.
Also:
currentDate.getDate()
just returns the date (i.e. the day in the month) as a number without the year and month.

Javascript epoch date incorrect

I am doing some javascript date stuff, and I executed the following:
console.log(new Date(0));
I expected to see the *nix Epoch, but I was oddly returned:
Wed Dec 31 1969 19:00:00 GMT-0500 (Eastern Standard Time)
What happened?
You are setting the internal time value, which is UTC, but seeing a string that is based on your system settings, which likely have an offset of UTC-05:00.
The ECMAScript specification explains how the Date constructor and instances work. Given:
new Date(0)
the Date constructor is called with one argument (§20.3.2.2 Date(value)) so it creates a Date instance with it's internal time value set depending on the type of argument. As the value is a number, the time value is set to that number.
The time value is an offset in milliseconds from 1970-01-01T00:00:00Z §20.3.1.1 Time Values and Time Range. Note that it's based on UTC.
The behaviour of console.log is entirely implementation dependent, so what you get from:
console.log(dateInstance);
depends on the host. However, most seem to call the object's toString method which returns an implementation dependent string based on the timezone setting for the host system (§20.3.4.41 Date.prototype.toString()). That is, a "local" time.
The timezone offset can be determined using getTimezoneOffset. It's in minutes and has the opposite sense to an ISO 8601 offset (e.g. UTC-05:00 will be +300). If you want to get a date string that represents the internal time value without an offset, use toUTCString.
I was unable to find any resources explaining it, but this 'error' is due to my timezone (as far as I can tell)
My timezone is GMT-0500, which is 5 hours behind UTC time. Add 5 hours to Wed Dec 31 1969 19:00:00 and you get the Epoch (Thurs Jan 1 1970 00:00:00)

Categories

Resources