Prevent Javascript from creating dates with a large months - javascript

In Javascript if I create a date like so:
var y=new Date('2014','16','06')
Then y will be on my computer Wed May 06 2015 00:00:00 GMT-0400. However, the month I entered is 16 not 5. Is there anyway to prevent Javascript from creating a valid date in this instance (when Month is too big) and just return 'Invalid Date'?

Here's the relevant information from the Mozilla Javascript documentation for Date:
Note: Where Date is called as a constructor with more than one
argument, if values are greater than their logical range (e.g. 13 is
provided as the month value or 70 for the minute value), the adjacent
value will be adjusted. E.g. new Date(2013,13,1) is equivalent to new
Date(2014,1,1), both create a date for 2014-02-01 (note that the month
is 0-based). Similarly for other values: new Date(2013,2,1,0,70) is
equivalent to new Date(2013,2,1,1,10) which both create a date for
2013-03-01T01:10:00.
So in answer, no, that's the only behavior of the Date constructor, and any validation you want to do on your input values is going to have to be done by you before you pass them into the constructor.
However, one possible option could be to concatenate a string of your date value and then use Date.parse() on it, which will return a valid value if your date is correct or NaN if it isn't.

Related

Understanding JavaScript dates in British Summer Time

I live in the UK. If I create a date object for 1st June, I would have expected .getUTCDate() to return the "correct" day of the month as 1, but instead it returns 31 and .getDate(), which I thought was meant to return the locale date returns 1.
new Date(2020,5,1).getUTCDate() // 31
new Date(2020,5,1).getDate(); // 1
Why is this? Is it because new Date(2020,5,1) is already converted to local time or something? I thought dates were stored universally, and it is only when the date is printed out that the locale rules are applied? I've read all the MDN docs and still don't understand, I would really appreciate if someone can walk through the steps of what happens for the above to return 31 and 1.
A brief explanation of how ECMAScript Date constructor works.
Single string values are parsed and converted to Dates in weird and wonderful ways that are mostly implementation dependent, see below. So all of the following ignores parsing and assumes the Date constructor is called with at least two arguments, year and month. In this case, string values are converted to number as if by Number(value).
All the non–UTC methods work in local time, i.e. based on the host system date, time and timezone offset settings. When creating a Date object using the constructor and values for year, month, day, etc. then any missing values are treated as 0 except for the day, which defaults to 1.
So
new Date(2020, 5, 1)
creates a date based on the host (local) settings for date, time and timezone offset for that date and time, respecting historical changes like daylight saving and other adjustments (common before 1900) as if by:
new Date(2020, 5, 1, 0, 0, 0, 0); // Local 1 Jun 2020 00:00:00.000
So getUTCDate will return 31 (i.e. 31 May) for systems with a timezone offset that is less than zero and 1 (i.e. 1 Jun) for any with an offset of zero or greater. The largest positive offset in common use is +14 and the smallest is -10.
If you want to create a Date based on UTC values, then use the Date.UTC method, whcih returns a number, the time value, so you have to pass it to the Date constructor to create a Date object:
new Date(Date.UTC(2020, 5, 1)).getUTCDate(); // 1 regardless of host settings
Parsing strings: new Date(string) and Date.parse(string)
This where the Date object crashes and burns. While the constructor mostly uses local, it can also use UTC even where UTC is not specified. Parsing of strings is almost entirely implementation dependent except for the 3 formats supported by ECMA-262. Even the supported formats are not parsed consistently across implementations so the general advice is do not use the built–in parser. See Why does Date.parse give incorrect results?

JavaScript getting date string as 11pm on the day before

I have the following input field:
In my web app I have -
string date - 06/05/2018
And this JS code:
var d = "06/05/2018".split("/");
var date = new Date(d[2] + "-" + d[1] + "/" + d[0]).getTime();
console.log(date)
This returns 1525561200000 which if I put that into epoch converter gives me...
Saturday, May 5, 2018 11:00:00 PM
This then screws up with my filtering system - date ranges because if I select the minimum date to be 06/05/2018 with the input field:
var d = $('#min').val()
var date = new Date(d).getTime();
console.log(date)
It is returning 1525564800000 which comes to Sunday, May 6, 2018 12:00:00 AM
How do I get around this?
Thanks
I could write an entire thesis on how problematic and difficult it is to work with dates in Javascript and how to avoid pitfalls and weird bugs, but in the end your specific problem comes down to a simple typo.
The string you're parsing manually and passing to the Date constructor looks like this:
2018-05/06
You've mistakenly used a / instead of a - as the second delimiter when concatenating the string. For some reason, the browser then creates the date object as midnight 2018-05-06 local time. When passing in the string in the standard format (which is what happens when taking it from the date input), i.e. 2018-05-06, the date object gets created as midnight 2018-05-06 UTC time.
So, in short, your problem can be solved by replacing the "/" with "-" in your string concatenation and the two dates should be the same.
However, I should point out that passing a string to the Date constructor is unreliable since the result is not standardized and may differ between browsers (which is also why it behaves so unpredictable and seemingly illogical in this case). It's a better idea to pass numbers instead since the specification dictates the result of that. You're already halfway there since you've split the date string into its components. Try this:
var date = new Date(
Number(d[2]),
Number(d[1]) - 1, // Subtracting 1 from month since it's base 0
Number(d[0])
).getTime();
(Technically, we don't even need to explicitly convert to Number since the Date constructor expects all arguments to be numbers when there's more than one argument and will convert whatever it gets into numbers internally)

Javascript setting date not working, showing wrong hour

I want to set date and time to 2016-05-11T00:00:00.000Z
var date = new Date(2016,4,12,0,0,0,0);
but instead of showing Date 2016-05-11T00:00:00.000Z its giving Date 2016-05-11T19:00:00.000Z
I want time 00:00:00 but its giving 19:00:00
Use Date.UTC:
Note: Where Date is called as a constructor with more than one argument, the specifed arguments represent local time. If UTC is desired, use new Date(Date.UTC(...)) with the same arguments. [Source]

JavaScript Date formatting and conversion issue

I'm located in PST timezone and I want to be able to take the string "2014-01-01" and convert it into Unix time without "2014-01-01" getting converted to PST.
Here's what I'm doing:
Date.parse(new Date("2014-01-01"))
I'm getting the value 1388534400000 which is equivalent to Tue Dec 31 2013 16:00:00 GMT-0800 (Pacific Standard Time)
I want to take the date as "2014-01-01" and not convert it into PST before converting it into Unix time.
A few things:
The Date constructor returns a Date object, not a string. You shouldn't wrap it in a call to Date.parse.
If you want a unix timestamp, just call getTime().
var ts = new Date("2014-01-01").getTime();
Alternatively, you can parse the date string without creating a Date object at all.
var ts = Date.parse("2014-01-01");
The behavior of date parsing in JavaScript is implementation dependent. Most browsers will already interpret a yyyy-mm-dd string to be in UTC, due to the dashes (-). If you replace with with slashes (/), you'll see the string get interpreted as local time instead.
I think you're confused about the output. You said the timestamp was equivalent to PST, but that's just one representation. It's also equivalent to the UTC value you passed in. It's not getting converted in the input, it's being converted when you are converting the timestamp back to local time.
You can use a library like moment.js, which gives you full control of the input and output. This is usually the best option, but has the overhead of including a library in your application.
Another way to convert the specified date string to Unix time is as follows:
var str = "2014-01-01";
var parts = str.split('-');
parts[1] -= 1; // js numeric mos are 0-11
var ms = Date.UTC( parts[0], parts[1], parts[2] ); // parts: YYYY, MM, DD
var unix_time = ms/1000; // Unix time uses seconds
console.log("Unix time: " + unix_time);
Date.UTC() returns the number of milliseconds occurring since January 1, 1970 midnight up to the instant of the specified date, irrespective of any timezone. The script transforms the result into Unix time, i.e. seconds, by dividing the number of milliseconds by 1000.
After splitting the string into an array, the code adjusts the element containing the month, lest JavaScript mistake its value for March; JavaScript comprehends numeric months as ranging from 0-11, not 1-12. Next, the script passes the elements sequentially in accordance with the year, month, day parameters that Date.UTC requires. Although UTC() expects numbers for parameters, it accepts the numerical strings.
Note: if you first create a new date object and expect to use a UTC method -- that results in an error because it is a static method of JavaScript's Date Object.
You may check the validity of the UTC() return value, using the aforementioned variables ms and str, as follows:
console.log( new Date( str ).toUTCString( ms ));
The output: Wed, 01 Jan 2014 00:00:00 GMT
See live demo here)
Passing a date string to the Date constructor instead of the numerical parameters it expects affords an unexpected benefit; the date string is treated as if it's timezone is UTC, i.e. zero by the local date object. Once created, the local date object executes its toUTCString() method to attain the above-indicated result. The toString() method would also yield the same output, but it appends local timezone information.

javascript dates compare

I'm working with javascript Date and i'm starting to go crazy :)
I want two compare only the year,month, day of two dates. The date are (retrieve from firebug stacktrace):
[Date {Thu Feb 11 2010 12:00:00 GMT+0000 (GMT Standard Time)}]
[Date {Sun Jul 11 2010 00:00:00 GMT+0100 (GMT Daylight Time)}]
In this point i'm trying compare the two dates like this:
if (datepickerBegin == null || datepickerBegin.length == 0 || datepickerBegin != date) {
//Do stuff
}
This code obvious doesn't work, which is the simple way of comparing these two String?
I'm trying to convert this var to Date and concatenate into another var the getMonth()+getYear()+getDay()... but
i believe that there is a easiest way.
By the way, why the following line give NaN
new Date(datepickerBegin).getMonth()
but the following line works?
new Date(Date.parse(datepickerBegin.toString())).getMonth()
After parsing the dates using Date.parse(...);, you can use the Date constructor to create date types like so. An example of this process has been abstracted into the function below:
function parseDateAsDatePart(dateString) {
var parsedDate = new Date(Date.parse(dateString));
return new Date(parsedDate.getYear(), parsedDate.getMonth(), parsedDate.getDate());
}
Once you change both strings into Date objects, you may compare them as shown above.
Note: as Linus mentioned above, Date.parse(...) returns an integer, not a date object, so it needs to be wrapped in the Date constructor.
Try converting the dates to time, using the .getTime() method. If the dates are equal, they will have the same values returned from getTime. This assumes that you're only using string values for your dates (ie "9/6/12"). If your dates will have time stamps associated with them, then you'll need to use the setHours() function to set all the time reference to 0 (d.setHours(0,0,0,0);).
Links:
https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/getTime
https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/setHours
Example:
if(datePickerBegin.getTime() === datePickerEnd.getTime())
{
//...do something.
}
Note: If you do end up going the .getMonth() route, then be aware that the function returns the months as zero based numbers, so add 1 to what it returns.
You can try with getMonth, GetDays , ...
http://www.comptechdoc.org/independent/web/cgi/javamanual/javadate.html

Categories