Javascript Date Comparison not behaving as expected - javascript

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.

Related

I need to get all the dates between any two dates in JavaScript

Using this code I am getting the dates excluding the start dates
var startdate = new Date("");
var enddate = new Date("");
while (startdate < enddate) {
startdate.setDate(startdate.getDate() + 1);
dates.push(new Date(startdate).format("mm/dd/yyyy"));
}
You should replace new Date(startdate) with new Date(startdate.getTime()) to avoid JS error. However, you cannot simply format JS Date object with format(), as this function does not exist, you have to extract year, month, day by yourself. If you want to do it, beware the month value is started from zero.
Please consider using a library like Moment.js instead, it is a lot handy to manipulate date, time and duration.
You can't simply format javascript date using format function, which doesn't exists. You need to split date, month, year and join. Here it may help-
var startdate = new Date();
var enddate = new Date("2019, 10, 23");
while (startdate < enddate) {
startdate.setDate(startdate.getDate() + 1);
dates.push(startdate.getMonth()+1+"/"+startdate.getDate()+"/"+startdate.getFullYear());
}
You have to increase moth by 1 startdate.getMonth()+1 because month starts from 0 in JS.
Consider using Moment.js which has lots of facility.

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.

Convert ISO date to international date type javascript

I want to filter data by current month (maybe additionally add next month data). I don't know how to go from the beginning.
In theory I think I could compare current month and month date from my data and then to display data only if two months variables match.
I thought I should start like this:
var myDate = new Date();
var thisMonth = new Date(myDate);
thisMonth.setMonth(myDate.getMonth()+1);
var nextMonth = new Date(myDate);
nextMonth.setMonth(myDate.getMonth()+2);
Thank you in advance for any kind of help!
Additional detailed explanation:
I copied SharePoint 2013 list whose data I displayed on SharePoint site page.
In content editor web part I wrote javascript code to show that list as a table.
I have two date columns (from/until) but they are displayed in table as YYYY-MM-DD HH:MM:SS. Looks to me like ISO date format. I saw several examples how to convert in js that type of date into date type like DD.MM.YYYY. None worked for me or I didn't know how to do it correctly. So I created calculated field that will present date type as text/string, after this I managed to show date on js table the way I wanted.
You should not parse strings with the Date constructor (or Date.parse, they are equivalent for parsing) as it's largely implementation dependent and notoriously unreliable.
I have two date columns (from/until) but they are displayed in table as YYYY-MM-DD HH:MM:SS. Looks to me like ISO date format.
Almost. The extended format is YYYY-MM-SSTHH:MM:SS, the T can be replaced by a space on agreement between parties exchanging the date but it's not strictly correct. If the timezone is omitted, it's treated as a "local" date (i.e. the host timezone offset is used in calculating the moment in time that it represents).
According to ECMA-262, if the format is not correct, browsers can either:
Treat it as invalid ISO 8601 and return an invalid date
Treat it as not ISO 8601 and fall back to whatever parsing algorithm they wish to use
So given:
new Date('2017-01-01 23:12:12')
Firefox returns a Date for 1 Jan 2017 23:12:12 in the host time zone, Safari returns an invalid date. Both are consistent with the standard.
So if you need a Date object, you should parse the string manually using either a library (e.g. fecha.js or moment.js) or a simple function.
But anyway, you don't need to parse the strings to a Date to reformat the string, just use string methods and avoid Date parsing vagaries completely.
function filterCurrentMonth() {
// Create string for comparison
var d = new Date();
var currentMonth = d.getFullYear() + '-' + ('0' + (d.getMonth()+1)).slice(-2);
// Hide rows that don't have string in the first cell
var rows = document.getElementById('t0').rows;
[].forEach.call(rows, function(row) {
if (row.cells[0].textContent.indexOf(currentMonth) == -1) {
row.style.display = 'none';
} else {
row.style.display = '';
}
});
}
function filterNone() {
var rows = document.getElementById('t0').rows;
[].forEach.call(rows, function(row) {
row.style.display = '';
});
}
#t0 {
font-size: 60%;
}
<button onclick="filterCurrentMonth()">Show only current month rows</button>
<button onclick="filterNone()">Show all rows</button>
<table id="t0">
<tr><td>2017-01-01 23:12:12<tr><td>2017-02-01 23:12:12<tr><td>2017-05-01 23:12:12
<tr><td>2017-03-01 23:12:12<tr><td>2017-04-01 23:12:12<tr><td>2017-12-01 23:12:12
<tr><td>2017-10-01 23:12:12<tr><td>2017-11-01 23:12:12<tr><td>2017-06-01 23:12:12
<tr><td>2017-07-01 23:12:12<tr><td>2017-09-01 23:12:12<tr><td>2017-08-01 23:12:12
<tr><td>2017-01-01 23:12:12<tr><td>2017-02-01 23:12:12<tr><td>2017-05-01 23:12:12
<tr><td>2017-03-01 23:12:12<tr><td>2017-04-01 23:12:12<tr><td>2017-12-01 23:12:12
<tr><td>2017-10-01 23:12:12<tr><td>2017-11-01 23:12:12<tr><td>2017-06-01 23:12:12
<tr><td>2017-07-01 23:12:12<tr><td>
<!-- begin snippet: js hide: false console: true babel: false -->
23:12:122017-08-01 23:12:12
Similarly, if you want to reformat the string to be DD.MM.YYYY you can just reformat the string:
/* Format string in YYYY-MM-DD HH:mm:ss format to DD.MM.YYYY
** #param {string} s - string in YYYY-MM-DD HH:mm:ss format
** #returns {string} in DD.MM.YYYY format
*/
function formatYMDtoDMY(s) {
var b = s.split(/\D/);
return b[2] + '.' + b[1] + '.' + b[0];
}
console.log(formatYMDtoDMY('2017-10-01 23:12:12'))
Note however that dates should use unambiguous formats like DD-MMM-YYYY, e.g. 01-Jan-2017. It only takes one more line of code for that. ;-)
Don't forget, getMonth() returns a Number, from 0 to 11, representing the month,
and Date make the date as object with methods and properties
There is a lot of examples here
var date = new Date('2010-10-11 00:00:00');
var formatDate = date.getDate() + '/'
+ (date.getMonth() + 1) + '/'
+ date.getFullYear();
console.log( formatDate );
So you can always pass the date on any format but there some important moments you can read here:
Converting string to date in js
Are you asking?
I don't know how to go from the beginning.
You could get the beginning from current month and the last date of next month by following code:
<html>
<script>
var myDate = new Date();
var thisMonth = new Date(myDate.getFullYear(), myDate.getMonth(), 1);
var nextMonth = new Date(myDate.getFullYear(), myDate.getMonth() + 2, 0);
console.log("Date start: " + thisMonth);
console.log("Date end: " + nextMonth);
console.log("Formatted date start: " + formatDate(thisMonth));
console.log("Formatted date end: " + formatDate(nextMonth));
function padLeft(n){
return ("00" + n).slice(-2);
}
function formatDate(){
var d = new Date,
dformat = [ d.getFullYear(),
padLeft(d.getMonth()+1),
padLeft(d.getDate())
].join('-')+
' ' +
[ padLeft(d.getHours()),
padLeft(d.getMinutes()),
padLeft(d.getSeconds())].join(':');
return dformat
}
</script>
</html>
I hope it helps you. Bye.

What is the proper way to create a timestamp in javascript with date string?

I have date format returned as 05-Jan, 12-feb etc.. when i convert current date using date object in javascript . I did something like this
var curr = new Date(),
curr_year = curr.getFullYear(),
curr_month = curr.getMonth(),
curr_day = curr.getDay(),
today = new Date(curr_year, curr_month, curr_day, 0, 0, 0, 0);
console.log(today);
Here the today is returned as invalid date i needed the create a timestamp which should not include minutes secs and millisecs as zero for date comparison of month and date alone based on that i can categories .Is there way to dynamically create a date and compare those dates for given format.
And when i try to convert my date string using date object it returns year as 2001. how can i compare dates based upon current year.
For eg: in php i have used mktime to create a date dynamically from given date format and compare those results. Any suggestion would be helpful. Thanks.
You can leverage the native JS Date functionality to get human-readable date strings for time stamps.
var today = new Date();
console.log( today.toDateString() ); // Outputs "Mon Feb 04 2013"
Date comparison is also built in.
var yesterday = new Date();
yesterday.setDate( yesterday.getDate() - 1);
console.log( yesterday.toDateString() ); // Outputs "Sun Feb 03 2013"
console.log( yesterday < today ); //Outputs true
You can use the other built-in methods to fine-tune this comparison to be/not be sensitive to minutes/seconds, or to set all those to 0.
You said that you used mktime() in php, so what about this?
change to this :
var curr = new Date(),
curr_year = curr.getFullYear(),
curr_month = curr.getMonth()+1,
curr_day = curr.getDay(),
today = curr_month+'/'+curr_day+'/'+curr_year;
console.log(today);
(getMonth()+1 is because January is 0)
change the :
today = curr_month+'/'+curr_day+'/'+curr_year;
to whatever format you like.
I have found a way to convert the date into timestamp i have tried as #nbrooks implemented but .toDateString has built in date comparison which works for operator < and > but not for == operator to do that i have used Date.parse(); function to achieve it. Here it goes..
var curr = new Date(),
curr_year = curr.getFullYear(),
curr_month = curr.getMonth(),
curr_day = curr.getDate(),
today = new Date(curr_year, curr_month, curr_day, 0,0,0,0);
var dob = new Date('dob with month and date only'+curr_year);
if(Date.parse(dob) == Date.parse(today)){
//Birthdays....
}
This method can be used to create a timestamp for dynamically created date.Thanks for your suggestions.

jQuery how can you verify date formatted mm/dd/yyyy is not greater than current date today

How do I verify in jQuery that a date entered on a input text box or value in html such as mm/dd/yyyy is not greater than todays date. Example would be "5/5/2011" would pass as true b/c its not greater than today "6/17/2011", but "5/5/3011" would be greater than today and should return false. Is there a simple function that can return true or false if a date in form "mm/dd/yyyy" is greater than todays date in javascript or jQuery?
Just convert to a Date object and compare your date value to Date.now - for example:
alert( Date.parse("3/1/2012") > Date.now())
You do not actually need to use jQuery for this at all, pure JavaScript is good enough. Please have a look at the docs for Javascript Date for more information.
convert to javascript Date objects to compare.
var d = new Date("5/5/2011")
var d2 = new Date()
var b = d < d2 // << true...
First off, you need to be sure that dates have a universal format. 10/1/2011 is in the future in the US (October 1st, 2011) but in the past in the UK (10th January 2011). If that's satisfied, the below will work just fine:
function greaterThanToday(datestring) {
var today = new Date();
var date = new Date(datestring);
return (date > today);
}
alert("5/5/2011: " + greaterThanToday("5/5/2011"));
alert("5/5/3011: " + greaterThanToday("5/5/3011"));
Don't even need jQuery, just Date objects.
Date.parse("6/17/2011") > Date.parse("5/5/3011")

Categories

Resources