I have a calculation function and part of this shows the number of days it will take to achieve a goal.
Rather than just show the number of days I want to calculate this into days & months or days, months and years depending on the number. I have an if statement for the splitting but can't seem to work out the maths to go from for example 132 days to x days x months... Any suggestions?
// GOAL
var timeToGoal = Math.round(goal / costPerDay);
// if more than a year
if ( timeToGoal >= 365 ) {
alert('days + months + years');
// if more than a month but less than a year
} else if ( timeToGoal >= 30 && timeToGoal <=365 ) {
alert('Days + months');
} else {
alert('days');
$('#savings-goal span').text(timeToGoal+' days');
}
Try something like this;
function humanise (diff) {
// The string we're working with to create the representation
var str = '';
// Map lengths of `diff` to different time periods
var values = [[' year', 365], [' month', 30], [' day', 1]];
// Iterate over the values...
for (var i=0;i<values.length;i++) {
var amount = Math.floor(diff / values[i][1]);
// ... and find the largest time value that fits into the diff
if (amount >= 1) {
// If we match, add to the string ('s' is for pluralization)
str += amount + values[i][0] + (amount > 1 ? 's' : '') + ' ';
// and subtract from the diff
diff -= amount * values[i][1];
}
}
return str;
}
It's expected that the argument is the difference in days you want to represent. It assumes a month of 30 days and a year of 365.
You should be using it like this;
$('#savings-goal span').text(humanise(timeToGoal));
http://jsfiddle.net/0zgr5gfj/
an attempt from me (this take leap year into account and based on the current date)
function humanise(total_days)
{
//var total_days = 1001;
var date_current = new Date();
var utime_target = date_current.getTime() + total_days*86400*1000;
var date_target = new Date(utime_target);
var diff_year = parseInt(date_target.getUTCFullYear() - date_current.getUTCFullYear());
var diff_month = parseInt(date_target.getUTCMonth() - date_current.getUTCMonth());
var diff_day = parseInt(date_target.getUTCDate() - date_current.getUTCDate());
var days_in_month = [31, (date_target.getUTCFullYear()%4?29:28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
var date_string = "";
while(true)
{
date_string = "";
date_string += (diff_year>0?diff_year + "Y":"");
if(diff_month<0){diff_year -= 1; diff_month += 12; continue;}
date_string += (diff_month>0?diff_month + "M":"");
if(diff_day<0){diff_month -= 1; diff_day += days_in_month[((11+date_target.getUTCMonth())%12)]; continue;}
date_string += (diff_day>0?diff_day + "D":"");
break;
}
console.log(date_string);
return date_string;
}
var timeToGoal = 1001;
$('#savings-goal span').text(humanise(timeToGoal));
This is a simpler solution that I did without the for bucle:
function jarh(x) {
var y = 365;
var y2 = 31;
var remainder = x % y;
var casio = remainder % y2;
year = (x - remainder) / y;
month = (remainder - casio) / y2;
var result ="--- Year ---" + year + "--- Month ---" + month + "--- Day ---" + casio;
return result;
}
var call = jarh(6781);
http://jsfiddle.net/yHAcY/1/
Related
I want to convert our current date on Earth to the current date on Mars, based on the Earth Date to Martian Solar Longitude Converter from this converter .
The way the code calculates the current date on Mars should be correct, so if anyone knows what's my mistake and how to help, please answere me.
JS:
function CheckGivenYear(){
let leap; // leap year ? (0==no, 1==yes) (returned value)
const val = val.getFullYear();
// check if it is a leap year
/* a year is a leap year if it is a multiple of 4 but not of 100,
or if it is a multiple of 400 */
if ((val % 4 == 0 && val % 100 != 0) || val % 400 == 0) {
leap = 1;
} else {
leap = 0; // not a leap year
}
return leap;
}
function Convert2Julian() {
let currentDate = new Date(),
day = currentDate.getDate(),
month = currentDate.getMonth() + 1,
year = currentDate.getFullYear();
let leap; // leap year ? (0==no, 1==yes)
let i;
let ref_year = 1968;
let ref_jDate = 2.4398565e6; // Julian date for 01/01/1968 00:00:00
let eDays = new Array(0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334);
// eDays = number of elapsed days during previous months of same year
let nDay = 0.0; // number of days
// compute number of days due to years
if (year > ref_year) {
for (i = ref_year; i < year; i++) {
nDay = nDay + 365.0;
if ((i % 4 == 0 && i % 100 != 0) || i % 400 == 0) {
// leap year
nDay++;
}
}
} else {
for (i = year; i < ref_year; i++) {
nDay = nDay - 365.0;
if ((i % 4 == 0 && i % 100 != 0) || i % 400 == 0) {
// leap year
nDay--;
}
}
}
leap = CheckGivenYear();
nDay = nDay + eDays[month - 1];
//alert(nDay)
//add 1 if year is leap and month >=3
if (leap == 1 && month >= 3) {
nDay = nDay + 1;
}
// add reference year offset and day
//jDate=ref_jDate+nDay+day;
let jDate = nDay * 1.0 + day * 1.0 + ref_jDate * 1.0 - 1.0;
return jDate;
}
function Convert2Ls() {
// Convert a Julian date to corresponding "sol" and "Ls"
let jDate;
let sol;
let ls;
let martianYear;
let martianMonth;
let jDate_ref = 2.442765667e6; // 19/12/1975 4:00:00, such that Ls=0
// jDate_ref is also the beginning of Martian Year "12"
let martianYear_ref = 12;
let earthDay = 86400.0;
let marsDay = 88775.245;
let marsYear = 668.6; // number of sols in a martian year
// Start by converting given date to Julian date
jDate = Convert2Julian();
// Convert julian days to sol date
//jDate = document.julian.value;
sol = ((jDate - jDate_ref) * earthDay) / marsDay;
martianYear = martianYear_ref;
// Compute Martian Year #, along with sol value
// sol being computed modulo the number of sols in a martian year
while (sol >= marsYear) {
sol = sol - marsYear;
martianYear = martianYear + 1;
}
while (sol < 0.0) {
sol = sol + marsYear;
martianYear = martianYear - 1;
}
// convert sol number to Ls
ls = Sol2Ls(sol);
// Knowing Ls compute martian month
martianMonth = 1 + Math.floor(ls / 30);
ls = Math.round(ls * 10) / 10;
sol = 1 + Math.floor(sol);
//Display value with a maximum of 2 decimal digits
//document.martianYear.value = martianYear;
//document.calendar.martianMonth.value = martianMonth;
//document.calendar.ls.value = Math.round(ls * 10) / 10;
//document.calendar.sol.value=Math.round(sol*10)/10;
//document.calendar.sol.value = 1 + Math.floor(sol);
}
function Sol2Ls(sol) {
var sol;
let ls;
let year_day = 668.6; // number of sols in a martian year
let peri_day = 485.35; // perihelion date
let e_ellip = 0.0934; // orbital ecentricity
let timeperi = 1.90258341759902; // 2*Pi*(1-Ls(perihelion)/360); Ls(perihelion)=250.99
let rad2deg = 180 / Math.PI;
let i;
let zz,
zanom,
zdx = 10;
let xref, zx0, zteta;
// xref: mean anomaly, zx0: eccentric anomaly, zteta: true anomaly
zz = (sol - peri_day) / year_day;
zanom = 2 * Math.PI * (zz - Math.round(zz));
xref = Math.abs(zanom);
// Solve Kepler equation zx0 - e *sin(zx0) = xref
// Using Newton iterations
zx0 = xref + e_ellip * Math.sin(xref);
do {
zdx =
-(zx0 - e_ellip * Math.sin(zx0) - xref) / (1 - e_ellip * Math.cos(zx0));
zx0 = zx0 + zdx;
} while (zdx > 1e-7);
if (zanom < 0) zx0 = -zx0;
// Compute true anomaly zteta, now that eccentric anomaly zx0 is known
zteta =
2 * Math.atan(Math.sqrt((1 + e_ellip) / (1 - e_ellip)) * Math.tan(zx0 / 2));
// compute Ls
ls = zteta - timeperi;
if (ls < 0) ls = ls + 2 * Math.PI;
if (ls > 2 * Math.PI) ls = ls - 2 * Math.PI;
// convert Ls into degrees
ls = rad2deg * ls;
return ls;
}
A Javascript Date object for Mars timekeeping and Earth-Mars date/time conversion.
https://github.com/aresastro/marsdatejs
****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;
};
I have a calculation function and part of this shows the number of days it will take to achieve a goal.
Rather than just show the number of days I want to calculate this into days & months or days, months and years depending on the number. I have an if statement for the splitting but can't seem to work out the maths to go from for example 132 days to x days x months... Any suggestions?
// GOAL
var timeToGoal = Math.round(goal / costPerDay);
// if more than a year
if ( timeToGoal >= 365 ) {
alert('days + months + years');
// if more than a month but less than a year
} else if ( timeToGoal >= 30 && timeToGoal <=365 ) {
alert('Days + months');
} else {
alert('days');
$('#savings-goal span').text(timeToGoal+' days');
}
Try something like this;
function humanise (diff) {
// The string we're working with to create the representation
var str = '';
// Map lengths of `diff` to different time periods
var values = [[' year', 365], [' month', 30], [' day', 1]];
// Iterate over the values...
for (var i=0;i<values.length;i++) {
var amount = Math.floor(diff / values[i][1]);
// ... and find the largest time value that fits into the diff
if (amount >= 1) {
// If we match, add to the string ('s' is for pluralization)
str += amount + values[i][0] + (amount > 1 ? 's' : '') + ' ';
// and subtract from the diff
diff -= amount * values[i][1];
}
}
return str;
}
It's expected that the argument is the difference in days you want to represent. It assumes a month of 30 days and a year of 365.
You should be using it like this;
$('#savings-goal span').text(humanise(timeToGoal));
http://jsfiddle.net/0zgr5gfj/
an attempt from me (this take leap year into account and based on the current date)
function humanise(total_days)
{
//var total_days = 1001;
var date_current = new Date();
var utime_target = date_current.getTime() + total_days*86400*1000;
var date_target = new Date(utime_target);
var diff_year = parseInt(date_target.getUTCFullYear() - date_current.getUTCFullYear());
var diff_month = parseInt(date_target.getUTCMonth() - date_current.getUTCMonth());
var diff_day = parseInt(date_target.getUTCDate() - date_current.getUTCDate());
var days_in_month = [31, (date_target.getUTCFullYear()%4?29:28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
var date_string = "";
while(true)
{
date_string = "";
date_string += (diff_year>0?diff_year + "Y":"");
if(diff_month<0){diff_year -= 1; diff_month += 12; continue;}
date_string += (diff_month>0?diff_month + "M":"");
if(diff_day<0){diff_month -= 1; diff_day += days_in_month[((11+date_target.getUTCMonth())%12)]; continue;}
date_string += (diff_day>0?diff_day + "D":"");
break;
}
console.log(date_string);
return date_string;
}
var timeToGoal = 1001;
$('#savings-goal span').text(humanise(timeToGoal));
This is a simpler solution that I did without the for bucle:
function jarh(x) {
var y = 365;
var y2 = 31;
var remainder = x % y;
var casio = remainder % y2;
year = (x - remainder) / y;
month = (remainder - casio) / y2;
var result ="--- Year ---" + year + "--- Month ---" + month + "--- Day ---" + casio;
return result;
}
var call = jarh(6781);
http://jsfiddle.net/yHAcY/1/
I have one date parameter. 31 October 2014. i want to get next days = 45 days after 31 October 2014. So it should be 2 Januari 2015. and excluding Saturday and Sunday.
I already make the function like this. But when i add 45. the 45 not excluding Saturday and Sunday.
function getNextBusinessDay() {
return getDeliveryDateObj(1);
}
function getDeliveryDateObj(businessDaysLeftForDelivery) {
var now = new Date();
var dayOfTheWeek = now.getDay();
now.setDate(now.getDate() + 45);
var calendarDays = businessDaysLeftForDelivery;
var deliveryDay = dayOfTheWeek + businessDaysLeftForDelivery;
if (deliveryDay >= 6) {
businessDaysLeftForDelivery -= 6 - dayOfTheWeek; //deduct this-week days
calendarDays += 2; //count this coming weekend
deliveryWeeks = Math.floor(businessDaysLeftForDelivery / 5); //how many whole weeks?
calendarDays += (deliveryWeeks * 2); //two days per weekend per week
}
now.setTime(now.getTime() + calendarDays * 24 * 60 * 60 * 1000);
return now;
}
This addWeekdays function should do what you want.
function addWeekdays(date, weekdays) {
var newDate = new Date(date.getTime());
var i = 0;
while (i < weekdays) {
newDate.setDate(newDate.getDate() + 1);
var day = newDate.getDay();
if (day > 1 && day < 7) {
i++;
}
}
return newDate;
}
var currentDate = new Date('10/31/2014');
var targetDate = addWeekdays(currentDate, 45);
alert(targetDate);
Here's how I solved my problem:
function test() {
var startDate = "31-oct-2014";
startDate = new Date(startDate.replace(/-/g, "/"));
var endDate = "", noOfDaysToAdd = 45, count = 0;
while (count < noOfDaysToAdd) {
endDate = new Date(startDate.setDate(startDate.getDate() + 1));
if (endDate.getDay() != 0 && endDate.getDay() != 6) {
count++;
}
}
$("#Test").val(endDate);
}
Have been fighting this for too many days. I am trying to display the difference of a date (x) and now as follows:
If the diff is exactly a year or years - just display the year diff
If the diff is years and months (1 year, 5 months) display it like that
If the diff is months (no years), display the months diff
If it's days, display the days.
Hope that's clear - I'm very tired.
Here is my code (the commented lines are what I can't get to work):
function RelativeTime(x){
var plural = '';
var mins = 60, hour = mins * 60; day = hour * 24,
week = day * 7, month = week * 4, year = day * 365;
if (x >= year){ x = (x / year)|0; dformat="year"; }
//else
//if ((x >= year)&& (x >= month)) { x = (x / year), (x / month)|0 ; dformat="year" , "month"; }
else if (x >= month) { x = (x / month)|0; dformat="month"; }
else if (x >= day*4) { x = (x / day)|0; dformat="day"; }
else if (x >= hour) { x = (x / hour)|0; dformat="hr"; }
else if (x >= mins) { x = (x / mins)|0; dformat="min"; }
else { x |= 0; dformat="sec"; }
if (x > 1) plural = 's';
if (x < 0) x = 0;
return x + ' ' + dformat + plural;
}
Try, this http://jsfiddle.net/mk95J/5/:
var age = '';
function RelativeTime(x){
var ymwdhm = [ [31536000, 'year'],
[2419200, 'month'],
[604800, 'week'],
[86400, 'day'],
[3600, 'hour'],
[60, 'min'],
[1, 'sec'] ];
for(var i=0;i<7;i++) {
if(x >= ymwdhm[i][0]) {
var res = parseInt(x / ymwdhm[i][0], 10);
age += res;
age += ymwdhm[i][1];
age += res > 1 ? 's ' : ' '; // plural
RelativeTime(x - (res * ymwdhm[i][0]));
break;
}
}
}
RelativeTime( 35746121 );
document.write(age); // 1year 1month 2weeks 6days 17hours 28mins 41 secs
I would think you would want to construct your string as you go, since you want to build it up. The "else if" constructs would be good if you were only going to show the highest level of difference (only years, or only months).
Maybe something like this:
function RelativeTime(x) {
var mins = 60, hour = mins * 60; day = hour * 24,
week = day * 7, month = week * 4, year = day * 365;
var responseString = '';
if (x >= year) {
var numberOfYears = parseInt(x / year, 10);
x = x - (numberOfYears * year);
responseString += numberOfYears + ' year';
if (numberOfYears > 1) {
responseString += 's';
}
responseString += ' ';
}
if (x >= month) {
var numberOfMonths = parseInt(x / month, 10);
x = x - (numberOfMonths * month);
responseString += numberOfMonths + ' month';
if (numberOfMonths > 1) {
responseString += 's';
}
responseString += ' ';
}
return responseString;
}
// And so on ....
document.write(RelativeTime(35746121));
There are some efficiencies that could be managed within there as well (it's certainly looking like a function could come out of there to replace the almost duplicate code, and you could probably reuse some variables through there).