I'm trying to count the numbers of years and the days(that remains after the years is counted). So it shows how long its gone in years+days since 1970-01-01. Right now I'm only able to get the years right, and I'm not sure if the days are correct. They are both separated, I need them to in some way make var diffDays and diffYear. A calculation so the computer gets that after counting years, to do minus numbers of years in days and show how many days thats left, since today.
<head>
<script>
var today = new Date();
var dd = today.getDate();
document.write(today);
function myFunction() {
var oneDay = 24*60*60*1000; // hours*minutes*seconds*milliseconds
var firstDate = new Date(1970,01,01);
var secondDate = new Date();
var diffYear = Math.round(Math.abs((firstDate.getTime() - secondDate.getTime())/(oneDay)/365));
var diffDays = Math.round(Math.abs((firstDate.getTime() - secondDate.getTime())/(oneDay)));
document.getElementById("antalYear").innerHTML = diffYear;
document.getElementById("antalDagar").innerHTML = diffDays;
}
</script>
</head>
<body onload="myFunction()">
<p>
Numbers of years and days:
<h3>
<span id="antalYear"></span>
years and
<span id="antalDagar"></span>
days
</h3> Since: 1970,01,01.
</p>
</body>
If you're okay with using a library I would recommend moment.js
It's the go to for handling almost anything related to dates.
var oldDate = moment("1970-01-01", "YYYY-MM-DD")
var today = moment()
console.log(today.diff(oldDate, "years"));
console.log(today.diff(oldDate, "days"));
$(".years").append(today.diff(oldDate, "years"))
$(".days").append(today.diff(oldDate, "days"))
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.23.0/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Years:<div class="years"></div>
</br>
Days:<div class="days"></div>
For the number of years since 1970, just subtract it from the current year:
date.getFullYear() - 1970
For the number of days since the beginning of the year, you can subtract a date for 1 Jan in the current year from the current date to get milliseconds, then divide by ms per day. However, that doesn't allow for daylight saving changeovers which might affect the result. If you want to round up, so that any time on 1 January is 1 day, etc. then you can set the time to 12 noon, divide by ms/day and round up (or round down and add one). That gives you the day number of the year.
E.g.
function dayOfYear(date) {
// Copy date so don't affect original
var d = new Date(date);
// Get time value for start of 1 Jan in date year
var yearStart = new Date(d.getFullYear(), 0);
// Get number of days, rounded up
return Math.ceil((d.setHours(12,0,0,0) - yearStart) / 8.64e7);
}
// Day of year for current date
console.log('Current day number: ' + dayOfYear(new Date()));
// Day of year for 31 Dec 2016
console.log('Day number for 31 Dec 2016: ' + dayOfYear(new Date(2016, 11, 31))); // 366
If you want the number of completed days (so 1 Jan is 0, 2 Jan is 1, etc.) just subtract 1 from the result (or use Math.floor instead of Math.ceil).
Related
I am using Bootstrap Datepicker, and based on the date selection I need to display a message to the user.
I have never used the Date Constructor before so it's very new to me.
What I need to do is the following;
allow user to select a date
display a message / alert based of the logic below
If their selected date is within the last 6 months of today, they quality for discount.
If their selected date doesn't fall within the last 6 months of today, they don't.
Although it's not working correctly have created a fiddle here.
Any help would be appreciated. Code also below;
HTML
<input type="text" class="form-control" id="datepicker" placeholder="Year Graduated" value="" data-date-format="dd/mm/yyyy">
<p id="rate"></p>
JS
function compareDate() {
// get date from datepicker
var dateEntered = $("#datepicker").datepicker("getDate");
dateEntered = new Date(dateEntered).getTime();
//alert("date entered: " + dateEntered);
// set todays date
var now = new Date();
// set date six months before today
var sixMonthBeforeNow = new Date(now).setTime(now.getTime() - 3 * 28 * 24 * 60 * 60);
//alert("six months before: " + sixMonthBeforeNow);
// if date entered is within six months from today
if (dateEntered > sixMonthBeforeNow) {
alert("You qualify for the discount rate.");
$("#rate").html('discount rate');
}
// if date entered is over six months from today
if (dateEntered < sixMonthBeforeNow) {
alert("you graduated more than six months ago");
$("#rate").html('no discount');
}
}
$("#datepicker").datepicker({
weekStart: 1,
daysOfWeekHighlighted: "6,0",
autoclose: true,
todayHighlight: true
});
$("#datepicker").change(function() {
compareDate();
});
Note: I'd prefer not to use any other 3rd party JS library / plugin.
Just change your sixMonthBeforeNow with the below code, that should work.
var sixMonthBeforeNow = new Date(now).setMonth(now.getMonth() - 6);
You need to be careful with date arithmetic because it's not symmetric due to the uneven length of months, so you need rules to deal with it. E.g. what date is exactly 6 months before 31 August?
Before answering, consider:
28 February plus 6 months is 28 August
1 March plus 6 months is 1 September.
So what date is 6 months before 29, 30 and 31 August? Is it 28 February or 1 March?
Similar issues arise for any last day of a month where the month 6 months previous doesn't have 31 days. Should the limit be the 30th of the month or the 1st of the following month? When you've answered that question, then you can devise an algorithm to deliver the right answer and then the code to implement it.
If you want such cases to set the date to the end of the month 6 months before, then you can check the month resulting from subtracting 6 months and if it's not 6, set it to the last day of the previous month, e.g.
function sixMonthsPrior(date) {
// Copy date so don't affect original
var d = new Date(date);
// Get the current month number
var m = d.getMonth();
// Subtract 6 months
d.setMonth(d.getMonth() - 6);
// If the new month number isn't m - 6, set to last day of previous month
// Allow for cases where m < 6
var diff = (m + 12 - d.getMonth()) % 12;
if (diff < 6) d.setDate(0)
return d;
}
// Helper to format the date
function formatDate(d) {
return d.toLocaleString(undefined, {day:'2-digit', month:'short', year:'numeric'});
}
// Tests
[ new Date(2018, 7,31), // 31 Aug 2018
new Date(2018, 8, 1), // 1 Sep 2018
new Date(2018,11,31), // 31 Dec 2018
new Date(2019, 2,31) // 31 Mar 2019
].forEach( d => console.log(formatDate(d) + ' => ' + formatDate(sixMonthsPrior(d))));
If that is't the logic you wish to apply, you need to say what is.
PS. You can also implement the above logic by just comparing the start and end dates (day number). If they're different, it must have rolled over a month so set to 0.
How to get difference between 2 Dates in Years, Months and days using moment.js?
For example the difference between 4/5/2014 & 2/22/2013 should be calculated as 1 Year, 1 Month and 14 Days.
Moment.js can't handle this scenario directly. It does allow you to take the difference between two moments, but the result is an elapsed duration of time in milliseconds. Moment does have a Duration object, but it defines a month as a fixed unit of 30 days - which we know is not always the case.
Fortunately, there is a plugin already created for moment called "Precise Range", which does the right thing. Looking at the source, it does something similar to torazaburo's answer - but it properly accounts for the number of days in the month to adjust.
After including both moment.js and this plugin (readable-range.js) in your project, you can simply call it like this:
var m1 = moment('2/22/2013','M/D/YYYY');
var m2 = moment('4/5/2014','M/D/YYYY');
var diff = moment.preciseDiff(m1, m2);
console.log(diff);
The output is "1 year 1 month 14 days"
You hardly need moment.
d1 = new Date(2014, 3, 5); // April 5, 2014
d2 = new Date(2013, 1, 22); // February 22, 2013
diff = new Date(
d1.getFullYear()-d2.getFullYear(),
d1.getMonth()-d2.getMonth(),
d1.getDate()-d2.getDate()
);
This takes advantage of the fact that the Date constructor is smart about negative values. For instance, if the number of months is negative, it will take that into account and walk back the year.
console.log(diff.getYear(), "Year(s),",
diff.getMonth(), "Month(s), and",
diff.getDate(), "Days.");
>> 1 Year(s), 1 Month(s), and 11 Days.
Your calculation is wrong--it's not 14 days, it's six remaining days in February and the first five days of April, so it's 11 days, as the computer correctly computes.
Second try
This might work better given #MattJohnson's comment:
dy = d1.getYear() - d2.getYear();
dm = d1.getMonth() - d2.getMonth();
dd = d1.getDate() - d2.getDate();
if (dd < 0) { dm -= 1; dd += 30; }
if (dm < 0) { dy -= 1; dm += 12; }
console.log(dy, "Year(s),", dm, "Month(s), and", dd, "Days.");
This worked for me. Verified with Age calculator.
function calculateAge(){
ageText = jQuery("#dob").closest(".form-group").find(".age-text");
ageText.text("");
level2.dob = jQuery("#dob").val();
if(!level2.dob) return;
level2.mdob= moment(level2.dob, 'DD-MM-YYYY');
if(!level2.mdob.isValid()){
alert("Invalid date format");
return;
}
level2.targetDate = moment();//TODO: Fill in the target date
level2.months = level2.targetDate.diff(level2.mdob, 'months'); // Calculate the months
let years = parseInt(level2.months/12); // A year has 12 months irrespective or leap year or not
let balanceMonths = level2.months%12; // The balance gives the number of months
let days;
if(!balanceMonths){ // If no balance months, then the date selected lies in the same month
months = 0; // so months = 0
days = level2.targetDate.diff(level2.mdob, 'days'); // only the days difference
}else{
months = balanceMonths;
dob_date = level2.mdob.date();
target_month = level2.targetDate.month();
construct_date = moment().month(target_month).date(dob_date);
days = level2.targetDate.diff(construct_date, 'days')+1; // There might be one day missed out. Not sure on UTC
}
ageText = years +" years " + months+ " months " + days +" days";
}
I need to create Date Objects from strings of Date data for every hour of every day since the year 2000.
The strings look like this for every hour, in a Month/Day/Year Hour format...
"04/02/2000 01", "04/02/2000 02", "04/02/2000 03" ...all the way to... "04/02/2000 24"
Now, I have the following code, which works fine except for on days with Daylight Savings Time...
// Split At Space
var splitDate = "04/02/2000 24".split(/[ ]+/);
var hour = splitDate[1];
var day = splitDate[0];
// Split At Slashes
var dayArray = day.split("/");
if (hour === "24") {
// Months are zero-based, so subtract 1 from the month
date = new Date(Date.UTC( dayArray[2], parseInt(dayArray[0] - 1), dayArray[1], 0, 0, 0 ));
date.setDate(date.getDate() + 1);
} else {
// Months and Hours are zero-based, so subtract 1 from each
date = new Date(Date.UTC( dayArray[2], parseInt(dayArray[0] - 1), dayArray[1], hour, 0, 0 ));
};
On days with daylight savings time, like 04/02/2000 adding a day does not work if the hour is 24. Instead, it just returns Sun, 02 Apr 2000 23:00:00 GMT
With Moment.js, is it possible to detect a DST day and get this code to work correctly?
To detect DST, use the .isDST() method: http://momentjs.com/docs/#/query/is-daylight-saving-time/
moment([2011, 2, 12]).isDST(); // false, March 12 2011 is not DST
moment([2011, 2, 14]).isDST(); // true, March 14 2011 is DST
Using this test, you should be able to determine how to modify your program's behavior accordingly.
Here's how I made a little checker:
var curDst = dtdate.isDST()
var prevDst = moment(dtdate).clone().subtract(1, "day").isDST();
var nextDst = moment(dtdate).clone().add(1, "day").isDST();
var isDstChangeDate = (curDst !== nextDst) === true || (curDst === prevDst) !== true;
I need a JavaScript function that returns the number of days remaining from a particular date of every year.
I found the following code, but how can I make it repeatable for every year, instead of changing the year in the function manually?
function daysUntil(year, month, day) {
var now = new Date(),
dateEnd = new Date(year, month - 1, day), // months are zero-based
days = (dateEnd - now) / 1000/60/60/24; // convert milliseconds to days
return Math.round(days);
}
daysUntil(2013, 10, 26);
I think my question above is not clear enough, i need to show days remaining in 26th October. So this starts again every year on 27th October. I don't need a loop for that.
"how can i make it repeatable for every year, instead of changing the year in function manually?"
Well you can't do literally every year to infinity, but you can easily add a loop to get a specific range of years:
var d;
for (var y = 2013; y < 2099; y++) {
d = daysUntil(y, 10, 26);
// do something with d, e.g.,
console.log(d);
}
UPDATE: You added this detail to your question:
"I think my question above is not clear enough, i need to show days remaining in 26th October. So this starts again every year on 27th October. I don't need a loop for that."
OK, that's still not very clear, but I think you're saying that your input would be just the day and month and you want to calculate the number of days until the next time that day/month rolls around, e.g., the number of days until your next birthday. If so, perhaps something like this:
function daysUntil(month, day) {
var now = new Date(),
currentYear = now.getFullYear(),
dateEnd = new Date(currentYear, month - 1, day); // months are zero-based
if (dateEnd - now < 0) // have we already passed that date this year?
dateEnd.setFullYear(currentYear + 1);
return Math.ceil((dateEnd - now) / 1000/60/60/24);
}
console.log(daysUntil(10,11)); // 365 - results from today, Oct 11
console.log(daysUntil(10,26)); // 15
console.log(daysUntil(7,7)); // 269
I am trying to determine the time elapsed between 2 dates using javascript. An example would be: "I quit smoking on January 5, 2008 at 3 A.M., how many years, months, and hours has elapsed since I quit?".
So my thoughts were:
Get "quit" date
Get current date
Convert to time (milliseconds)
Find the difference
Create a new date using the difference
Extract the years, months, etc. from that date
Well, it is acting strange and I can't pin point why. Any insight?
//create custom test date
var d1 = new Date(2012, 8, 28, 13, 14, 0, 0);
//create current date
var d2 = new Date();
//get date times (ms)
var d1Time = (d1.getTime());
var d2Time = (d2.getTime());
//calculate the difference in date times
var diff = d2 - d1;
//create a new date using the time differences (starts at Jan 1, 1970)
var dDiff = new Date();
dDiff.setTime(diff);
//chop off 1970 and get year, month, day, and hour
var years = dDiff.getFullYear() - 1970;
var months = dDiff.getMonth();
var days = dDiff.getDate();
var hours = dDiff.getHours();
You can see it in action at this temporary host.
Why don't you just do the math to calculate the values? What you are putting into Date when you do dDiff.setTime(diff); is meaningless to you. That is just going to give you the date diff ms from the epoch.
Changing part of your code may solve your problem. jsfiddle
var start = new Date(0); // pivote point of date.
var years = dDiff.getFullYear() - start.getFullYear();
var months = dDiff.getMonth() - start.getMonth();
var days = dDiff.getDate() - start.getDate();
var hours = dDiff.getHours() - start.getHours();;
console.log(years, months, days, hours);
But you have to manipulate these values based on there value( they may come negative).
Date represents a particular point in time, not a timespan between two dates.
You are creating a new date by setting dDiff milliseconds ellapsed since the unix epoch.
Once you have the milliseconds ellapsed, you should extract the information you need by dividing it. See this question.
May I recomend taking a look at Moment.js?
This won't be accurate as it does not take into account the leap dayys. Other than that, it is working correctly and I don't see any problem. The time difference is roughly 6.5 days. Taking into account timezone and the fact that 0 is Jan 1st, the value I see is as expected.
The accurate solution would be to
Convert the time difference into days
Subtract the number of leap years elapsed since the specified date
Divide the remaining by 365 to get the number of days
Create an array with the day count of each month (without considering leap days) and loop through the elapsed months, subtracting the day count for the completed months. The number of iterations will be your month count
The remainder is your day count
Various notes:
new Date(2012, 8, 28, 13, 14, 0, 0); is 28 September 2012 13:14:00 (not August if you would it)
new Date(0) returned value is not a constant, because of the practice of using Daylight Saving Time.
dDiff.getMonth(); return 0 for Jan, 1 for Feb etc.
The begin of date (1 Jan 1970) begin with 1 so in difference you should subtract this.
I think the second point is your mistake.
According with your algorithm, try this:
// create date in UTC
//create custom test date
var dlocaltime = new Date(2012, 8, 28, 13, 14, 0, 0);
var d1 = new Date(dlocaltime.getUTCFullYear(),dlocaltime.getUTCMonth(), dlocaltime.getUTCDate(), dlocaltime.getUTCHours(),dlocaltime.getUTCMinutes(),dlocaltime.getUTCSeconds());
//create current date
var now = new Date();
var d2 = new Date(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate(), now.getUTCHours(), now.getUTCMinutes(), now.getUTCSeconds());
console.log(d1);
console.log(d2);
//get date times (ms)
var d1Time = (d1.getTime());
var d2Time = (d2.getTime());
//calculate the difference in date times
var diff = d2 - d1;
//create a new date using the time differences (starts at Jan 1, 1970)
var dDiff = new Date();
dDiff.setTime(diff);
//chop off 1970 and get year, month, day, and hour
var years = dDiff.getUTCFullYear() - 1970;
var months = dDiff.getUTCMonth();
var days = dDiff.getUTCDate()-1; // the date of new Date(0) begin with 1
var hours = dDiff.getUTCHours();
var minutes = dDiff.getUTCMinutes();
var seconds = dDiff.getUTCSeconds();
console.log("Years:"+years);
console.log("months:"+months);
console.log("days:"+days);
console.log("hours:"+hours);
console.log("minutes:"+minutes);
console.log("seconds:"+seconds);