Reputation: 473
So I want to display a date with no particular attention to time of day. There is also nothing messing with the date. I am on a MacBook Pro.
If I input numbers into the Date constructor the following below appears.
I want to show April 28, 1993 for example.
var objDate = new Date(1993, 3, 28),
dateString = objDate.toLocaleDateString(undefined, {
weekday: "long",
year: "numeric",
month: "long",
day: "numeric",
hour: "numeric",
timeZoneName: 'long'
});
console.log(dateString)
//Chrome Outputs: "Wednesday, April 28, 1993, 12 AM Mountain Daylight Time"
//Firefox Outpus: "Tuesday, April 27, 1993, 6 PM Mountain Daylight Time"
let nowDate = new Date(1993, 3, 28);
console.log(nowDate.toString())
//Chrome Outputs: "Wed Apr 28 1993 00:00:00 GMT-0600 (Mountain Daylight Time)"
//Firefox Outputs: "Wed Apr 28 1993 00:00:00 GMT+0000 (UTC)"
console.log(nowDate.toLocaleString())
//Chrome Outputs: "4/28/1993, 12:00:00 AM"
//Firefox Outputs: "4/27/1993, 6:00:00 PM"
So now the dates are showing both the 27th and the 28th, even though I want it to show just the 28th.
But! If I change the numbers to a string format like the following code. It is still inconsistent.
var objDate = new Date("1993-04-28"),
dateString = objDate.toLocaleDateString(undefined, {
weekday: "long",
year: "numeric",
month: "long",
day: "numeric",
hour: "numeric",
timeZoneName: 'long'
});
console.log(dateString)
//Chrome Outputs: "Wednesday, April 27, 1993, 12 AM Mountain Daylight Time"
//Firefox Outpus: "Tuesday, April 27, 1993, 6 PM Mountain Daylight Time"
let nowDate = new Date("1993-04-28");
console.log(nowDate.toString())
//Chrome Outputs: "Wed Apr 27 1993 00:00:00 GMT-0600 (Mountain Daylight Time)"
//Firefox Outputs: "Wed Apr 28 1993 00:00:00 GMT+0000 (UTC)"
console.log(nowDate.toLocaleString())
//Chrome Outputs: "4/27/1993, 12:00:00 AM"
//Firefox Outputs: "4/27/1993, 6:00:00 PM"
Now here is the last bit of code.
If I input a time of day into the string format, like noon, it turns out fine as per to show which day it is.
EDIT: I just checked this method in Safari, and it outputs Invalid Date.
var objDate = new Date("1993-04-28 12:00"),
dateString = objDate.toLocaleDateString(undefined, {
weekday: "long",
year: "numeric",
month: "long",
day: "numeric",
hour: "numeric",
timeZoneName: 'long'
});
console.log(dateString)
//Chrome Outputs: "Wednesday, April 28, 1993, 12 PM Mountain Daylight Time"
//Firefox Outpus: "Wednesday, April 28, 1993, 6 AM Mountain Daylight Time"
let nowDate = new Date("1993-04-28");
console.log(nowDate.toString())
//Chrome Outputs: "Wed Apr 28 1993 12:00:00 GMT-0600 (Mountain Daylight Time)"
//Firefox Outputs: "Wed Apr 28 1993 12:00:00 GMT+0000 (UTC)"
console.log(nowDate.toLocaleString())
//Chrome Outputs: "4/28/1993, 12:00:00 PM"
//Firefox Outputs: "4/28/1993, 6:00:00 AM"
So now here are the questions in particular.
Why do the methods with different date inputs, sometimes set a different day? What are the browsers doing differently in each one of the listed cases? I thought each of the methods I used would be locally based and not UTC based.
EDIT: I might just have to use one of the libraries just to handle all the inconsistencies. Although is there a reasonably small library? I found dayjs and it looks small enough.
Upvotes: 1
Views: 971
Reputation: 15120
Parsing of date strings is implementation dependent - meaning that it is not consistent across browsers. Certain string formats are generally treated as UTC, not local. From the JavaScript Date docs...
Note: parsing of date strings with the
Date
constructor (andDate.parse
, they are equivalent) is strongly discouraged due to browser differences and inconsistencies. Support for RFC 2822 format strings is by convention only. Support for ISO 8601 formats differs in that date-only strings (e.g. "1970-01-01") are treated as UTC, not local.
Similarly, toString
may not produce a similarly formatted date string across browsers. From the Date.prototype.toString docs (note that ECMAScript 2018 has not been fully implemented in all browsers as of the date of this answer)...
Until ECMAScript 2018 (edition 9), the format of the string returned by Date.prototype.toString was implementation dependent. Therefore it should not be relied upon to be in the specified format.
And toLocaleString
locales
and options
are not supported across all browsers.
As you have noted, there are many libraries such as Moment.js that can help with this.
If you are just trying to take consistent date string inputs and reformat them for display, it may not be all that difficult with vanilla js (but the difficulty depends a great deal on the consistency of your input values). For example:
const formatDate = (date) => {
const months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
const [y, m, d] = date.split('-');
return months[m - 1] + ' ' + d + ', ' + y;
}
const date = formatDate('1993-04-28');
console.log(date);
// April 28, 1993
Upvotes: 1
Reputation: 1894
Yes there are a lot of inconsistencies between browsers. Tee worst is on IE and Safari, where a new Date("2018-08-23 18:00:00")
is not a valid date format:)
The best way I found is to convert it to "Zulu" time and add T
for time, like this: new Date("2018-08-23T18:00:00Z")
Just use yourDate.replace(" ", "T");
to add the T
, and then simply add the Z
string.
For any question let me a comment, thanks.
Upvotes: 0