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;
Related
So I'm trying to make a period counter (cliche) and I'm also beginner at HTML and Javascript so bear with me. I made it so the user can put in the date that their period started, and I want to add 31 to the amount of days they entered so it comes out as a date.
My script so far:
function theDate() {
var m = document.getElementById("inmonth").value;
Number(m).toString();
var d = document.getElementById("inday").value;
var y = document.getElementById("inyear").value;
var nd = new Date(m + "/" + d + "/" + y);
var thirtyDaysLater = 31;
var fstart = nd.setDate(nd.getDate() + thirtyDaysLater);
document.getElementById("enddate").innerHTML = "Last Period End Date: " +
nd;
document.getElementById("nextdate").innerHTML = "Next Period Start Date: " +
fstart;
definitely a duplicate but setDate both returns a number (the number of seconds since X passed) and modifies the date, so you'd want to do something like this.
// After setting nd and thirty days later
var fstart = new Date(nd); //copy the date
fstart.setDate(fstart.getDate() + thirtyDaysLater);
// Now fstart contains the modified date and nd contains the initial one.
From there just use as you want.
In short
var a = new Date(b) // date Object a copy of b
a.setDate(num) // Returns a number (which identifies the date) and modifies a
b = new Date(a.setDate(num)) // a is modified, b is now a copy of a.
and for funsies
// a contains the current date - 30 days (it properly accounts for months)
var a = new Date(new Date().setDate(new Date().getDate() - 30));
You should not use the built-in parser. Rather then building a string, giving it to an unreliable parser and hoping you get a consistent result, just give the parts directly to the Date constructor.
Also, setDate modifies the date in place, so there's no need for fstart:
function theDate() {
var y = document.getElementById("inyear").value;
var m = document.getElementById("inmonth").value;
var d = document.getElementById("inday").value;
var nd = new Date(y, m-1, d);
document.getElementById("enddate").innerHTML = "Last Period End Date: " + nd.toString();
var thirtyDaysLater = 31;
nd.setDate(nd.getDate() + thirtyDaysLater);
document.getElementById("nextdate").innerHTML = "Next Period Start Date: " + nd.toString();
}
Day: <input id="inday" value="5"><br>
Month: <input id="inmonth" value="10"><br>
Year: <input id="inyear" value="2017"><br>
<button onclick="theDate()">Calculate</button>
<p id="enddate">
<p id="nextdate">
This doesn't do any validation of input, you may want to add that.
I have an object containing time. For example x.time = 10:20:00.
I want to take the current time minus my objects time.
This is my code so far, but i get the error message ="Invalid Date":
for(var i = 0; i<x.length; i++){
nowDate = new Date();
minutesLeft = new Date(nowDate.getFullYear(), nowDate.getMonth(), nowDate.getDate() + x[i].time);
text +- "It is "+ minutesLeft[i] + " milliseconds left";
}
In order to convert your time property into a date object you can do:
var timepieces = x.time.split(':');
var date = new Date();
date.setHours(timepieces[0]);
date.setMinutes(timepieces[1]);
date.setSeconds(timepieces[2]);
Then you can directly compare the two dates by using the getTime() method of the Date object.
nowDate.getTime() === date.getTime()
nowDate.getTime() > date.getTime()
nowDate.getTime() < date.getTime()
You can also get the difference of two dates in milliseconds:
var milliseconds = nowDate.getTime() - date.getTime();
There are a bunch of problems with your code. I'll go through and hopefully catch everything.
Use var to declare your variables inside your loop. (further reading)
When you create the variable minutesLeft you are doing a bit of weird concatenation. You told us that x.time is a string such as "10:20:00" but you are (string) concatenating that with Date.prototype.getDate which returns a number in the range 1-31 (representing the day of the month). You are essentially doing this:
minutesLeft = new Date(2017,0,1910:20:00);
Which I hope you see will not create a new date. You perhaps wanted something along the lines of
minutesLeft = new Date(2017,0,19, 10, 20, 0);
Which should give you what you want (todays date set to the appropriate time defined by x.time.
text +- does not make any sense. I suspect a typo, you meant text += which will append the value on the right to the variable text. Or, perhaps text = which will assign the value, replacing what was there
"It is "+ minutesLeft[i] + " milliseconds left" using minutesLeft[i] will take a single character from a string (or an item from an array, if the value is an array). Yours is just a date object, and is not an array, so I suspect you just meant to leave off the [i] part altogether.
If you're trying to get the difference between the current date/time and your selected date/time you need to do some arithmetic with nowDate and minutesLeft. I'm assuming this is a difference you're after.
var x = [{time:"10:20:20"}];
var text = "";
for(var i = 0; i<x.length; i++){
var nowDate = new Date();
var timeSplit = x[i].time.split(":");
var minutesLeft = new Date(nowDate.getFullYear(), nowDate.getMonth(), nowDate.getDate());
minutesLeft.setHours(timeSplit[0]);
minutesLeft.setMinutes(timeSplit[1]);
minutesLeft.setSeconds(timeSplit[2]);
text += "It is "+ (nowDate-minutesLeft) + " milliseconds left";
}
console.log(text);
For example x.time = 10:20:00. I want to take the current time minus my objects time.
Your code seems quite confused, it seems you're trying to do the following:
var time = '10:20:00';
var timeParts = time.split(':');
var now = new Date();
// Current date and time
console.log(now.toString());
// Subtract the hours part of the time from the hours part of the current time
now.setHours(now.getHours() - timeParts[0]);
// Subtract the minutes part of the time from the minutes part of the current time
now.setMinutes(now.getMinutes() - timeParts[1]);
// Subtract the seconds part of the time from the seconds part of the current time
now.setSeconds(now.getSeconds() - timeParts[2]);
// Adjusted date and time
console.log(now.toString());
// You can set the time parts all in one go:
var now2 = new Date();
now2.setHours(now2.getHours() - timeParts[0],
now2.getMinutes() - timeParts[1],
now2.getSeconds() - timeParts[2]);
console.log(now2.toString());
Lastly, copying a date is as simple as:
var date1 = new Date();
var date2 = new Date(date1);
I used the range function from pikaday.
with onSelectI set the date range what actually works.
Here is my example:
onSelect: function(date) {
var first_ = (date.getDate() - date.getDay())+1;
var last_ = first_ + 4;
var firstday = new Date(date.setDate(first_));
var lastday = new Date(date.setDate(last_));
picker.setStartRange(firstday);
picker.setEndRange(lastday);
picker.draw();
var f_startdate = firstday.getDate()+'.'+(firstday.getMonth()+1)+'.'+firstday.getFullYear();
var f_enddate = lastday.getDate()+'.'+(lastday.getMonth()+1)+'.'+lastday.getFullYear();
var kw = getWeekNumber(date.getFullYear()+'/'+(date.getMonth()+1)+'/'+date.getDate());
document.getElementById('calendar').value = f_startdate+' - '+f_enddate;
// document.getElementById('calendar').value = 'KW: '+(kw+1);
}
But when I select the 03.06.2016 the range is set to the "30.05.2016 - 03.05.2016" and the Input is wrong. Maybe anyone can help me.
Here is a working example: https://jsfiddle.net/24aL9f21/1/
Your issue is here:
var first_ = (date.getDate() - date.getDay())+1;
That gives you the date of the previous Monday, but also goes negative. 3 June is a Friday (day number 5), so first_ is set to:
3 - 5 + 1 = -1
Then:
var last_ = first_ + 4;
so last_ is set to 3. Now when you do:
var firstday = new Date(date.setDate(first_));
you are actually setting date to a date of -1, which is one before the start of the month so 30 May. setDate returns the time value, so firstday is a new Date instance set to 30 May also.
Then:
var lastday = new Date(date.setDate(last_));
you are setting date to 3 May (remembering that in the line above you set it to 30 May). Again, the setDate method returns the time value, so a new Date object is created for that date. So you get dates for 30 May and 3 May (and if you check date, you'll set it's also 3 May).
QED (which my Mathematics teacher told me was "Quite Easily Done"). ;-)
So your code for the Monday is fine. If you want to get the date for the following Friday, just do:
var lastday = date.setDate(date.getDate() + 4);
Here lastday and date will reference the same Date object, but creating another copy doesn't seem useful.
I have read a few articles but nothing seems to the point. I have created a form that records a reservation date (when a user wants to reserve a game) and the number of days they hope to borrow it for. I want to add this to the reservation date to get the date the game must be returned by. I have wrapped up my code so far into a function so that I can call it using an onclick method. What should this code look like to work properly? Almost forgot - to make life hard my date is written like this YYYY-MM-DD
function ReturnDate(){
var reservation_begin = document.getElementById('reservation_start').value;
var loan_period = document.getElementById('requested_days').value;
var reservation_end = document.getElementById('return_date');
var dateResult = reservation_begin + loan_period;
return_date.value = dateResult;
}
USING the Suggestions made by Linus
I made the following alterations but had trouble with the formatting of the return date. e.g Setting the reservation date to 2015-01-03 gave me the result of 2015-0-32 for the return date
function ReturnDate(){
var reservation_begin = document.getElementById('reservation_start').value;
var loan_period = document.getElementById('requested_days').value;
var resDate = new Date(reservation_begin);
alert(resDate)
var period = loan_period;
var output = document.getElementById('return_date');
resDate.setDate(resDate.getDate() + period);
alert(period)
//return_date.value = resDate.getFullYear() + "-" + (resDate.getMonth() + 1) + "-" + resDate.getDate();
return_date.value = resDate.getFullYear() + "-" + resDate.getMonth() + "-" + (resDate.getDate() +1);
}
As mentioned dates could be a bit tricky to handle with js.
But to just add days to a date this could be a solution?
JSBIN: http://jsbin.com/lebonababi/1/edit?js,output
JS:
var resDate = new Date('2015-02-01');
var period = 6;
var output = "";
resDate.setDate(resDate.getDate() + period);
output = resDate.getFullYear() + "-" + (resDate.getMonth() + 1) + "-" + resDate.getDate();
alert(output);
EDIT:
Added a new JSBin which is more consistent with the original code.
JSBin: http://jsbin.com/guguzoxuyi/1/edit?js,output
HTML:
<input id="reservationStart" type="text" value="2015-03-01" />
<br />
<input id="requestedDays" type="text" value="14" />
<br />
<a id="calculateDate" href="javascript:;">Calculate Date</a>
<br /><br /><br />
Output:
<input id="calculatedDate" type="text" />
JS:
// Click event
document.getElementById('calculateDate').addEventListener('click', returnDate);
// Click function
function returnDate(){
var reservationStart = document.getElementById('reservationStart').value,
requestedDays = parseInt(document.getElementById('requestedDays').value),
targetDate = new Date(reservationStart),
formattedDate = "";
// Calculate date
targetDate.setDate(targetDate.getDate() + requestedDays);
// Format date
formattedDate = formatDate(targetDate);
// Output date
document.getElementById('calculatedDate').value = formattedDate;
}
// Format date (XXXX-XX-XX)
function formatDate(fullDate) {
var dateYear = fullDate.getFullYear(),
dateMonth = fullDate.getMonth()+1,
dateDays = fullDate.getDate();
// Pad month and days
dateMonth = pad(dateMonth);
dateDays = pad(dateDays);
return dateYear + "-" + dateMonth + "-" + dateDays;
}
// Pad number
function pad(num) {
return (num < 10 ? '0' : '') + num;
}
As per my comment,
Split reservation_begin and use the Date constructor feeding in the
parts to create a Javascript date object. getTime will give you the
milliseconds since the Epoch. There are 86400000 milliseconds in a day, so
multiply this by loan_period. Add the two millisecond result together
and use the Date constructor with your total milliseconds to get
dateResult as a Javascript date object.
using Date.UTC but you don't have to.
function pad(num) {
return num < 10 ? '0' + num : num;
}
var reservation_begin = ('2015-02-01').split('-'),
loan_period = '5',
begin,
end;
reservation_begin[1] -= 1;
begin = new Date(Date.UTC.apply(null, reservation_begin)).getTime();
end = new Date(begin + 86400000 * loan_period);
document.body.textContent = [
end.getUTCFullYear(),
pad(end.getUTCMonth() + 1),
pad(end.getUTCDate())
].join('-');
Why split the date string into parts? This is to avoid cross browser parsing issues.
Why use milliseconds? This is the smallest value represented by Javascript Date, using this will avoid any rollover issues that may be present in browsers.
Why use UTC? You haven't specified the requirements for your script, and this is about as complex as it gets. You don't have to use it, you can just feed the parts into Date and use the non UTC get methods.
What does pad do? It formats the month values to MM and date values to DD.
Note that month is zero referenced in Javascript so months are represent by the numbers 0-11.
A bit confused with the third variable "reservation_end" but according to your question this solution might work.
var dateResult = new Date(reservation_begin);
dateResult.setDate(dateResult.getDate() + parseInt(loan_period));
alert(dateResult);
http://jsfiddle.net/uwfpbzt2/
Example using todays date:
var today = new Date();
today.setDate(today.getDate() + x);
where x is the number of days. Then just use getYear(), getMonth() and getDate() and format it how you like.
EDIT
var myDate = new Date(year, month, day, hours, minutes, seconds, milliseconds);
Assuming your date is entered in dd/mm/yyyy format as inputDate then
dateParts = inputDate.split("/");
var myDate = new Date(dateParts[2], dateParts[1]-1, dateParts[0]);
Depending on the date format your split() delimiter and array positions may be different but this is the general idea.
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.