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.
Related
I am trying to pass string variable to JS date object and create date in future.
Its easy to do in this way:
var d = new Date();
var year = d.getFullYear();
var month = d.getMonth();
var day = d.getDate();
var my_date = new Date(year + 1, month +1, day +1);
But how I can pass it with string variable, so that I can achieve something like this:
var d = new Date();
var year = d.getFullYear();
var month = d.getMonth();
var day = d.getDate();
var my_variable = 'year + 1, month +1, day +1';
var my_date = new Date(my_variable);
In this case it returns Invalid date
Note
You need to be a little careful with date arithmetic since it's not symmetric and may give odd results, e.g. 29 Feb 2016 + 1 year gives 1 March 2017, and 31 July minus 1 month is 1 July since there is no 31 June, it rolls over to July, and so on.
Given your original requirement, you might consider a parser for your particular format, e.g.
function myParse(s, date) {
date = date || new Date();
// Default values object
var values = {
year:{sign:1, value:0}, month:{sign:1, value:0}, day:{sign:1, value:0}
};
// Tokenise string
var part = s.toLowerCase().match(/[a-z]+|\d+|[+-]/ig);
// Process the tokens
if (part) {
for (var i=0, iLen=part.length; i<iLen; i++) {
if (part[i] in values) {
values[part[i]].sign = part[i+1] == '+'? 1 : -1;
values[part[i]].value = +part[i+2];
i += 2;
}
}
}
// Apply to date
date.setFullYear(
date.getFullYear() + values.year.sign * values.year.value,
date.getMonth() + values.month.sign * values.month.value,
date.getDate() + values.day.sign * values.day.value
);
return date;
}
// Examples
var options = {day:'2-digit',month:'short',year:'numeric'};
console.log('Today is ' + (new Date().toLocaleString('en-gb', options)));
['year+1,month+1,day+1', // one of each
'year+2,day+2', // missing parameters
'day + 15, month +2', // any order, random whitespace
'month - 3' // subtraction
].forEach(function(s) {
console.log(s + '\n' + myParse(s).toLocaleString('en-gb', options));
});
It's fairly tolerant but you should validate the input. It could be extended to handle time too, and also the end of month issues noted above.
Unfortunately javascript (and all the languages that I know off hand) do not work like that.
You could use an eval statement instead, which allows you to create the entire instruction as a string and run that string...
var my_variable = 'year + 1, month +1, day +1';
eval('var my_date = new Date(' + my_variable + ');');
HOWEVER using of eval is dangerous, and could open you up to unexpected attacks. Only use it if absolutely necessary, and if you're sure that the string being used is "safe"
You are inserting Javascript code as a string, which makes no sense to the Date class.
You can have your variables stored in an array to pass them elegantly to Date.
const dates = [year + 1, month +1, day +1]
const my_date = new Date(...dates);
I've read a follow up comment which indicates you'll only be getting strings from wherever you are retrieving the data from. Firstly if the string is in the format of 'year + 1, month + 1, day + 1', it'll never make sense to the Date object. If the string is just 3 numbers separated by a comma, you could split the string at the commas and pass them to the Date object in the same fashion.
const dates = myString.split(',');
const my_date = new Date(...dates);
I want to show all dates between two days.I can't do this.Please help..
This is my code...
var Day = 24*60*60*1000; // hours*minutes*seconds*milliseconds
var firstDate = new Date("2017-04-10");
var secondDate = new Date("2017-04-15");
var diffDays = (secondDate.getTime() - firstDate.getTime())/Day;
alert(diffDays);
for(var i=0;i<= diffDays ;i++)
{
var d = new Date(firstDate + i);
alert(d);
}
Your i variable is the number of the day to display. Your firstDate variable is a Date.
This line:
var d = new Date(firstDate + i);
adds these together and tries to create a new Date. Due to these being different types (a date and a number) type coercion comes into play (ie: the Date and the Number get converted to strings, and concatenated together).
Try this:
var DAY_IN_MS = 24 * 60 * 60 * 1000; // hours*minutes*seconds*milliseconds
var theDate = new Date("2017-04-10");
var i = 5;
// Date + Number = Type Coercion! Both objects will be converted to strings and concatenated together.
alert(theDate + i);
// The Date constructor doesn't care, and will work because it can get a date from the first part of the string.
alert(new Date(theDate + i));
// If you use `getTime()` you can get the numerical value of the Date, which you can use for arithmetic.
alert(theDate.getTime());
// By adding `i`, however, you are only adding a few milliseconds to the first date !!
alert(new Date(theDate.getTime() + i);
// Number + Number of days times milliseconds per day = success!
alert(new Date(theDate.getTime() + (i * DAY_IN_MS)));
I think you mean:
var d = new Date(firstDate.getTime() + (i * Day));
Short answer, increment the right amount of milliseconds to firstDate.getTime() :
for(var i=0;i<= diffDays ;i++)
{
firstDate = new Date(firstDate.getTime() + Day);
console.log(firstDate);
}
Long answer, you have several things wrong in your code :
Here var d = new Date(firstDate + i); you are adding to a Date object string representation the value of i in this case incremented on the loop.
You are then parsing this String into a new Date object, but Javascript only recognizes the date and ignores the appended number
You should either try to get the milliseconds of firstDate as you did for diffDays and then add i * Day (also consider renaming this variable to something else, maybe a const DAY_IN_MS or something).
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'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;
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.