Javascript not parsing dates properly - javascript

I have been using some extensions on the Date prototype to perform some operations (Advice: do not do that, it screws the date object; too late for me in my current project) and lately have been having some more issues than usual.
To parse strings in H:m format, I made a custom function and assigned it to the Date prototype like this:
Date.__parse = Date.parse;
Date.parse = function(string){
var pattern = /^\d{1,2}:\d{1,2}/ig;
var today = new Date();
if ( pattern.exec(string) ){
var year = today.getFullYear();
var month = today.getMonth()+1;
var day = today.getDate();
var t = year+"-"+month+"-"+day+" "+string;
var timestamp = Date.__parse(t);
return new Date(timestamp);
}
else{
return new Date(Date.__parse(string));
}
}
Ugly when you try to log the date object but working until recently.
For a time, Date.parse seems to work with dates in "d-m-Y" format, but lately it is returning "invalid date" when I do it.
Did something change in the way major browsers parse the dates, or some change to the specification, or must I assume that the error was there before, and it didn´t trigger "Invalid Date" because I was lucky? (I mostly use the function to validate input fields, so it could very well pass unnoticed).
Guess I will have to write my own date scripts and totally forget the js Date object, it´s really horrible (tried to use moment.js, but the performance in the component where I use it was very poor, that´s why I had to make custom functions).
EDIT
For a better understanding;
What I was doing and seemed to work:
Date.parse("23-7-2016") // Never got an error, expected 23 Jul 2016
What I found after tracking a validation error:
var startDate = Date.parse("23-7-2016");
console.log(startDate.toISOString()); //Got Invalid Date
What I think may have happened
var startDate = Date.parse("12-7-2016");
// expected 12 Jul 2016, got 7 Dec 2016, silently fails, everyone is happy
Why I think the prev. case is not the case: I use an interactive scheduler and performed thousands of tests on it, hardly such an error would go unnoticed.
Worst scenario: chrome updated and changed the way it parses dates.
Not sure... hoped someone could enlighten me.

I've determined your method should work for any valid input. You problem is most likely that your regex is valid for hours above 23, and minutes above 59.
See my jsfiddle, which enumerates all valid inputs. https://jsfiddle.net/kLngLL72/4/
I didn't overwrite the Date.parse function in my example to prevent infinite nesting of the function.
Date.__parse = Date.parse;
var dparse = function(string){
var pattern = /^\d{1,2}:\d{1,2}/ig;
var today = new Date();
if ( pattern.exec(string) ){
var year = today.getFullYear();
var month = today.getMonth()+1;
var day = today.getDate();
var t = year+"-"+month+"-"+day+" "+string;
var timestamp = Date.__parse(t);
return new Date(timestamp);
}
else{
return new Date(Date.__parse(string));
}
}
$("#data").append("<tr><td>" + dparse("01-01-2016 1:31") + "</td></tr>");
$("#data").append("<tr><td>" + dparse("1-1-2016 0:0") + "</td></tr>");
$("#data").append("<tr><td>" + dparse("1-1-2016 12:59") + "</td></tr>");
$("#data").append("<tr><td>" + dparse("1-1-2016 23:59") + "</td></tr>");
$("#data").append("<tr><td>" + dparse("12-31-2016 1:1") + "</td></tr>");
$("#data").append("<tr><td>" + dparse("12-31-2016") + "</td></tr>");
$("#data").append("<tr><td>" + dparse("12-31-2016 24:0") + "</td></tr>");
$("#data").append("<tr><td>" + dparse("12-31-2016 99:99") + "</td></tr>");
for (var i = 0; i < 24; i++)
{
for (var j = 0; j < 60; j++)
{
$("#data").append("<tr><td>" + dparse("12-31-2016 " + i + ":" + j) + "</td></tr>");
}
}
UPDATED - NEW JS FIDDLE https://jsfiddle.net/mfe55xun/2/
This new example, only passes the hour and minute string in.
Date.__parse = Date.parse;
var dparse = function(string){
var pattern = /^\d{1,2}:\d{1,2}/ig;
var today = new Date();
if ( pattern.exec(string) ){
var year = today.getFullYear();
var month = today.getMonth()+1;
var day = today.getDate();
var t = year+"-"+month+"-"+day+" "+string;
var timestamp = Date.__parse(t);
return new Date(timestamp);
}
else{
return new Date(Date.__parse(string));
}
}
$("#data").append("<tr><td>" + dparse("99:99") + "</td></tr>");
for (var i = 0; i < 24; i++)
{
for (var j = 0; j < 60; j++)
{
$("#data").append("<tr><td>" + dparse(i + ":" + j) + "</td></tr>");
}
}
UPDATE
It should be noted that if your input string included the date, the regular Date.parse would work on a string with your H:m formatting:
Date.parse("1/2/2016 4:3")
You would just need to append your "4:3" to a current date string, and you could remove your custom Date.parse function.
Another Update For Updated Question
I don't think that format ever worked correctly for you. It has cases where it will work, but it's always going to interpret the day "23rd" to be a month, and give you an invalid date. Here is another jsfiddle example that loops through all conceivable dates in that format, notice only days 1-12 work. https://jsfiddle.net/mfe55xun/6/
Date.__parse = Date.parse;
var dparse = function(string){
var pattern = /^\d{1,2}:\d{1,2}/ig;
var today = new Date();
if ( pattern.exec(string) ){
var year = today.getFullYear();
var month = today.getMonth()+1;
var day = today.getDate();
var t = year+"-"+month+"-"+day+" "+string;
var timestamp = Date.__parse(t);
return new Date(timestamp);
}
else{
return new Date(Date.__parse(string));
}
}
for (var i = 0; i <= 31; i++)
{
for (var j = 0; j <= 12; j++)
{
$("#data").append("<tr><td>" + i + "-" + j + "-2016 = " + dparse(i + "-" + j + "-2016" ) + "</td></tr>");
}
}
Look at the results loop:
test results
0-0-2016 = Invalid Date
0-1-2016 = Invalid Date
0-2-2016 = Invalid Date
0-3-2016 = Invalid Date
0-4-2016 = Invalid Date
0-5-2016 = Invalid Date
0-6-2016 = Invalid Date
0-7-2016 = Invalid Date
0-8-2016 = Invalid Date
0-9-2016 = Invalid Date
0-10-2016 = Invalid Date
0-11-2016 = Invalid Date
0-12-2016 = Invalid Date
1-0-2016 = Invalid Date
1-1-2016 = Fri Jan 01 2016 00:00:00 GMT-0500 (Eastern Standard Time)
1-2-2016 = Sat Jan 02 2016 00:00:00 GMT-0500 (Eastern Standard Time)
1-3-2016 = Sun Jan 03 2016 00:00:00 GMT-0500 (Eastern Standard Time)
1-4-2016 = Mon Jan 04 2016 00:00:00 GMT-0500 (Eastern Standard Time)
1-5-2016 = Tue Jan 05 2016 00:00:00 GMT-0500 (Eastern Standard Time)
1-6-2016 = Wed Jan 06 2016 00:00:00 GMT-0500 (Eastern Standard Time)
1-7-2016 = Thu Jan 07 2016 00:00:00 GMT-0500 (Eastern Standard Time)
1-8-2016 = Fri Jan 08 2016 00:00:00 GMT-0500 (Eastern Standard Time)
1-9-2016 = Sat Jan 09 2016 00:00:00 GMT-0500 (Eastern Standard Time)
1-10-2016 = Sun Jan 10 2016 00:00:00 GMT-0500 (Eastern Standard Time)
1-11-2016 = Mon Jan 11 2016 00:00:00 GMT-0500 (Eastern Standard Time)
1-12-2016 = Tue Jan 12 2016 00:00:00 GMT-0500 (Eastern Standard Time)
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/parse
The Date.parse() method parses a string representation of a date, and
returns the number of milliseconds since January 1, 1970, 00:00:00 UTC
or NaN if the string is unrecognised or, in some cases, contains
illegal date values (e.g. 2015-02-31).
It is not recommended to use Date.parse as until ES5, parsing of
strings was entirely implementation dependent. There are still many
differences in how different hosts parse date strings, therefore date
strings should be manually parsed (a library can help if many
different formats are to be accommodated).

Related

How to parse date in JS? [duplicate]

This question already has answers here:
Parsing a string to a date in JavaScript
(35 answers)
Closed 2 years ago.
I must to get properly date value from my long date in string.
I have this date:
Sun Aug 30 2020 00:00:00 GMT+0200 (Central European Summer Time)
how to parse this date to: 2020-08-30?
and i have another use case:
Tue Aug 25 2020 11:58:04 GMT+0200 (Central European Summer Time)
how to parse this date to: 11:58?
thanks for any help :)
//////////////////////////////////////////////////////////////
If you're sure that your strings are always in that format, you could just split on spaces:
date = "Sun Aug 30 2020 00:00:00 GMT+0200 (Central European Summer Time)";
[day_of_week, month, day, year, time, ...tz] = date.split(" ");
tz = tz.join(" "); // combine timezone back into one string
You could process this further, but you might want to look more into Date: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date
This would work:
const formatDate = (date) => {
const d = new Date(date);
let month = '' + (d.getMonth() + 1);
let day = '' + d.getDate();
const year = d.getFullYear();
if (month.length < 2) {
month = '0' + month;
}
if (day.length < 2) {
day = '0' + day;
}
return [year, month, day].join('-');
}
// Would print 2020-08-30
console.log(formatDate('Sun Aug 30 2020 00:00:00 GMT+0200 (Central European Summer Time)'))
You could use Date node build in lib or moment. If you’re planning to do a lot of date manipulation I would suggest use moment npm package
For getting the date version
moment(your string).format(“YYYY-MM-DD”)
For getting the time
moment(your string).format(“HH:mm”)
function formatDate(date) {
var d = new Date(date),
month = '' + (d.getMonth() + 1),
day = '' + d.getDate(),
year = d.getFullYear();
if (month.length < 2)
month = '0' + month;
if (day.length < 2)
day = '0' + day;
return [year, month, day].join('-');
}
you can use this or if you want to use 3rd party lib moment.js (https://momentjs.com/) is the best and easy to implement

convert date format to 'YYYYMMDD'

In Javascript, I have date string as shown below:
var dateStr = "Wed Mar 25 2015 05:30:00 GMT+0530 (India Standard Time)";
I need to convert it to "YYYYMMDD" format. For example the above date should be : "20150325"
A good function for doing that which I found and used it always.
Date.prototype.yyyymmdd = function() {
var mm = this.getMonth() + 1; // getMonth() is zero-based
var dd = this.getDate();
return [this.getFullYear(),
(mm>9 ? '' : '0') + mm,
(dd>9 ? '' : '0') + dd
].join('');
};
var date = new Date();
date.yyyymmdd();
Here's a dirty hack to get you started. There are numerous ways of achieving the format you want. I went for string manipulation (which isn't the best performance).
var someDate = new Date("Wed Mar 25 2015 05:30:00 GMT+0530 (India Standard Time)");
var dateFormated = someDate.toISOString().substr(0,10).replace(/-/g,"");
alert(dateFormated);
function getFormattedDate(date) {
var year = date.getFullYear();
var month = (1 + date.getMonth()).toString();
month = month.length > 1 ? month : '0' + month;
var day = date.getDate().toString();
day = day.length > 1 ? day : '0' + day;
return year + month + day;
}
And then just call the function :
alert(getFormattedDate(new Date());
The Date object is able to parse dates as string d = new Date( dateStr ); provided that they are properly formatted like the example in your question.
The Date object also offers methods to extract from the instance the year, month and day.
It's well documented and there are plenty of examples if you just Google for it.
What is worth mentioning is that the Date object doesn't handle timezone and the internal date-time is always converted into the client's timezone.
For example here's what I get if I try to parse your date in my browser (I'm in GMT+01):
dateStr = "Wed Mar 25 2015 05:30:00 GMT+0530 (India Standard Time)";
d = new Date( dateStr );
---> Wed Mar 25 2015 01:00:00 GMT+0100 (CET) = $2
If you need to handle timezone properly the easiest way is to use a library like MomentJS

parse JSON date to another format

If I receive all records from DB with JSON how I can change format 2014-09-04 23:20:00 (this is stored on DB) to 04/09/2014. At the moment date are parsed to Thu Jan 01 1970 00:00:02 GMT+0000 (GMT Standard Time)
<script>
$("document").ready(function() {
$.getJSON("test1.php", function(data) {
var table = $("<table>");
$("#div-my-table").empty().append(table);
$.each(data, function(i, item) {
table.append("<tr><td>" + item.code +"</td><td>" + item.line +"</td><td>" + item.org +"</td><td>" + new Date(parseInt(item.by_date.substr("u"))) + "</td></tr>");
});
});
});
</script>
You parse the string, using any of several libraries available for the purpose, and then put it in the format you want, using any of several libraries avaialble for the purpose. On a modern browser, the string you've quoted should be parsed correctly by new Date(), but if you're seeing it not get parsed correctly (your example makes no sense), you may need something like MomentJS.
Or of course, you can regex it:
var yourString = "2014-09-04 23:20:00";
var parts = /^(\d{4})-(\d{2})-(\d{2})/.exec(yourString);
var newString = parts[3] + "/" + parts[2] + "/" + parts[1];
snippet.log("newString = " + newString);
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
If you got the values as Thu Jan 01 1970 00:00:02 GMT+0000 (GMT Standard Time) means, then do like following
var d=new Date('Thu Jan 01 1970 00:00:02 GMT+0000 (GMT Standard Time)');
var day=d.getDate();
var month=d.getMonth()+1;
var year = d.getFullYear();
then format the string like d.getDate()+"/"+(d.getMonth()+1)+"/"+d.getYear()
So you'll get the day, month and year. You can format as the way you want.
You can extract the day, month and year from your Date and then use it to form a string. You can try something as the following:
var dateObj = new Date(jsonDate);
var month = dateObj.getUTCMonth() + 1; //months from 1-12
var day = dateObj.getUTCDate();
var year = dateObj.getUTCFullYear();
newdate = day + "/" + month + "/" + year;
alert(newdate);
where jsonDate is the date element you extracted from JSON.
// Split timestamp into [ Y, M, D, h, m, s ]
var t = "2010-06-09 13:12:01".split(/[- :]/);
// Apply each element to the Date function
var d = new Date(t[0], t[1]-1, t[2], t[3], t[4], t[5]);
alert(d);
// -> Wed Jun 09 2010 13:12:01 GMT+0100 (GMT Daylight Time)

How to change date format in JS

I found a solution to transform a date like:
Thu Sep 04 2014 00:00:00 GMT+0200 (Romance Daylight Time)
to a format french 04/09/2014
How can i achieve this?
You can do that by using the Date object and its functions:
function zerofy(number){
if(number < 10)
number = "0" + number;
return number;
}
var date = new Date("Thu Sep 04 2014 00:00:00 GMT+0200 (Romance Daylight Time)");
var day = zerofy(date.getDate());
var month = zerofy(date.getMonth());
var year = date.getFullYear();
var result = day + "/" + month + "/" + year
console.log(result);
Working Demo
I would recommend going over this document from MDN for these kind of problems.
Perhaps a basic one-liner would help?
function formatDate(date){
return [('0'+date.getDate()).slice(-2),('0'+date.getMonth()).slice(-2),date.getFullYear()].join('/');
}

Convert RFC 822 date to valid Date for javascript

I'm using a script calendar that when I choose a date, it convert it to a new format (yyyy-mm-dd)
It works in most browser but in Firefox and Opera, I get an invalid date format because the format i work with is RFC 822.
I'm looking for a way to convert this date format
example:
Thu Sep 08 2011 12:00:00 GMT-0400 (EDT)
and change it to
2011-09-08
Could that be done in javascript ?
UPDATE
Here's my code trying to replace the (EDT) to nothing
$(".taskDate").datepick({
onSelect: function(selectedDate){
selectedDate = selectedDate.replace(/ \(.+\)/, '');
//alert(selectedDate);
var newDate = new Date(selectedDate);
$(".selectedDate").text(newDate.getFullYear()+'-'+(newDate.getMonth()+1)+'-'+newDate.getDate());
location.href="index.php?date="+newDate.getFullYear()+'-'+(newDate.getMonth()+1)+'-'+newDate.getDate();
}
});
Now I get an error
selectedDate.replace is not a function
How come ?
UPDATE 2
Fixed it because it seems that it was an object and not a darn string.
Added
selectedDate = selectedDate.toString();
before the new Date();
Now it's working for all browsers...
Works in Firefox6, see my jsfiddle.
var sOriginalDate = 'Thu Sep 08 2011 12:00:00 GMT-0400 (EDT)';
var oDate = new Date(sOriginalDate);
var iMonth = oDate.getMonth() + 1;
var iDay = oDate.getDate();
var sNewDate = oDate.getFullYear() + '-'
+ (iMonth < 10 ? '0' : '') + iMonth + '-'
+ (iDay < 10 ? '0' : '') + iDay;
alert(sNewDate);
Since the date is RFC 822 you could parse it to a valid Date (the ending EDT does not affect the result):
var dateAsDateObject = new Date(Date.parse(dateInRFC822Format));
This will work with dateInRFC822Format equal to either "Thu Sep 08 2011 12:00:00 GMT-0400 (EDT)" or "Thu Sep 08 2011 12:00:00 GMT-0400"
Now you can get the info you require from dateAsDateObject:
year: dateAsDateObject.getFullYear()
month: dateAsDateObject.getMonth()
day: dateAsDateObject.getDay()
Note: for formatting, if you don't mind using jqueryui you could also use the $.datepicker.formatDate() method. E.g. var stringRepresentation = $.datepicker.formatDate('yy-mm-dd', dateAsDateObject);
Try:
var mydate = new Date(originaldate);
mydate = mydate.getYear() + '-' + (mydate.getMonth() + 1) + '-' + mydate.getDate();

Categories