I know this question has been asked a thousand times, but im trying to get javascript to display me the days between two dates. I have seen this post:How do i get the number of days between two dates in javascript
From one of the comments I have used this code:
<input type="text" name="sod" class="startd" value="10/02/2016" />
<input type="text" name="dos" class="endd" value="12/02/2016" />
<script>
function treatAsUTC(date) {
var result = new Date(date);
result.setMinutes(result.getMinutes() - result.getTimezoneOffset());
return result;
}
function daysBetween(startDate, endDate) {
var millisecondsPerDay = 24 * 60 * 60 * 1000;
return (treatAsUTC(endDate) - treatAsUTC(startDate)) / millisecondsPerDay;
}
alert(daysBetween($('.startd').val(), $('.endd').val()));
</script>
The reulst from the javascript give 61 days, but I want it to read as dd/mm/yyyy not mm/dd/yyyy as it currently is, so the result should be 2 days.
I have tried removing the treatAsUTC parts but it then desont give any answer at all.
function daysBetween(startDate, endDate) {
var millisecondsPerDay = 24 * 60 * 60 * 1000;
return (endDate - startDate) / millisecondsPerDay;
}
alert(daysBetween($('.startd').val(), $('.endd').val()));
can any one help or guide me in the right direction?
Thanks in advance.
Ian
The reulst from the javascript give 61 days, but I want it to read as dd/mm/yyyy not mm/dd/yyyy as it currently is, so the result should be 2 days.
So you just need to parse the date correctly. The original was:
function parseDate(str) {
var mdy = str.split('/')
return new Date(mdy[2], mdy[0]-1, mdy[1]);
}
Which parses a date in m/d/y format, so to support d/m/y, just change the last line to:
return new Date(mdy[2], mdy[1]-1, mdy[0]);
Tidying up the code a bit, you might end up with something like:
// Parse a date in d/m/y format as UTC
function treatAsUTC(s) {
var b = s.split(/\D/);
return new Date(Date.UTC(b[2], b[1]-1, b[0]));
}
function daysBetween(startDate, endDate) {
startDate = treatAsUTC(startDate);
endDate = treatAsUTC(endDate);
return (endDate - startDate) / 8.64e7;
}
function calcDiff() {
document.querySelector('#result').value =
(daysBetween(document.querySelector('#sod').value,
document.querySelector('#dos').value));
}
<input type="text" id="sod" class="startd" value="10/02/2016" />d/m/y
<input type="text" id="dos" class="endd" value="12/02/2016" />d/m/y
<br>
<button onclick="calcDiff()">Calculate difference in days</button>
<input type="text" id="result" readonly>Days
But you don't actually need UTC, you can just round the result. If parsing dates, the milliseconds will only ever be out by the daylight saving change, rounding to the nearest whole day fixes that. But I guess it's nice using UTC as it doesn't need rounding.
Related
I have a form submit with 2 date inputs: share_start and share_end in yyyy-mm-dd format. I use JS to validate the input and want to check whether share_end date is within 7 days from the share_start date.
Now, the tricky bit is that I don't have a JS date() dates/timestamps, but only those input dates, but when trying to add on 7 days to the input in JS all I end up with an error since JS needs to operate with date(). I cannot use any external scripts like moment.js to help with this.
Does JS have some sort of in-built function like PHPs strtotime where I can just add + 7 days or something?
Thank you
// Form Submit Validation
function validateForm() {
var share_start = '2021-05-07';
var share_end = '2021-05-15';
var share_max = share_start.setDate(date.getDate() + 6);
if (share_end > share_max) {
alert("Share End Date cannot be more than 7 days from now");
return false;
}
}
At last figured it out.... Bloody JS date conversion is really a pain without libraries such moments.js
var date1 = '2021-01-01';
var date2 = '2021-01-08';
var diffTime = Math.abs(date2 - date1);
var diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
if (diffDays > 6) {
alert("Share cannot be longer than 6 days");
return false;
}
In my particular case, I am getting the date values from a variable, which I then calculate the difference in seconds, after which I convert those seconds to days. Followed by a simple if statement where I check if the value is greater than x days, and I am good to go.
This question already has answers here:
exclude weekends in javascript date calculation
(6 answers)
Calculate working days between two dates in Javascript excepts holidays
(10 answers)
Closed 1 year ago.
I know this question is asked a lot of times. And i did my research, but i really don't understand it. I just started using javascript.
This is my code to calculate days between the two inputs.. I erased my attempts to calculate weekend.
function GetDays(){
var datefrom = new Date(document.getElementById("datefrom").value);
var dateto = new Date(document.getElementById("dateto").value);
return parseInt((dateto - datefrom) / (1000 * 60 * 60 * 24));
}
function cal(){
if(document.getElementById("dateto")){
document.getElementById("numdays2").innerHTML=GetDays();
}
}
An answer in PHP is also good for me.
Hope someone can help me.
You should really make your function with parameters, so that the function can be unaware of input/output details and does not have to reference document.
Also, it is a habit to start function names with a lowercase letter unless it is a constructor (which is not the case here).
As to the algorithm: move the two given dates to the Sunday that precedes them (unless they already are Sundays). As getDay() returns 0 for Sunday, you can just subtract the getDay() number of days from the date, and it will be a Sunday. Remember how many working days you subtracted like that.
Then when both dates are Sundays, calculate the number of weeks between them and multiply this by 5 (working days).
Finally adjust this number by adding and subtracting the days you altered the dates with in order to make them align with Sunday.
Here is an interactive snippet:
function getDays(datefrom, dateto) {
datefrom = new Date(datefrom);
dateto = new Date(dateto);
let before = datefrom.getDay();
datefrom.setDate(datefrom.getDate() - before); // Go to previous Sunday
if (before) before--; // should be in {0,1,2,3,4,5}
let after = dateto.getDay();
dateto.setDate(dateto.getDate() - after); // Go to previous Sunday
if (after == 6) after--; // should be in {0,1,2,3,4,5}
// Count each 7 day difference as 5 days, and compensate for the changes to Sundays:
return Math.round((dateto - datefrom) / (1000 * 60 * 60 * 24)) / 7 * 5 + after - before
}
document.addEventListener("input", function () {
var datefrom = new Date(document.getElementById("datefrom").value);
var dateto = new Date(document.getElementById("dateto").value);
document.getElementById("numdays2").textContent = getDays(datefrom, dateto);
});
From: <input type="date" id="datefrom" value="2021-01-01"><br>
To: <input type="date" id="dateto" value="2021-01-01"><br>
Number of working days: <span id="numdays2">1</span>
I have a problem enabling only during 2 weeks data format. For example, I want only to show today and before 14 days. Now my coding just can lock before days.
Scenario:
If today 03 Feb 2021, I want to enable dates are 20 Jan 2021 until 03 Feb 2021. Other dates will be disabled.
var today = new Date().toISOString().split('T')[0];
document.getElementsByName("accident")[0].setAttribute('min', today);
<input type="date" class="form-control" id="accident" name="accident" value="" title="Date of Accident">
Now my result like below the picture:
Hope someone can guide me on which part I am getting wrong it. Thanks.
According to MDN Documentation. You need to set min and max values to specify an interval
// Get date objects
const today = new Date();
const twoWeeksAgo = new Date();
twoWeeksAgo.setDate(today.getDate() - 14);
// Then set in input
const input = document.querySelector('[name=accident]');
input.setAttribute('min', twoWeeksAgo.toISOString().slice(0, 10));
input.setAttribute('max', today.toISOString().slice(0, 10));
<input type="date" name="accident" />
You only set min, but you did not set max.
Because of this relationship, it only knows your minimum date, but does not know your maximum date, so the previous result is normal, as long as you make up the setting, it will work.
For details, please refer to here.
const getDateStr = (d) => d.toISOString().split('T')[0];
const daysRange = (days) => {
const d = new Date();
const when = new Date(d.setDate(d.getDate() + days));
return [new Date(), when].map(m=>getDateStr(m));
};
const limit = daysRange(-14);
const picker = document.getElementsByName("accident")[0];
picker.setAttribute('min', limit[1]);
picker.setAttribute('max', limit[0]);
picker.setAttribute('value', limit[0]);
label {
display: block;
font: 1rem 'Fira Sans', sans-serif;
}
input,
label {
margin: .4rem 0;
}
<label for="start">date:</label>
<input type="date" name="accident">
The solution you're looking for is something like this,
const twoWeeksAgo = 14 * 24 * 60 * 60 * 1000;
let dateElement = document.querySelector('#accident');
dateElement.min = new Date(Date.now() - twoWeeksAgo).toISOString().split('T')[0];
dateElement.max = new Date().toISOString().split('T')[0];
<input type="date" class="form-control" id="accident" name="accident" value="" title="Date of Accident">
You can use the max and min attributes of the HTML5 date element (documented here) to restrict your element to only show certain values.
In this particular case, the min attribute is set to the date (in yyyy-mm-dd format) two weeks ago and the max attribute is set to the current date.
The magic computation twoWeeksAgo is the number of milliseconds in 14 days which will allow you to compute the date 14 days ago.
The code new Date(Date.now() - twoWeeksAgo) gives us a Date object set to two weeks ago and the .toISOString() function returns the date in YYYY-MM-DDTHH:mm:ss.sssZ format, i.e., a date-time string.
Since the min attribute only requires the date and not the time, we then split the obtained string using 'T' as a delimiter, which would give us the date in YYYY-MM-DD format.
Putting it all together we get this line for the date two weeks ago
dateElement.min = new Date(Date.now() - twoWeeksAgo).toISOString().split('T')[0];
And similarly for the upper limit date,
dateElement.max = new Date().toISOString().split('T')[0];
I want to do same thing as
How do I get the number of days between two dates in JavaScript?
but I want do the same on this date format: 2000-12-31.
function daysBetween(date1String, date2String){
var d1 = new Date(date1String);
var d2 = new Date(date2String);
return (d2-d1)/(1000*3600*24);
}
console.log( daysBetween('2000-12-31', '2005-05-04') ); //-> 1585
ISO8601 date strings are recognized by JavaScript directly. No need to parse them yourself.
Try this.
var toDate = "2000-12-31";
var fromDate = "2000-10-30";
var diff = Math.floor(( Date.parse(toDate) - Date.parse(fromDate) ) / 86400000);
You wont be asking this question if you have checked the answer with more up-votes and not the marked answer on the link you have provided. :)
Well, it's not jQuery, but just as easy to work with. Check out DateJS. Can parse dates, differences, and more.
The other solutions here do not take into account the TimeZone information (which is fine if that is what you want)
but I came across a problem like this: I have two dates:
Thu Mar 01 2012 00:00:00 GMT+0100 and Sat Mar 31 2012 00:00:00 GMT+0200
which will give you 29.95833 days before the Math.floor and hence 29 days after the floor.
This is not the 30 days I was expecting. Clearly Daylight Saving has kicked in and shortened
one of the days by an hour.
Here is my solution which takes TimeZones into account:
function daysBetween(date1String, date2String) {
var ONE_DAY = 1000 * 60 * 60 * 24;
var ONE_MINUTE = 1000 * 60;
var d1 = new Date(date1String);
var d2 = new Date(date2String);
var d1_ms = d1.getTime() - d1.getTimezoneOffset() * ONE_MINUTE;
var d2_ms = d2.getTime() - d2.getTimezoneOffset() * ONE_MINUTE;
return Math.floor(d1_ms - d2_ms/ONE_DAY);
}
I am trying to use datejs (date ninja or whathaveyou..) and I am getting odd results.
Here's what I output to console to test.
var d1 = Date.today();
var d2 = Date.parse(work.tax_credit_start);
var span2 = new TimeSpan(d2 - d1);
console.log('result of timespan test = ' + span2.getDays() + 'days between now and ' + Date.parse(work.tax_credit_start).toString('dd-mm-yyyy') + ' - ' + work.tax_credit_start );
I am expecting about -584 days according to date calculations in excel and other online services.
Here's what I got:
result of timespan test = -462days between now and 30-00-2010 - 30-06-2010
I have got a localisation file for datejs for New Zealand style dates too, so I am not expecting that to be an issue. Though it appears to be the issue. Also if I parse a date and then render it as a string in the same format that it was in before being parsed it should not change yeah?
Long day, maybe I just need a break.
Your thoughts/help internets?
Firstly, 30-00-2010 will be resolved as Wed Dec 30 2009 00:00:00. Is that what you really want?
Secondly, the difference in days between 30-00-2010 and 30-06-2010 is only a couple of days more than 6 months, how do you get -584 days? I get -182.
Anyway, it's not a difficult calculation. Create two date objects for the required dates, set their time to noon (so as to remove daylight saving issues across dates), subtract one from the other, divide the result by the number of milliseconds in a day (24 * 60 * 60 * 1000) and round to the nearest integer.
Here's a some quick functions to do the job:
// Iput as d/m/y or d-m-y
function dmyToDate(s) {
var bits = s.split(/[-/]/);
return new Date(bits[2], --bits[1], bits[0]);
}
// Difference between dates in days. If only one date supplied,
// today is used for endDate
// Copy startDate so don't mess it up
function daysBetweenDates(startDate, endDate) {
endDate = typeof endDate == 'string'? dmyToDate(endDate) : new Date();
startDate = typeof startDate == 'string'? dmyToDate(startDate) : new Date(startDate);
endDate.setHours(12,0,0);
startDate.setHours(12,0,0);
var diff = startDate - endDate;
var ms = 24 * 60 * 60 * 1000; // or 8.64e7
return Math.round(diff/ms);
}
The issue is definitely caused by your work.tax_credit_start string(?) value. The Datejs parser will return a null value if parsing fails.
In your sample, d1 will be subtracted from a null Date. This will return an unexpected number value. You're then passing that 'unexpected' number into the TimeSpan constructor, which will return some unexpected .days value.
Here's a working sample of your original.
Example
var d1 = Date.parse("2010-01-30");
var d2 = Date.parse("2010-06-30");
var span2 = new TimeSpan(d2 - d1);
span2.days // 150 days
I have a couple recommendations for your original sample:
If you're passing a string value into Date.parse() AND you have control over the format of that value, it would be best to pass in the ISO format of yyyy-MM-dd.
If you're expecting a Date object returned from Date.parse(), it's best to check that value against null to ensure you actually have a valid Date object.
The following demonstrates checking for a null value of d1, then setting to a default value if null.
Example
var d1 = Date.parse("30-00-2010"); // Not a valid Date
if (!d1) {
d1 = new Date();
}
console.log(d1); // will be 'now'
The above sample could be cleaned up by passing the default value right when setting the variable.
Example
var d1 = Date.parse("30-00-2010") || new Date();
console.log(d1); // will be 'now'
Hope this helps.