getDay() returns correct value on desktop but wrong value on mobile

Hi,

I have the following code:

var date = new Date('2018-06-11'); // June 11
alert(date.getDay());

It returns 1 (correct) on desktop browsers (Firefox/Chrome), but it returns 0 (wrong) on mobile browsers (Android Chrome). Checked on multiple mobile phones, it returns 0.

What might be the issue?

Thanks.

I am still curious to know why the day of the week returns wrong on mobile browsers, but I am now using the following approach, which returns the correct value on mobile too, just in case anyone else stumbles into the same issue.

var date = '2018-06-11' // this date is input, and changes dynamically
var year = date.substring(0,4);
var month = (date.substring(5,7) < 10) ? date.substring(5,7).substring(1,2) - 1 : date.substring(5,7) - 1 // 1 is subtracted since JS has months as 0-11, not as 1-12. Why would anyone design it like this??
var day = date.substring(8,10)

var d = new Date();
d.setFullYear(year);
d.setMonth(month);
d.setDate(day);

alert(d.getDay()); // returns 1 (correct) both on desktop and mobile

what year/month/day/hour does your phone think is in the wrong date object?

(For the record, the problem is most likely a timezone one.)

The phones I tested, one in Europe, one in US, display the year, month and day correctly, but when I display the day of the week using date.getDay(), they did not display it correctly. It worked fine on desktop browsers, not on mobile browsers, that’s what I couldn’t understand. Timezone shouldn’t have an effect I believe, because the date is not read from the client locally.

The only thing that comes to my mind is that Android Chrome treated the date I enter 2018-06-11 (June 11), as November 6, which makes the wrong result correct. Is that possible? Isn’t the correct date format as YYYY-MM-DD in JS Date()? But that won’t work as an explanation because the phone shows correct date when I display the date in Y, M, D.

I will, for the moment, assume your timezone is somewhere West of GMT.

It depends. The browser may be interpreting “2018-06-11” as “2018-06-11 00:00:00 PST”, in which case the date would match correctly, and return the correct result.
If the browser instead has read “2018-06-11” as Zulu Time (2018-06-11 00:00:00 UTC), then the actual date value being stored is equivalent to 2018-06-10 17:00:00 PST, which would make the weekDay 0.

Try running new Date('2018-06-11').getTime() on both devices, and see if they spit out the same value.

EDIT: Here’s an example from my console, running Chrome on my laptop:

Note that because it interpretted the date as Zulu time, it actually interprets the Day of the Week as Sunday, and gives me 0.

1 Like

(Also, if it had interpreted the date as November 6, it should have returned a 2, as the 6th of November is a Tuesday this year)

I did the test you suggested on desktop and mobile, they both gave the same result: 1528675200000

If the mobile browser interprets the date differently, then why did my solution in the second post worked? I mean,

var date = new Date('2018-06-11');

didn’t work, but manually setting year, month and day worked.

var d = new Date();
d.setFullYear(year);
d.setMonth(month);
d.setDate(day);

Thanks for your input. I will make sure to manually set the year/month/day in similar cases going forward.

Keep in mind that new Date() sets the hour/minute/second to the Current time. If you’re doing straight date operations, that may not be an issue, but just something to keep in mind.

For the purpose of testing, I am using the following jsfiddle to experiment with on my Android Chrome.

It gives more information saying:
Mon Jun 11 2018 12:00:00 GMT+1200 (New Zealand Standard Time) day is 1

Can you please let us know what yours says when your Android device says 0?

1 Like

Desktop says:

Mon Jun 11 2018 03:00:00 GMT+0300 (GMT+03:00) day is 1

Mobile says:

Sun Jun 10 2018 17:00:00 GMT-0700 (PDT) day is 0

So, in the light of how different browsers behave differently as we see, can we say using the following should be avoided?

var date = new Date('2018-06-11');

Well no, it’s not to be avoided per-se, it’s a global world view and storage you have to take into consideration.

You tell Javascript “2018-06-11”. Javascript interprets this as 2018-06-11 Zulu (UTC). That gets stored as a number. It is a moment in time - simultaneously around the world, at that moment, it is both Monday and Sunday - depending on which side of midnight you fall on. So in the US, at that moment, it is Weekday 0, and in Europe, it’s Weekday 1. It is locally many different hours of the day, in every timezone or DST-observation zone, etc. It is, however, EVERYWHERE, the exact same numerical value in timestamp form. Which is what Javascript (and pretty much every timezone-neutral timekeeper language in the world) stores.

Why? Because things happen at moments. Your meeting starts at 18:00, you say. Well no, it starts at 18:00 PDT on Monday. In England, it starts at 1 AM Tuesday. So is the meeting on a Monday or Tuesday? It depends. Computers don’t like it when questions have answers like “it depends”.

If you wanted to specify PDT, you could have said new Date('2018-06-11 00:00:00 PDT'), and Javascript would have interpreted it correctly. However, again, this is just a MOMENT. You haven’t fixed the problem, just shifted the line of measurement. (Somewhere in Eastern Asia, this moment is a Tuesday, not a Monday.)

2 Likes

The behaviour of Date.parse (or passing a date string to the Date constructor) was not standardized untill ES5. When you pass a date string in ISO format a ES5 compliant browser assumes the UTC time zone, a non-ES5 compliant browser might not. https://developer.mozilla.org/nl/docs/Web/JavaScript/Reference/Global_Objects/Date/parse

Also, it’s not a question of browsers behaving differently - your desktop thinks its in Saudi Arabia (GMT+3), and your phone thinks it’s in California (GMT-7). Opposing sides of that midnight line.

I understand it better now. Thank you for the detailed explanation.

I now realized that for my specific need, which I need “Day 1” returned when I input “2018-06-11” regardless of the location in the world or how a browser treats it, I should use a string for my input, instead of a date object.

Like,

var date = "2018-06-11";

instead of

var date = new Date("2018-06-11");

Wish I had thought of it earlier.

2 Likes

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.