Javascript Relative Time - Display difference in Years & Months - javascript

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).

Related

Convert current date to Mars date with JavaScript

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

Datatables footer sum()

I'm trying to make a correct sum() of hh:mm:ss type of data, and i'm trying to understand why it has this behaviour when the minutes or seconds are getting >= 100. And how can i fix it?
correct:
incorrect:
This is the sum() function i took from Datatables forum:
jQuery.fn.dataTable.Api.register('sum()', function () {
return this.flatten().reduce(function (a, b) {
if (typeof a === 'string') {
a = a.replace(/[^\d.-]/g, '') * 1;
}
if (typeof b === 'string') {
b = b.replace(/[^\d.-]/g, '') * 1;
}
return a + b;
}, 0);
});
And this is the rest of the code full of conversions, and making my head spin.
var tempoPage = tempo.column(3, { page: 'current' })
.data()
.sum();
tempoPage = tempoPage.toString();
while (tempoPage.length < 6) {
tempoPage = "0" + tempoPage
}
tempoPage = tempoPage.replace(/^(\d+)(\d{2})(\d{2})$/, function (m, m1, m2, m3) {
m1 = Number(m1);
m2 = Number(m2);
m2 += parseInt(m3 / 60, 10);
m3 = m3 % 60; // get soconds
m1 += parseInt(m2 / 60, 10); //get hours
m2 = m2 % 60; // get minutes
//convert back to string
m2 = m2.toString();
m3 = m3.toString();
m1 = m1.toString();
while (m1.length < 2){
m1 = '0' + m1
}
while (m2.length < 2){
m2 = '0' + m2
}
while (m3.length < 2){
m3 = '0' + m3
}
return m1 + ':' + m2.slice(-2) + ':' + m3.slice(-2);
})
//write in footer
$(tempo.column(3)
.footer()).html(tempoPage);
},
Does any one see a better way to do this or can point me on the right track?
Thank you.
I cannot say what is wrong with the code. It seems really complicated, the only thing we need to do is to sum 3 values, and add for example 1 minute when seconds increases 60. Have made this less complicated sumHours() plugin, it seems to do the job (but have not tested in depth) :
jQuery.fn.dataTable.Api.register( 'sumHours()', function ( ) {
function pad(int) {
return int > 9 ? int.toString() : '0' + int.toString()
}
var t, hours = 0, mins = 0, secs = 0;
for (var i=0; i<this.length; i++) {
t = this[i].split(':')
hours += parseInt(t[0])
mins += parseInt(t[1])
if (mins >= 60) {
mins -= 60
hours += 1
}
secs += parseInt(t[2])
if (secs >= 60) {
secs -= 60
mins += 1
}
}
return pad(hours) + ':' + pad(mins) + ':' + pad(secs)
})
You can use this the same way as the as the official sum() example you hve linked to :
api.column( 0, {page:'current'} ).data().sumHours()
demo -> http://jsfiddle.net/vbuyjm9s/

How can I get the amount of month from days in js? [duplicate]

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/

javascript Date Object how long ago

I'm trying to show how long ago a video was uploaded, i cant seem to get the hours and minutes Date Object Methods to work in this script. I'm working of a script called YouMax 2.0 and i have been editing the function getDateDiff, i have come up with this edit of the function. Thank you for any help on this.
function getDateDiff(timestamp) {
if (null === timestamp || timestamp === "" || timestamp === "undefined") return "?";
var splitDate = ((timestamp.toString().split('T'))[0]).split('-');
var splitTime = ((timestamp.toString().split('T'))[1]).split(':');
var d1 = new Date();
var d1Y = d1.getFullYear();
var d2Y = parseInt(splitDate[0], 10);
var d1M = d1.getMonth() + 1;
var d2M = parseInt(splitDate[1], 10);
var d1D = d1.getDate();
var d2D = parseInt(splitDate[2], 10);
var d1H = d1.getHours();
var d2H = parseInt(splitTime[0], 10);
var d1T = d1.getMinutes();
var d2T = parseInt(splitTime[1], 10);
var diffInMinutes = (d1T + 59 * d1H + 23) - (d2T + 59 * d2H + 23);
if (diffInMinutes <= 1) return "1 Minute";
else if (diffInMinutes <= 59) return diffInMinutes + " Minutes";
var diffInHours = (d1H + 23 * d1M) - (d2H + 23 * d1M);
if (diffInHours <= 1) return "1 Hour";
else if (diffInHours < 23) return diffInHours + " Hours";
var diffInDays = (d1D + 30 * d1M + 12 * d1Y) - (d2D + 30 * d2M + 12 * d2Y);
if (diffInDays < 7) return diffInDays + " days";
else if (diffInDays > 7 && diffInDays < 14) return "1 week";
else if (diffInDays >= 14 && diffInDays < 30) return Math.floor(diffInDays / 7) + " weeks";
var diffInMonths = (d1M + 12 * d1Y) - (d2M + 12 * d2Y);
if (diffInMonths <= 1) return "1 month";
else if (diffInMonths < 12) return diffInMonths + " months";
var diffInYears = Math.floor(diffInMonths / 12);
if (diffInYears <= 1) return "1 year";
else if (diffInYears < 12) return diffInYears + " years";
}
my new function only returns minutes and other and wont update to change of day
I assume you are fetching the timestamp from a mysql database. This was also answered here. The top answer is in php but it is not really different from Javascript. I do suggest using php for this however.
you can see that your splitting was not correct...
this is working fine..
var splitDate = ((timestamp.toString().split('T'))[0]).split('-');
var splitTime = ((timestamp.toString().split('T'))[1]).split(':');
var splitTime1 = ((splitTime[2].toString().split('Z'))[0]).split('.');
splitDate[0] = Year;
splitDate[1] = Month;
splitDate[2] = Day;
splitTime[0] = Hours;
splitTime[1] = Minutes;
splitTime1[0] = Seconds;
splitTime1[1] = MilliSeconds;
you can now perform what ever you want to..

Convert a number (of days) to days, months and years with jQuery

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/

Categories

Resources