I was trying to calculate the days left until a specific date. I know that there are a million different approaches and tutorials about it, but I wanted to write a code by myself. The problem is that the output of the function is "NaN". I am very thankful for your help.
This is my code:
var daysLeft = function(input) {
var num = '';
var date = [];
var x = 0;
for (i = 0; i < input.length; i++) {
if (!isNaN(input.charAt(i))) {
num += input.charAt(i);
}
else {
date[x] = parseInt(num, 10);
x++;
}
}
var inputDate = new Date(date[2], date[1], date[0]);
var today = new Date();
var timeDiff = Math.abs(inputDate.getTime() - today.getTime());
return Math.ceil(timeDiff / (1000*3600*24));
};
daysLeft("11.12.2014");
BTW: I wrote this code, because the Date() function works with the American format of Dates (MM/dd/YYYY) and not with UTC dates. I am also aware that there is the Date.UTC() function, but anyway. I just wanted to turn around months and days myself.
When you parse num to set date[x], you need to reset num to ''.
...
else {
date[x] = parseInt(num, 10);
x++;
num = '';
}
You might consider using String.split() to separate your input at the periods.
My Solution is:
function isNumeric(n) {
return !isNaN(parseFloat(n)) && isFinite(n);
}
var daysLeft = function(input) {
var num = '';
var date = [];
var x = 0;
for (i = 0; i < input.length; i++) {
if (!isNaN(input.charAt(i)) && isNumeric(input.charAt(i))) {
num += input.charAt(i);
}
else {
date[x] = parseInt(num, 10);
x++;
num = '';
}
}
date[x] = parseInt(num, 10);
var inputDate = new Date(date[2], date[1], date[0]);
var today = new Date();
var timeDiff = Math.abs(inputDate.getTime() - today.getTime());
return Math.ceil(timeDiff / (1000*3600*24));
};
But a better would be:
function parseDate(input) {
var parts = input.split('-');
// new Date(year, month [, day [, hours[, minutes[, seconds[, ms]]]]])
return new Date(parts[0], parts[1]-1, parts[2]); // Note: months are 0-based
}
var daysLeft = function(input) {
var inputDate = parseDate(input);
var today = new Date();
var timeDiff = Math.abs(inputDate.getTime() - today.getTime());
return Math.ceil(timeDiff / (1000*3600*24));
};
You should use something like this:
var daysLeft = function(input) {
var num = '';
var date = [];
var x = 0;
for (i = 0; i < input.length; i++) {
if (!isNaN(input.charAt(i))) {
num += input.charAt(i);
}
else {
date[x] = parseInt(num, 10);
x++;
num='';
}
}
date[x] = parseInt(num, 10);
var inputDate = new Date(date[2], date[1], date[0]);
var today = new Date();
var timeDiff = Math.abs(inputDate.getTime() - today.getTime());
return Math.ceil(timeDiff / (1000*3600*24));
};
daysLeft("11.12.2014");
Related
I have a date in datetime and I need to calculate it with the current date in javascript to check if 7 days have passed.
var created_at = 2021-05-20; //return 2021-05-20 14:00:00
var data = new Date();
var dataAtual = data.getFullYear() + "-" + ("0" + (data.getMonth() + 1)).substr(-2) + "-" + ("0" + data.getDate()).substr(-2);
var result = data - created_at;
if(result < 7){
var create_date = true;
console.log(true);
} else {
var created_date = false;
console.log(false);
}
Can you try the below code
var date1 = new Date('2021-05-20 14:00:00')
var date2 = new Date()
var resulu = date2.getDate() - date1.getDate()
if(result < 7){
var create_date = true;
console.log(true);
} else {
var created_date = false;
console.log(false);
}
Get the difference of dates in milliseconds and convert into days.
const old_date = new Date('2021-05-20');
const today = new Date();
const diff_days = (today - old_date) / 24 * 60 * 60 * 1000;
if (diff_days < 7) {
console.log('older than a week');
} else {
console.log('in last week');
}
Do not know what i'm doing wrong and would like some help to fix it i am trying to make script to write out the day date and time like this It is currently: 3:15 PM on Wednesday, September 21. this is what i have
function renderTime(){
var mydate = new date();
var year = mydate.getYear();
if(year < 1000){
year +=1900
}
var day = mydate.getDay();
var month = mydate.getMonth();
var daym = mydate.getDate();
var dayarray = new Array("Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday");
var montharray = new Array("Jannuary","Februry","March","April","May","June","July","Augest","September","October","November","December");
var currentTime = new Date();
var h = currentTime.getHour();
var m = currentTime.getMinutes();
var ampm = h >= 12 ? 'pm' : 'am';
if(h == 24){
h = 0;
} else if (h > 12 ){
h = h - 0;
}
if(h < 10){
h = "0" + h;
}
if(m < 10){
m = "0" + m;
}
}
document.write("It is currently"+h+m+"on"+dayarray[day]+ montharray[month]+daym);
You can simplify it by using toLocaleDateString and toLocaleTimeString:
var myDate = (new Date()).toLocaleDateString("en-US", {weekday: 'long',month: 'long',day: 'numeric'});
var myTime = (new Date()).toLocaleTimeString("en-US", {hour: 'numeric',minute: 'numeric'
});
var message = 'It is currently: ' + myTime + ' on ' + myDate;
console.log(message);
var mydate = new Date();
var year = mydate.getYear();
if(year < 1000){
year +=1900
}
var day = mydate.getDay();
var month = mydate.getMonth();
var daym = mydate.getDate();
var dayarray = new Array("Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday");
var montharray = new Array("Jannuary","Februry","March","April","May","June","July","Augest","September","October","November","December");
var currentTime = new Date();
var h = currentTime.getHours();
var m = currentTime.getMinutes();
var ampm = h >= 12 ? 'pm' : 'am';
if(h == 24){
h = 0;
} else if (h > 12 ){
h = h - 12;
}
if(h < 10){
h = "0" + h;
}
if(m < 10){
m = "0" + m;
}
document.write("It is currently "+h+ ":"+ m+ ampm +" on "+dayarray[day] + ' ' + montharray[month] + ' '+daym);
let dateString = new Date().toLocaleDateString("en-US").split("/");
// returns an array ["month", "day as number in month", "year"]
let timeString = new Date().toLocaleTimeString("en-US").split(/:| /);
// returns an array ["hour", "minute", "second", "am or pm"]
let weekDayNumber = new Date().getDay();
let days = ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];
let months = ["Jannuary","Februry","March","April","May","June","July","Augest","September","October","November","December"];
document.write("It is currently"+timeString[0]+timeString[1]+"on"+days[weekDayNumber ]+ months[dateString[0]]+dateString[1]);
You're running all your date rendering in a function which keeps all your interim variables private. This is a good thing, but you're not providing any way to get the result out. Include a return statement in your function to return the formatted string like this:
return ("It is currently "+h+":"+m+" on "+dayarray[day]+" "+ montharray[month]+" "+daym);
You create a new Date object for time, but you should just use the one you created for date, and you missed a letter of a method name. Here's the revised version:
function renderTime(){
var mydate = new Date();
var year = mydate.getYear();
if(year < 1000){
year +=1900
}
var day = mydate.getDay();
var month = mydate.getMonth();
var daym = mydate.getDate();
var dayarray = new Array("Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday");
var montharray = new Array("January","Februry","March","April","May","June","July","Augest","September","October","November","December");
// re-use mydate here instead of creating a new object.
var h = mydate.getHours(); // You missed the 's' off 'getHours()'
var m = mydate.getMinutes();
var ampm = h >= 12 ? 'pm' : 'am';
if(h == 24){
h = 0;
} else if (h > 12 ){
h = h - 0;
}
if(h < 10){
h = "0" + h;
}
if(m < 10){
m = "0" + m;
}
// Return the result. Added some spaces to pretty it up a bit
return ("It is currently "+h+":"+m+ampm+" on "+dayarray[day]+" "+ montharray[month]+" "+daym);
}
// Now output the return value of the function.
document.write(renderTime());
I'm creating a custom function in Google Sheets to provide the end date for a task based on the start date and the number of hours I think the task will take.
i.e. end date = start date + hours.
The function aims to skip weekends and consider a working day between 9 and 5pm (I'm working up to excluding lunchtimes and specifying weekends and holidays, but all in good time).
The function works fine for about five activities, but then errors "Exceeded maximum stack depth". Here's a screenshot of what I'm referring to.
And here's the AppScript / JavaScript.
//var startdate = new Date(2016, 04, 16, 9, 0, 0);
//var addhours = 3;
Date.prototype.addHours = function(h) {
this.setHours(this.getHours() + h);
return this;
}
Date.prototype.addDays = function(days) {
var dat = new Date(this.valueOf());
dat.setDate(dat.getDate() + days);
return dat;
}
/**
* Adds hours to a date excludes weekends
*
* #param {number} startdate The date to add the hours to
* #param {number} addHours The hours to add
* #return The new date
* #customfunction
*/
function MYWORKDAY(startdate, addhours) {
var endDate = new Date();
var endTime = new Date(startdate).setHours(17, 0, 0);
var remainingEffortHrs = new Date();
var availableTimeHrs = endTime - startdate;
availableTimeHrs = (availableTimeHrs / 1000) / 60 / 60;
if (startdate.map) { // Test whether input is an array.
return startdate.map(MYWORKDAY); // Recurse over array if so.
} else {
// Add the hours to the start date
//endDate = new Date(startdate).addHours(addhours);
endDate = new Date(startdate).addHours(addhours);
// Calculate remaining effort - if the task ends after 5pm
if (endDate > endTime) {
remainingEffortHrs = ((Math.abs(endDate - endTime)) / 1000) / 60 / 60;
} else {
remainingEffortHrs = 0;
}
if (remainingEffortHrs > 0) {
startdate = new Date(startdate).addDays(1);
startdate = MYWORKDAY(startdate, remainingEffortHrs);
} else {
// Remaining effort is 0
startdate = endDate;
}
return GetNextWorking(startdate);
}
}
function GetNextWorking(endDate) {
// Get the next working day
if (endDate.getDay() != 0 && endDate.getDay() != 6) {
return endDate;
} else {
adjustedEndDate = new Date(endDate.setDate(endDate.getDate() + 1));
adjustedEndDate = new Date(adjustedEndDate);
// Recursively call the this function until the returned
// date is a working day
return adjustedEndDate = GetNextWorking(adjustedEndDate);
}
}
I hope this makes sense. This has taken a while to get to this stage and any suggestions as to how to improve the performance or refactor would be greatly appreciated.
Here's the working code. I ran into some serious problems whilst trying to add code to include lunchtimes, but this worked to highlight the flaws in my logic. This should now also take into account a lunchtime from a second sheet called 'Settings' in Google Sheets. (I hadn't quite worked out how to bypass the Reference error when working outside of Google Sheets). This does however solve the Exceeded maximum stack depth error. Maybe you can suggest an improvement?
var dayStartTime = getStartTime();
var dayEndTime = getEndTime();
var lunchtimeEnd = getLunchtimeEnd();
var lunchtimeStart = getLunchtimeStart();
/* Starts the next day
*
* #param {number} startdate The date to add the hours to
* #return The new date
* #customfunction
*/
Date.prototype.addDays = function(days) {
var dat = new Date(this.valueOf());
dat.setDate(dat.getDate() + days);
return dat;
}
function addHours(date, h) {
return new Date(date.getTime() + (h*60*60*1000));
}
function MYWORKDAY(startdate,effort) {
if (startdate.map) {
return startdate.map(MYWORKDAY);
} else {
var endTime = new Date();
var availableTimeHrs;
var endDate = 0;
while (effort > 0)
{
endTime = new Date(startdate).setHours(dayEndTime.getHours(), dayEndTime.getMinutes(), dayEndTime.getSeconds());
lunchtimeEnd = todaysLunchEnd(startdate);
lunchtimeEnd = new Date(lunchtimeEnd);
lunchtimeStart = todaysLunchEnd(startdate);
lunchtimeStart = new Date(lunchtimeStart);
endDate = addHours(startdate, effort);
if (startdate <= lunchtimeStart && endDate >= lunchtimeEnd) {
endDate = addHours(endDate, 1);
}
if(endDate > endTime)
{
effort = ((Math.abs(endDate - endTime)) / 1000) / 60 / 60;
startdate = new Date(startdate).addDays(1);
startdate = GetNextWorking(startdate);
startdate = new Date(startdate).setHours(dayStartTime.getHours(), dayStartTime.getMinutes(), dayStartTime.getSeconds());
startdate = new Date(startdate);
}
else
{
effort = 0;
}
}
}
return endDate;
}
function GetNextWorking(endDate) {
if (endDate.getDay() != 0 && endDate.getDay() != 6) {
return endDate;
} else {
adjustedEndDate = new Date(endDate.setDate(endDate.getDate() + 1));
adjustedEndDate = new Date(adjustedEndDate);
return adjustedEndDate = GetNextWorking(adjustedEndDate);
}
}
function MYSTARTDATE(startdate) {
//var startTime = getStartTime();
var morningStart = new Date();
if (startdate.getHours() == 17) {
morningStart = startdate.addDays(1);
morningStart = GetNextWorking(morningStart);
morningStart.setHours(9);
} else {
morningStart = startdate;
}
return morningStart;
}
function todaysLunchEnd(endDate) {
var lunchtimeEnd = getLunchtimeEnd();
lunchtimeEnd = new Date(endDate).setHours(lunchtimeEnd.getHours(), lunchtimeEnd.getMinutes(), lunchtimeEnd.getSeconds());
lunchtimeEnd = new Date(lunchtimeEnd);
return lunchtimeEnd;
}
function getStartTime() {
var settingsSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Settings");
var range = settingsSheet.getRange("B5");
var startTime = range.getValue();
var startTime;
if (!startTime) {
startTime = new Date(28800000);
//startTime = new Date(32400000); // 09:00
}
return startTime;
}
function getEndTime() {
var settingsSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Settings");
var range = settingsSheet.getRange("B6");
var endTime = range.getValue();
if (!endTime) {
endTime = new Date(57600000);
//endTime = new Date(61200000); // 17:00
}
return endTime;
}
function getLunchtimeStart() {
var settingsSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Settings");
var range = settingsSheet.getRange("B7");
var startTime = range.getValue();
if (!startTime) {
startTime = new Date(39600000); //11am
//startTime = new Date(43200000); // 12pm
}
return startTime;
}
function getLunchtimeEnd() {
var settingsSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Settings");
var range = settingsSheet.getRange("B8");
var endTime = range.getValue();
if (!endTime) {
endTime = new Date(43200000); //12:00
//endTime = new Date(46800000); //13:00
}
return endTime;
}
****Salary type monthly.****
var getDiffDatesSalary = function days_between(date1,date2, monthlyBasic) {
var dateObj1 = new Date(date1);
var month1 = dateObj1.getMonth(); //months from 1-12
var day1 = dateObj1.getDate();
var year1 = dateObj1.getFullYear();
var daysInMonth1 = Date.getDaysInMonth(year1, month1);
var dateObj2 = new Date(date2);
var month2 = dateObj2.getMonth(); //months from 0-11
var day2 = dateObj2.getDate();// days from 1
var year2 = dateObj2.getFullYear();
var daysInMonth2 = Date.getDaysInMonth(year2, month2);
var date1FractionDays = daysInMonth1 - day1;
var date2FractionDays = daysInMonth2 - day2;
var newDate1, newDate2;
if(day1 > 1){
var perDaySalary1 = monthlyBasic / daysInMonth1;
var thisMonthFarctionDaysSalaryForDate1 = perDaySalary1 * date1FractionDays;
month1 += 1; // after calculate fraction this month basic, round month from next
newDate1 = new Date(year1,month1);
}
if(day2 !== daysInMonth2){
var perDaySalary2 = monthlyBasic / daysInMonth2;
var thisMonthFarctionDaysSalaryForDate2 = perDaySalary2 * day2;
month2 -= 1; //after calculate fraction this month basic, round month from previous
newDate2 = new Date(year2,month2);
}
// i want to calculate totalSalaryamount of date ranges
// var totalFractionDaysSalary = thisMonthFarctionDaysSalaryForDate1 + thisMonthFarctionDaysSalaryForDate2;
// var totalMonthsSalay = roundMonths * monthlyBasic;
// var totalSalaryamount = totalFractionDaysSalary + totalMonthsSalay;
};
**
result = thisMonthFarctionDaysSalaryForDate1 + thisMonthFarctionDaysSalaryForDate2 + (roundMonths * monthlyBasic)
result will be getDiffDatesSalary("2016/01/15","2016/03/25", 1000);
516.13+806.45 + 1000 // total: 2322.58
Or/And getDiffDatesSalary("2015/01/15","2016/03/25", 1000) ;
516.13+806.45 + (1000 * 13) // total: 14322.58
Or/And getDiffDatesSalary("2016/01/01","2016/02/29", 1000);
1000* 2 // 2000
**
I suggest to split the task in two sections:
Get total days
Calculate salary.
This proposal uses the difference between years, months and days and makes a correction if the day difference is negative. Same day means one day.
function getDays(date1, date2) {
var date1Obj = new Date(date1),
date2Obj = new Date(date2),
totalYear = date2Obj.getFullYear() - date1Obj.getFullYear(),
totalMonth = date2Obj.getMonth() - date1Obj.getMonth(),
totalDay = date2Obj.getDate() - date1Obj.getDate() + 1;
if (totalDay < 0) {
totalMonth--;
totalDay += new Date(date1Obj.getFullYear(), date1Obj.getMonth(), 0).getDate();
}
return 360 * totalYear + 30 * totalMonth + totalDay;
}
function getDiffDatesSalary(date1, date2, salaryPerMonth) {
return getDays(date1, date2) * salaryPerMonth / 30;
}
document.write(getDiffDatesSalary("2016/01/15", "2016/03/25", 1000) + '<br>');
document.write(getDiffDatesSalary("2016/01/31", "2016/02/15", 1000) + '<br>');
document.write(getDiffDatesSalary("2016/03/20", "2016/03/20", 3000) + '<br>');
I got the answer of my question. If anyone need or improve this answer. Here is the working codes:
var getDiffDatesSalary = function days_between(date1,date2, monthlyBasic) {
var dateObj1 = new Date(date1);
var month1 = dateObj1.getMonth(); //months from 0-11
var day1 = dateObj1.getDate();
var year1 = dateObj1.getFullYear();
var daysInMonth1 = Date.getDaysInMonth(year1, month1);
var dateObj2 = new Date(date2);
var month2 = dateObj2.getMonth(); //months from 0-11
var day2 = dateObj2.getDate();// days from 1
var year2 = dateObj2.getFullYear();
var daysInMonth2 = Date.getDaysInMonth(year2, month2);
//get number of months in two different dates;
var diffMonths = parseInt(diffInMonths(date2,date1)) +1; //from 1-12
var date1FractionDays = daysInMonth1 - day1; // date1 fraction days
var date2FractionDays = daysInMonth2 - day2; // date2 fraction days
var totalFractionDaysSalary= 0, fractionMonthsCount = 0, thisMonthFarctionDaysSalaryForDate1 = 0, thisMonthFarctionDaysSalaryForDate2 =0; //reset as 0;
//when date1: day start from 01, no fraction start of the month. Otherwise calculate salary for fraction days
if(day1 > 1){
var perDaySalary1 = monthlyBasic / daysInMonth1;
thisMonthFarctionDaysSalaryForDate1 = perDaySalary1 * date1FractionDays;
fractionMonthsCount +=1;
}
//when date2: day end === end Of the Month, no fraction. Otherwise calculate salary for fraction days
if(day2 !== daysInMonth2){
var perDaySalary2 = monthlyBasic / daysInMonth2;
thisMonthFarctionDaysSalaryForDate2 = perDaySalary2 * day2;
fractionMonthsCount +=1;
}
// both date1 date2 fraction days salary sum
totalFractionDaysSalary = thisMonthFarctionDaysSalaryForDate1 + thisMonthFarctionDaysSalaryForDate2;
var roundMonthsForSalary = diffMonths - fractionMonthsCount; // after less round month calculate
// if user do wrong reset as 0. because negative month not possible
if (roundMonthsForSalary < 0){
roundMonthsForSalary = 0;
}
// round month salary calculation
var totalSalaryForRoundMonths = roundMonthsForSalary * monthlyBasic;
// finally fraction days and round month sum to get return result.
return totalFractionDaysSalary + totalSalaryForRoundMonths;
};
// get number of months in two different dates
function diffInMonths(to,from){
var months = to.getMonth() - from.getMonth() + (12 * (to.getFullYear() - from.getFullYear()));
if(to.getDate() < from.getDate()){
var newFrom = new Date(to.getFullYear(),to.getMonth(),from.getDate());
if (to < newFrom && to.getMonth() == newFrom.getMonth() && to.getYear() %4 != 0){
months--;
}
}
return months;
};
The below script is failing for the scenario : start date 09/12/2009 end date 10/15/2009. The date difference is not more than 90 days, but still fails. can any one help?
var startDate = new Date(document.getElementById('ctl00$MainContent$FromYearTxt').value);
var endDate = new Date(document.getElementById('ctl00$MainContent$ToYearTxt').value);
var monthsDiff = endDate.getMonth() - startDate.getMonth();
var durationLimit = 0;
for (i = 1; i <= monthsDiff; i++) {
durationLimit += new Date(startDate.getFullYear(), startDate.getMonth() + i, 0).getDate();
}
var timeDiff = endDate.getTime() - startDate.getTime();
var daysDiff = Math.floor(timeDiff / (1000 * 60 * 60 * 24));
if (daysDiff > durationLimit) {
args.IsValid = false;
} else {
args.IsValid = true;
}
If you are looking for a 3 month validation, then I think a better choice will be
function test() {
var args = {}; //creating for test
var startDate = new Date(document.getElementById('ctl00$MainContent$FromYearTxt').value);
var endDate = new Date(document.getElementById('ctl00$MainContent$ToYearTxt').value);
var maxDate = new Date(startDate);
maxDate.setMonth(maxDate.getMonth() + 3);
args.IsValid = endDate.getTime() <= maxDate.getTime();
document.getElementById('result').innerHTML = JSON.stringify(args)
}
<input id="ctl00$MainContent$FromYearTxt" value="03/13/2009" />
<input id="ctl00$MainContent$ToYearTxt" value="06/13/2009" />
<button onclick="test()">Test</button>
<div id="result"></div>