Using moment.js will save you lots of headache, and is the easiest way to achieve cross-browser compatibility for this sort of thing.
var m = moment.utc("3/22/2015","M/D/YYYY")
var s = m.format("YYYY-MM-DD HH:mm:ss")
Using UTC for this is important since you don't want to be affected by the user's time zone. Otherwise, if your date fell into a DST transition, it could be adjusted to some other value. (You're not really intersted in UTC, you're just using it for stability.)
In response to this part of your updated question:
To simplify the question, I'm looking for a function like this:
function date_decomposition(d) {
...
}
console.log(date_decomposition(new Date("3/22/2015 00:00:00")));
=> [2015, 3, 22, 0, 0, 0]
While it's now clear what you are asking for, you must understand it is not possible to achieve your exact requirements, at least not in a cross-browser, cross-region, cross-timezone manner.
Each browser has it's own way of implementing the string-to-date parsing. When you use either the constructor new Date(string)
or the Date.parse(string)
method, you're invoking functionality that is implementation specific.
There's a chart showing many of the formatting differences here.
Even if the implementation were consistent across all environments, you'd have regional formatting and time zone differences to contend with.
In the case of regional formatting issues, consider 01/02/2015
. Some regions use mm/dd/yyyy
ordering and will treat this as January 2nd, while other regions use dd/mm/yyyy
ordering and will treat this as February 1st. (Also, some parts of the world use yyyy/mm/dd
formatting.)
Wikipedia has a list and map of where in the world different date formats are used.
In the case of time zones, consider that October 19th, 2014 at Midnight (00:00) in Brazil did not exist, and November 2nd, 2014 at Midnight (00:00) in Cuba existed twice.
The same thing happens on other dates and times in different time zones. From the information you provided, I can deduce that you are in Iran time zone, which uses UTC+03:30 during standard time, and UTC+04:30 during daylight time. Indeed, March 22, 2105 at Midnight (00:00) did not exist in Iran.
When you try to parse these invalid or ambiguous values, each browser has its own behavior, and there indeed differences between the browsers.
For invalid times, some browsers will jump forward an hour, while others will jump backwards an hour.
For ambiguous times, some browsers will assume you meant the first (daylight-time) instance, while others will assume you meant the second (standard-time) instance.
Now with all of that said, you can certainly take a Date
object and deconstruct its parts, quite simply:
function date_decomposition(d) {
return [d.getFullYear(), d.getMonth()+1, d.getDate(),
d.getHours(), d.getMinutes(), d.getSeconds()];
}
But this will always be based on the local time zone where the code is running. You see, inside the Date
object, there is just one value - a number representing the elapsed milliseconds since 1970-01-01T00:00:00Z
(without leap seconds being considered). That number is UTC-based.
So, in recap, all of the issues you are having are related to the way the string was parsed into the Date
object to begin with. No amount of focusing on the output functions will help you to resolve that in a completely safe manner. Whether you use a library or write your own code, you'll need to obtain that original string of data to get the result you are looking for. By the time it's in a Date
object, you've lost the information you need to make this work.
By the way, you might consider watching my Pluralsight course, Date and Time Fundamentals, which covers much of this in even greater detail. Module 7 is entirely about JavaScript and these sorts of gotchas.