Comparing two dates with javascript or datejs (date difference) - javascript

I am trying to compare two dates which are in Finnish time form like this: dd.mm.YYYY or d.m.YYYY or dd.m.YYYY or d.mm.YYYY.
I am having a hard time finding out how to do this, my current code won't work.
<script src="inc/date-fi-FI.js" type="text/javascript"></script>
<script type="text/javascript">
function parseDate() {
var date = $('#date').val();
var parsedDate = Date.parse(date);
alert('Parsed date: '+parsedDate);
}
function jämförMedIdag (datum) {
if (datum == null || datum == "") {
alert('Inget datum!');
return;
}
/*resultat = Date.compare(Datum1,Datum2);
alert(resultat); */
var datum = Date.parse(datum);
var dagar = datum.getDate();
var månader = datum.getMonth();
var år = datum.getYear();
var nyttDatum = new Date();
nyttDatum.setFullYear(år,månader,dagar);
var idag = new Date();
if(nyttDatum>idag) {
var svar = nyttDatum - idag;
svar = svar.toString("dd.MM.yyyy");
alert(svar);
return(svar);
} else {
var svar = idag - nyttDatum;
svar = svar.toString("dd.MM.yyyy");
alert(svar);
return(svar);
}
}
</script>
This code will try to calculate the difference between two dates, one of them being today. No success lolz.
Thanks in advance!
My final code (thanks RobG!):
function dateDiff(a,b,format) {
var milliseconds = toDate(a) - toDate(b);
var days = milliseconds / 86400000;
var hours = milliseconds / 3600000;
var weeks = milliseconds / 604800000;
var months = milliseconds / 2628000000;
var years = milliseconds / 31557600000;
if (format == "h") {
return Math.round(hours);
}
if (format == "d") {
return Math.round(days);
}
if (format == "w") {
return Math.round(weeks);
}
if (format == "m") {
return Math.round(months);
}
if (format == "y") {
return Math.round(years);
}
}
It is not fully accurate, but very close. I ended up adding some addons to it to calculate in day week month year or hour, anyone can freely copy and use this code.

If you are using Datejs, and the optional time.js module, you can run your calculations with the following code by creating a TimeSpan object:
Example
// dd.mm.YYYY or d.m.YYYY
// dd.m.YYYY or d.mm.YYYY
var start = Date.parse("20.09.2011");
var end = Date.parse("28.09.2011");
var span = new TimeSpan(end - start);
span.days; // 8
Of course the above could be simplified down to one line if you really want to be extra terse.
Example
new TimeSpan(Date.parse(end) - Date.parse(start)).days; // pass 'end' and 'start' as strings
Hope this helps.

If your dates are strings in the common form d/m/y or some variation thereof, you can use:
function toDate(s) {
var s = s.split('/');
return new Date(s[2], --s[1], s[0]);
}
You may want to validate the input, or not, depending on how confident you are in the consistency of the supplied data.
Edit to answer comments
To permit different separators (e.g. period (.) or hyphen (-)), the regular expression to split on can be:
var s = s.split(/[/\.-]/);
The date will be split into date, month and year numbers respectively. The parts are passed to the Date constructor to create a local date object for that date. Since javascript months are zero indexed (January is 0, February is 1 and so on) the month number must be reduced by one, hence --s[1].
/Edit
To compare two date objects (i.e get the difference in milliseconds) simply subtract one from the other. If you want the result in days, then divide by the number of milliseconds in a day and round (to allow for any minor differences caused by daylight saving).
So if you want to see how many days are between today and a date, use:
function diffToToday(s) {
var today = new Date();
today.setHours(0,0,0);
return Math.round((toDate(s) - today) / 8.64e7);
}
alert(diffToToday('2/8/2011')); // -1
alert(diffToToday('2/8/2012')); // 365
PS. The "Finnish" data format is the one used by the vast majority of the world that don't use ISO format dates.

Using the Date object:
var today = Date.today();
var dateToday = Date.parse(today.toString('MMMM d, yyyy'));
var prevMonthDate = dateToday.addDays(-30);
var difference = (dateToday - prevMonthDate)/86400000;
console.log(difference); //will give you the difference in days.

Related

Compare a date in string format with todays date

I know this has been asked before but I can't get it to work due to my date format, which I can't change. Any help would be appreciated.
My date is in this format;
4/11/2017 12:30 PM.
If I inspect it in the developer tools it shows it as
4/11/2017 12:30 PM EDIT: Won't show with prepended space here
i.e. with a space in front, not sure if that's relevant.
Does anyone know if it's possible or how to compare it with today's date to see if it's in the past or future?
I've tried tinkering with the following code but can't get it to work because of the time, PM, and forward slashes.
var q = new Date();
var m = q.getMonth();
var d = q.getDate();
var y = q.getFullYear();
var date = new Date(d,m,y);
mydate=new Date('13/04/2017');
console.log(date);
console.log(mydate)
if(date>mydate)
{
alert("greater");
}
else
{
alert("smaller")
}
If you have dates that are in the same format of something like 13/04/2017, you could split the string based on the slashes and compare the values starting from the right moving left.
By this, I mean when you have your array of three values for each date, you could first compare the year, if that's the same, move on to comparing the month, if that's the same then on to comparing the day.
But if for instance one of the year's is 2018 while the other is 2016, you would immediately know that the 2018 one comes later.
var st = "19/05/2019";
var st2 = "19/05/2019";
function provideLaterDate(date1, date2) {
var splitDateDate1 = date1.split("/").reverse();
var splitDateDate2 = date2.split("/").reverse();
var laterDate = false;
splitDateDate1.forEach(function(val, idx, arr) {
if ( laterDate === false ) {
if ( val > splitDateDate2[idx] ) {
laterDate = splitDateDate1;
} else if ( val < splitDateDate2[idx]) {
laterDate = splitDateDate2;
} else {
laterDate = "Both are the same";
}
}
});
if ( /\//.test(laterDate) ) {
return laterDate.reverse().join("/");
} else {
return laterDate;
}
}
To get rid of the "time pm" part, you could simply do something like:
// Assuming your date has a structure like this: 4/11/2017 12:30 PM.
var newDate = unformattedDate.split(" ")[0];
// This will separate your date string by spaces, and since there are no spaces until after the year in your date, the 0 index will give you the date minus the time and pm portion. Please pardon the not-consistent variable names.
The problem was with the way you were constructing date. Construct date like this var mydate = new Date(2017, 04, 03); and it works.
var q = new Date();
var m = q.getMonth();
var d = q.getDate();
var y = q.getFullYear();
var date = new Date(d, m, y);
var mydate = new Date(2017, 04, 03);
console.log(date);
console.log(mydate)
if (date > mydate) {
alert("greater");
}
else {
alert("smaller")
}
You can split the date. Be aware you should contruct your date as follows:
var date = new Date(y,m,d);
Means year first, then month and finally day, as you can see under https://www.w3schools.com/jsref/jsref_obj_date.asp
You can use the following code to perform what you want:
var q = new Date();
var m = q.getMonth();
var d = q.getDate();
var y = q.getFullYear();
var date = new Date(y,m,d);
newdate = '13/04/2017'
array = newdate.split('/');
var d1 = array[0]
var m1 = array[1]-1
var y1 = array[2]
mydate = new Date(y1,m1,d1);
console.log(date);
console.log(mydate)
if(date>mydate)
{
alert("greater");
}
else
{
alert("smaller")
}
You can always check the date created is correct by using the date.toString() function. Be aware 0=January for month as you can check under https://www.w3schools.com/jsref/jsref_getmonth.asp. That's why I added the -1 for var m1.
Problem:
It's not working because you are comparing a date with an Invalid date, it will always return false.
Explanation:
And the Invalid date comes from the line new Date('13/04/2017'), because 13 is expected to be a month number and not a day which is an invalid month, because the new Date(stringDate) will be treated as a local Date and not a UTC date by the browser, and it depends on which browser you are using.
You can see in the JavaScript Date Specification that:
parsing of date strings with the Date constructor (and Date.parse, they are equivalent) is strongly discouraged due to browser differences and inconsistencies. Support for RFC 2822 format strings is by convention only. Support for ISO 8601 formats differs in that date-only strings (e.g. "1970-01-01") are treated as UTC, not local.
Demo:
So if we change new Date('13/04/2017') to new Date('04/13/2017') the code will work as expected:
var date = new Date();
var mydate = new Date('04/13/2017');
console.log(date);
console.log(mydate)
if (date > mydate) {
alert("greater");
} else {
alert("smaller")
}
if(date.getTime()>mydate.getTime()){
alert("greater");
}
else if (date.getTime()==mydate.getTime){
alert("simmilar");
else {alert("smaller");}

Using Javascript to subtract two dates given from form entries

I'm trying to use javascript to subtract two dates. The date values come from form fields. I'm using Formidable Pro on a WordPress site for the form.
The form is one to allow a business to pay taxes. The taxes are due on the 20th of each month. Sometimes a business may pay their taxes late, so at the beginning of the form they specify what month they are paying taxes for.
The first date is the current date. It's populated into the form field using Formidable short code in the format mm/dd/yyyy.
The second date is calculated from from entries for Year and Month. Those values are then concatenated with "20" to form a full date value for the 20th of the month for which they are paying taxes.
If they are paying taxes on or before the 20th, there is no penalty. If it's after 20th, there's a penalty. I want to subtract the dates and then determine whether the payment is late based on the difference being greater than zero--and that difference value being populated into a form field.
This is the code I've been using. You'll see where I commented out one method of calculating and returning the difference value into the form.
With the code below, the script returns a "NaN" error into the difference field.
Why? How do I fix the error and have it report the difference? All I need to know is if its negative or >= zero.
<script type="text/javascript">
jQuery(document).ready(function($){
$('#field_21nfg, #field_o1ns5').change(function(){
var Year = $("#field_21nfg").val();
var Month = $("#field_o1ns5").val();
$("#field_tm25b").val(Month+'/'+'20'+'/'+Year);
// var Due = $("#field_tm25b5").val();
// var Today = $("#field_1pjvu").val();
//
// var dDue = new Date('Due');
// var dToday = new Date('Today');
// var diff = Math.floor(dDue - dToday);
// $("#field_smmyr").val(diff);
var oneDay = 24*60*60*1000;
var Today_str = $("#field_1pjvu").val(); // E.g., "mm/dd/yyyy";
var Today_dt = new Date(parseInt(Today_str.substring(6), 10), // Year
parseInt(Today_str.substring(0, 2), 10) - 1, // Month (0-11)
parseInt(Today_str.substring(3, 5), 10)); // Day
var Due_str = $("#field_tm25b5").val(); // E.g., "mm/dd/yyyy";
var Due_dt = new Date(parseInt(Due_str.substring(6), 10), // Year
parseInt(Due_str.substring(0, 2), 10) - 1, // Month (0-11)
parseInt(Due_str.substring(3, 5), 10)); // Day
//var diff = Math.floor(Due_dt-Today_dt);
var diffDays = Math.round(Math.abs((Today_dt.getTime() - Due_dt.getTime())/(oneDay)));
$("#field_smmyr").val(diffDays);
});
});
</script>
"1pjvu" is the key of the today's date field
"21nfg" is the year value field of the billing period given by the user.
"o1ns5" is the month value field of the billing period field given by the user.
"tm25b" is the concatenated due date: the 20th of the month given in the above field.
"smmyr" is the key of the difference field.
UPDATE April 19 2016
Thank you all for your help. If you can't tell, I don't know JS but am hacking my way along as I go. After much fumbling, I got it to work. Here's my final code:
<script type="text/javascript">
jQuery(document).ready(function($){
$('#field_21nfg, #field_o1ns5').change(function(){
var Year = $("#field_21nfg").val(); //Collect value from Filing Period Year form field
var Month = $("#field_o1ns5").val();//Collect value from Filing Period Month form field
var Day = 20; //Due date for filing tax return
var DueDate = Month+'/'+Day+'/'+Year;
$("#field_tm25b").val(DueDate); //Populate "Due Date" form field with due date generated above
function parseMDY(s) {
var b = s.split(/\D/);
return new Date(b[2], b[0]-1, b[1]);
}
var Today = $("#field_1pjvu").val(); //Collect Value from Today's Date form field
if (DueDate > Today) {
$("#field_smmyr").val(1); //Returns true/1 for on or before due date
} else {
$("#field_smmyr").val(0); //Returns false/0 for after due date
}
});
});
</script>
You are making life more difficult than it needs to be. To parse a date string in m/d/y format, use a simple function like the one below.
If you want to compare dates using < or > as whole days, you can just compare them. But even though the relational comparison operators compare the dates as numbers, the == and === operators don't, so clearer to explicitly compare the time values.
function parseMDY(s) {
var b = s.split(/\D/);
return new Date(b[2], b[0]-1, b[1]);
}
var a = '2/29/2016';
var b = '12/31/2015';
document.write(parseMDY(a) + '<br>' + parseMDY(b) + '<br>');
document.write('Is ' + a + ' before ' + b + '? ' +
(parseMDY(a).getTime() < parseMDY(b).getTime())
);
And if you want to compare to "today", don't forget to set the hours to zero:
var today = new Date();
today.setHours(0,0,0,0);
You could try using timestamps in ms instead of actual formatted dates. Using JS you can do it like this:
var myDate="18/04/2016";
myDate=myDate.split("/");
var newDate=myDate[1]+"/"+myDate[0]+"/"+myDate[2];
var ts = new Date(newDate).getTime(); //timestamp in milliseconds
Converting your 2 dates to timestamps will allow you to substract one from another and then convert it back to formatted date:
var date = new Date(ts*1000);
var d = date.getDate();
var m = date.getMonth() + 1;
var y = date.getFullYear();
var formatted = d + '/' + m + '/' + y;

Date object returns NaN when trying to calculate time between two dates in IE8

I have a string which represents the expiry of an item like so: 2020-10-31T21:30:11, and I have a function to calculate the amount of days left until this date (below).
However, in IE8 it doesn't work. I think this is because timeEnd is returning NaN. Can someone explain why this doesn't work and point me in the right direction?
I have a jsFiddle here.
And here's a snippet of my code:
HTML
<span class="days-left" data-publishend="2020-10-31T21:30:11"></span>
JS
$('.days-left').each(function () {
if ($(this).data("publishend")) {
var timeEnd = new Date($(this).data("publishend")), // returns NaN in IE8
timeNow = new Date(),
oneDay = 24*60*60*1000,
oneHour = 60*60*1000,
oneMin = 60*1000,
daysLeft = Math.floor(Math.abs(timeEnd.getTime() - timeNow.getTime()) / oneDay),
hoursLeft = Math.floor(Math.abs(timeEnd.getTime() - timeNow.getTime()) / oneHour),
minsLeft = Math.floor(Math.abs(timeEnd.getTime() - timeNow.getTime()) / oneMin),
string;
if (daysLeft < 1) {
if (hoursLeft < 1.5) {
string = minsLeft + ' minutes';
} else {
string = hoursLeft + ' hours left';
}
}
if (daysLeft === 1) string = '1 day left';
if (daysLeft > 1) string = daysLeft + ' days left';
$(this).text(string);
}
});
You are right, IE8 won't parse your date right at the beginning (timeEnd init).
Here is the reason : https://stackoverflow.com/a/17593482/2143734
Just one more date handling issue ;)
try this
function parseISO8601(dateStringInRange) {
var isoExp = /^\s*(\d{4})-(\d\d)-(\d\d)\s*$/,
date = new Date(NaN), month,
parts = isoExp.exec(dateStringInRange);
if(parts) {
month = +parts[2];
date.setFullYear(parts[1], month - 1, parts[3]);
if(month != date.getMonth() + 1) {
date.setTime(NaN);
}
}
return date;
}
to make the conversion.
Source: Date constructor returns NaN in IE, but works in Firefox and Chrome
From looking at answers in this Stackoverflow question, I've got a grasp of what was going on and created my own function that worked the string that I wanted to convert a date object.
IE8 cannot parse the string 2020-10-31T21:30:11 like other browsers can. But the date object can accept comma separated values representing the year, month, day, etc, and use them to create the new instance (more info about the Date object).
So I created a function that takes my string, spits it at the "T" and then splits the remaining values at either the "-" or the ":". The function then returns the a date object instance using these values as the parameters.
function parseDateString(dateString) {
var a = dateString.split('T'),
year = a[0].split('-')[0],
month = a[0].split('-')[1],
day = a[0].split('-')[2],
hour = a[1].split(':')[0],
min = a[1].split(':')[1];
return new Date(year, month - 1, day, hour, min);
}

Javascript Validate Date&Time

Ive got a piece of JS that needs to validate and compare a start date and time against an end date and time.
So in other words end date & time cannot be less than start date and time.
Now the problem.
I originally only accepted the time in 24 hour(military) Format. but now let the user choose between 12 hour or 24 hour.
Example 13:00 or 1:00 PM
This piece of code work for 24 hour time format, but not for 12, its 12:00 PM that causes the problem.
So I need to adapt this piece of code to work for either 12 hour or 24 hour, but im not sure how to do this.
function validateStartEndTime() {
var date = document.getElementById("datepickerStart").value;
var dateEnd = document.getElementById("datepickerEnd").value;
if (!isValidDate(date)) {
alert("Not Valid Date");
return false;
}
var start = document.getElementById("timepicker").value;
var end = document.getElementById("timepickerEnd").value;
var stDate = new Date(parse(date +" "+ start));
var enDate = new Date(parse(dateEnd + " "+ end));
var compDate = enDate - stDate;
if (compDate >= 0)
return true;
else {
alert("End time must be greater than Start Time ");
return false;
}
}
You could write a function that converts time in 12 hour format to time in 24 hour format, something like:
function convertTo24HourFormatIfNeeded(timeString) {
var is12HourFormat = timeString.indexOf("M") !== -1;
if (is12HourFormat) {
var isPm = timeString.indexOf("PM") !== -1;
var timeStringNoSuffix = timeString.split(" ")[0];
if (isPm) {
var hoursAndMinutes = timeStringNoSuffix.split(":");
var hours = hoursAndMinutes[0];
var convertedHours = (Number(hours) + 12);
var minutes = hoursAndMinutes[1];
return convertedHours + ":" + minutes;
} else {
return timeStringNoSuffix;
}
} else {
return timeString;
}
}
Then use it in your code:
var start = convertTo24HourFormatIfNeeded(document.getElementById("timepicker").value);
var end = convertTo24HourFormatIfNeeded(document.getElementById("timepickerEnd").value);
If you're not adverse to using external libraries, i found MomentJs to be very handy working with dates, and among other things it allows to parse the date in a user-defined format, so you could build your date string accordingly to user selection of AM/PM or 24-hour format and feed it to moment js.

javascript date subtraction

I am looking for a way to do proper subtraction between two javascript Date objects and get the day delta.
This is my approach but it fails for todays date as an input:
<script type="text/javascript">
function getDayDelta(incomingYear,incomingMonth,incomingDay){
var incomingDate = new Date(incomingYear,incomingMonth,incomingDay);
var today = new Date();
var delta = incomingDate - today;
var resultDate = new Date(delta);
return resultDate.getDate();
}
//works for the future dates:
alert(getDayDelta(2009,9,10));
alert(getDayDelta(2009,8,19));
//fails for the today as input, as expected 0 delta,instead gives 31:
alert(getDayDelta(2009,8,18));
</script>
What would be a better approach for this ?
The month number in the Date constructor function is zero based, you should substract one, and I think that is simplier to calculate the delta using the timestamp:
function getDayDelta(incomingYear,incomingMonth,incomingDay){
var incomingDate = new Date(incomingYear,incomingMonth-1,incomingDay),
today = new Date(), delta;
// EDIT: Set time portion of date to 0:00:00.000
// to match time portion of 'incomingDate'
today.setHours(0);
today.setMinutes(0);
today.setSeconds(0);
today.setMilliseconds(0);
// Remove the time offset of the current date
today.setHours(0);
today.setMinutes(0);
delta = incomingDate - today;
return Math.round(delta / 1000 / 60 / 60/ 24);
}
getDayDelta(2008,8,18); // -365
getDayDelta(2009,8,18); // 0
getDayDelta(2009,9,18); // 31
(2009,8,18) is NOT August 18th. It's September 18th.
You could call getTime() on each date object, then subtract the later from the earlier. This would give you the number of milliseconds difference between the two objects. From there, it's easy to get to days.
A couple of hiccups to watch for, though: 1) daylight savings time, and 2) ensuring your times are coming from the same time zone.
This will work better, but it doesn't properly deal with negative result values. You might want to simply parse the values yourself and deal with them.
function getDayDelta(incomingYear,incomingMonth,incomingDay){
var incomingDate = new Date(incomingYear,incomingMonth-1,incomingDay);
var today = new Date();
today = new Date(Date.parse(today.format("yyyy/MM/dd")));
var delta = incomingDate - today;
if (delta == 0) { return 0; }
var resultDate = new Date(delta);
return resultDate.getDate();
}
//works for the future dates:
alert(getDayDelta(2009,9,10));
alert(getDayDelta(2009,8,19));
alert(getDayDelta(2009, 8, 18));

Categories