Timestamp parse not working in IE - javascript

I have a timestamp in the following format:
[yyyy-MM-ddThh:mm:ssZ] (example: 2015-05-15T03:34:17Z)
I want's to parse this timestamp into Date and format is like: [Fri May 15 2015 09:04:17 GMT +5:30]:
Now, i am use the following code to parse and it work's fine in Firefox 3.6+ browsers. But the problem is, it's not working in internet explorer (IE) 8, in IE it returns 'NaN'.
My Javascript code is:
var myDate = new Date(timestampDate);
//In Firefox i get myDate as Date object and i can get day, month and year. But in IE this myDate value is coming as NaN
var day = myDate.getDate();
var month = myDate.getMonth();
var year = myDate.getFullYear();
Any help is rewarded. Please give me a solution to make this working in IE also.

(function(){
//if the browser correctly parses the test string, use its native method.
var D= new Date('2011-06-02T09:34:29+02:00');
if(D && +D=== 1307000069000) Date.fromISO= function(s){
return new Date(s);
};
Date.fromISO= function(s){
var day, tz,
rx=/^(\d{4}\-\d\d\-\d\d([tT][\d:\.]*)?)([zZ]|([+\-])(\d\d):(\d\d))?$/,
p= rx.exec(s) || [];
if(p[1]){
//extract the y-m-d h:m:s.ms digits:
day= p[1].split(/\D/);
for(var i= 0, L= day.length; i<L; i++){
day[i]= parseInt(day[i], 10) || 0;
};
day[1]-= 1; //adjust month
//create the GMT date:
day= new Date(Date.UTC.apply(Date, day));
if(!day.getDate()) return NaN;
if(p[5]){
// adjust for the timezone, if any:
tz= (parseInt(p[5], 10)*60);
if(p[6]) tz+= parseInt(p[6], 10);
if(p[4]== '+') tz*= -1;
if(tz) day.setUTCMinutes(day.getUTCMinutes()+ tz);
}
return day;
}
return NaN;
}
})();
//test alert(Date.fromISO("2015-05-15T03:34:17Z").toUTCString())

yyyy-MM-ddThh:mm:ssZ is an ISO date. Browsers don't support them very well, FireFox doesn't parse 2015-05-15T03:34:17+01 for example.
You'll have to extract the elements out of the string manually before creating your date.

I had the same problem and found this, supposing that you use jQuery UI:
$.datepicker.parseDate('yy-mm-dd', '2014-02-14');
This is a useful method of the UI Datepicker. I'm just about to write my own date parser to make my code jqui-independent but it may help others so I leave this answer here.

Related

If current date and time is greater (after) than X

I am trying to create an if statement that can check today's date and time and if it's greater than a predefined date and time, do something. I'm looking to do this in vanilla JS only and get it to work in IE.
This is the basic working code for Chrome.
var ToDate = new Date()
if (new Date("2018-11-30 05:00").getTime() > ToDate.getTime()) {
alert("true")
} else {
alert("false")
}
How can I make something like this work in IE?
if (new Date("2018-11-30 05:00").getTime() > ToDate.getTime()) {
On firefox and chrome there are no issues with it. On Internet Explorer it's false.
On IE (or in general) the string needs to be an RFC2822 or ISO 8601 formatted date
Example:
new Date("2018-11-29T19:15:00.000Z")
If you need portable solution (eg. support older Internet Explorer) I would use this constructor instead:
new Date(year, monthIndex [, day [, hours [, minutes [, seconds [, milliseconds]]]]]);
Keep in mind that monthIndex starts from 0 (January).
Test:
function assertTrue(exp, message) {
if (exp === false) {
message = message || 'Assertion failed';
alert(message);
throw message;
}
}
function testShouldPassForDatesInTheFuture() {
var ToDate = new Date(2018, 10, 29);
assertTrue(new Date(2018, 10, 30).getTime() > ToDate.getTime());
}
function testShouldPassForDatesInThePast() {
var ToDate = new Date(2018, 10, 29);
assertTrue(new Date(2018, 10, 28).getTime() < ToDate.getTime());
}
testShouldPassForDatesInThePast();
testShouldPassForDatesInThePast();
alert('All test passed');
You need to append 'T00:00:00.000Z' to your date.
new Date("2018-11-30" + 'T00:00:00.000Z')
Full code is below:
var ToDate = new Date()
if (new Date("2018-11-30" + 'T00:00:00.000Z').getTime() > ToDate.getTime()) {
alert("true")
} else {
alert("false")
}
Your issue is that the date format YYYY-MM-DD HH:mm is not supported by ECMAScript, so parsing is implementation dependent. Safari, for example:
new Date("2018-11-30 05:00")
returns an invalid date.
You can first parse the string manually, either with a bespoke function (e.g. How to parse a string into a date object at JavaScript?) or a library, then you can compare the result with new Date() as for Compare two dates with JavaScript.
A simple parse function is not difficult:
/* Parse string in YYYY-MM-DD HH:mm:ss to a Date
* All parts after YYYY-MM are optional, milliseconds ignored
*/
function parseDate(s) {
var b = s.split(/\D/);
return new Date(b[0], b[1]-1, b[2]||1, b[3]||0, b[4]||0, b[5]||0);
}
["2018-11-23 17:23",
"2019-01",
"2020-12-31 23:59:59"].forEach(s => {
console.log(`${s} => ${parseDate(s).toString()}`);
});
Then you can compare dates using <, <=, > and >=.
In this case, a date like "2018-01-01" will be considered past at any time after 2018-01-01 00:00:00.000.
Alternatively, since the string is similar to ISO 8601 format, you can compare the parts of the string with a similarly formatted string for today:
// Return date string in YYYY-MM-DD HH:mm:ss format
// Only return as many parts as len, or all 6 if missing
function formatDate(d, len) {
var parts = [d.getFullYear(), '-'+d.getMonth()+1, '-'+d.getDate(), ' '+d.getHours(), ':'+d.getMinutes(), ':'+d.getSeconds()];
var spacer = ['-','-',' ',':',':'];
len = len || 6;
return parts.splice(0, len).join('');
}
['2018-06-30 12:04',
'2018-10',
'2018-12-15 03:14:45',
'2019-01-01',
'2020-12-15 03:14:45'].forEach(s => {
console.log(`${s} has passed? ${s < formatDate(new Date(), s.split(/\D/).length)}`);
});
In this case, 2018-01-01 will be equal to any date generated on that day, and "2018-01" will be equal to any date generated in January 2018. It's up to you whether you use < or <= for the comparison.
So you need to consider carefully where you draw the boundary between earlier and later and adjust the logic accordingly.

Angular $filter is not working in firefox and safari

I am formatting the existing date using Angular.js but its only working in chrome. I am explaining my code below.
$scope.timestamp=2016-12-16 07:58:30 AM
$scope.orginalTime= $filter('date')(new Date($scope.timestamp.replace("-","/")),'dd-MM-yyyy HH:mm:ss a');
Here i am formatting the date time but its only working in chrome. I need this should work in all browser including firefox,safari+MAC.
It's always better to manually parse strings as results are inconsistent across browsers. You do something like this
function parseDate(timestamp){
raw = timestamp.split(" ");
date = raw[0].split("-");
time = raw[1].split(":");
month = parseInt(date[1]-1);
hour = raw[2] == "AM" ? time[0] : parseInt(time[0]) + 12;
return new Date(date[0], month, date[2], hour, 58, 30);
}
parseDate("2016-12-16 07:58:30 AM");

Javascript Date Comparison not behaving as expected

I am getting a SQL date - NOT datetime - object pushed into my Javascript code, and I need to see whether it's before today or not. Here is the code I have (the relevant part):
todaysDate = new Date();
todaysDate.setHours(0,0,0,0);
var date = Date.parse(row[3]);
// date.setHours(0,0,0,0);
if (date < todaysDate) {
alert("date is before today");
dueDate = '<small class="text-danger">';
} else {
alert("date is after today");
dueDate = '<small class="text-muted">';
}
row[3] is the source of the SQL date. So, this works fine for everything except dates that are today. Without the commented line, it thinks that anything with today's date is in the past. With the commented line, my code breaks. Any thoughts as to how to fix this? Not sure what I'm doing wrong.
Thanks!
If your date string is like "2016-04-10" and your time zone is west of GMT, say -04:00, then in browsers compliant with ECMAScript 2016 you will get a Date for "2016-04-09T19:00:00-0400".
When you create a Date using new Date() and set the hours to zero (assuming it's 10 April where you are), you'll get a Date for "2016-04-10T00:00:00-0400".
So when compared they have different time values.
What you need is to either treat the string you get from the database as local, or get the UCT date where you are, so:
var dateString = '2016-04-10';
var parsedDate = new Date(dateString);
var todayUTCDate = new Date();
todayUTCDate.setUTCHours(0,0,0,0);
document.write(parsedDate + '<br>' + todayUTCDate);
But not all browsers parse strings according to ECMAScript 2015 so they should always be manually parsed. Use a library, or write a small function, e.g.
// Parse date string in format 'yyyy-mm-dd' as local date
function parseISOLocal(s) {
var b = s.split(/\D/);
return new Date(b[0], b[1]-1, b[2]);
}
and replace:
var date = Date.parse(row[3]);
with:
var date = parseISOLocal(row[3]);
and then in the comparison, compare the time values:
if (+date < +todaysDate) {
or
if (date.getTime() < todaysDate.getTime()) {
Use getTime() of date object.
The getTime() method returns the number of milliseconds between midnight of January 1, 1970 and the specified date.
You can compare miliseconds and do your operations
date.getTime() > todaysDate.getTime()
Also be sure that Date.parse is returning a valid date.

Comparing javascript date time and timestamp from PostgreSQL

In PostgreSQL database, I have save in the timestamp column this value: 2013-03-15 08:50:00.
My goal is to take this date from database and check, if the current time is less about 12 hours than the time from database.
For this purpose, I wanted to get the current time from new Date() and compare it with the date from database - but this doesn't work because of different time formats.
How could I do that and convert those times on the same (comparable) format?
var ds='2013-03-15 08:50:00';
without any timezone information you can't really tell what day it is.
Assuming your string is in UTC, you can use the Date constructor
if you replace the space with a 'T' and add a 'Z' at the end:
var ds='2013-03-15 08:50:00';
var day=new Date(ds.replace(' ','T')+'Z');
day.toUTCString()
Fri, 15 Mar 2013 08:50:00 GMT
You can write a Date parsing function that will parse ISO or sql formats,
which may be needed on some older browsers.
Date.fromISO= function(s){
var day, tz,
rx=/^(\d{4}\-\d\d\-\d\d([tT ][\d:\.]*)?)([zZ]|([+\-])(\d\d):(\d\d))?$/,
p= rx.exec(s) || [];
if(p[1]){
day= p[1].split(/\D/);
for(var i= 0, L= day.length;i<L;i++){
day[i]= parseInt(day[i], 10) || 0;
};
day[1]-= 1;
day= new Date(Date.UTC.apply(Date, day));
if(!day.getDate()) return NaN;
//adjust for time zone offset:
if(p[5]){
tz= (parseInt(p[5], 10)*60);
if(p[6]) tz+= parseInt(p[6], 10);
if(p[4]== '+') tz*= -1;
if(tz) day.setUTCMinutes(day.getUTCMinutes()+ tz);
}
return day;
}
return NaN;
}
then call Date.fromISO('2013-03-15 08:50:00');

Validate two dates of this "dd-MMM-yyyy" format in javascript

I have two dates 18-Aug-2010 and 19-Aug-2010 of this format. How to find whether which date is greater?
You will need to create a custom parsing function to handle the format you want, and get date objects to compare, for example:
function customParse(str) {
var months = ['Jan','Feb','Mar','Apr','May','Jun',
'Jul','Aug','Sep','Oct','Nov','Dec'],
n = months.length, re = /(\d{2})-([a-z]{3})-(\d{4})/i, matches;
while(n--) { months[months[n]]=n; } // map month names to their index :)
matches = str.match(re); // extract date parts from string
return new Date(matches[3], months[matches[2]], matches[1]);
}
customParse("18-Aug-2010");
// "Wed Aug 18 2010 00:00:00"
customParse("19-Aug-2010") > customParse("18-Aug-2010");
// true
You can do the parsing manually, for your given format, but I'd suggest you use the date.js library to parse the dates to Date objects and then compare.
Check it out, its awesome!
And moreover, its a great addition to your js utility toolbox.
The native Date can parse "MMM+ dd yyyy", which gives:
function parseDMY(s){
return new Date(s.replace(/^(\d+)\W+(\w+)\W+/, '$2 $1 '));
}
+parseDMY('19-August-2010') == +new Date(2010, 7, 19) // true
parseDMY('18-Aug-2010') < parseDMY('19-Aug-2010') // true
Firstly, the 'dd-MMM-yyyy' format isn't an accepted input format of the Date constructor (it returns an "invalid date" object) so we need to parse this ourselves. Let's write a function to return a Date object from a string in this format.
function parseMyDate(s) {
var m = ['jan','feb','mar','apr','may','jun','jul','aug','sep','oct','nov','dec'];
var match = s.match(/(\d+)-([^.]+)-(\d+)/);
var date = match[1];
var monthText = match[2];
var year = match[3];
var month = m.indexOf(monthText.toLowerCase());
return new Date(year, month, date);
}
Date objects implicitly typecast to a number (milliseconds since 1970; epoch time) so you can compare using normal comparison operators:
if (parseMyDate(date1) > parseMyDate(date2)) ...
Update: IE10, FX30 (and likely more) will understand "18 Aug 2010" without the dashes - Chrome handles either
so Date.parse("18-Aug-2010".replace("/-/g," ")) works in these browsers (and more)
Live Demo
Hence
function compareDates(str1,str2) {
var d1 = Date.parse(str1.replace("/-/g," ")),
d2 = Date.parse(str2.replace("/-/g," "));
return d1<d2;
}

Categories

Resources