Convert number of days left into years, months, days [duplicate] - javascript

This question already has answers here:
Difference between two dates in years, months, days in JavaScript
(34 answers)
How to get difference between 2 Dates in Years, Months and days using moment.js
(3 answers)
How to get the difference of two dates in mm-dd-hh format in Javascript
(3 answers)
Closed 2 years ago.
I am trying to get the difference between two dates (my birthday and the current date to get the time left until my birthday), But I want the output format in ('Year/Months/Days); How can I do that? that's what I've tried so far :
const birthday = new Date ('11-20-2021').getTime();
const today = new Date ().getTime();
const dys = (1000*60*60*24);
const months = (dys*30);
let differance = birthday-today ;
const formatted = Math.round(differance/dys);
console.log(formatted);`
thank you in advance

How do you feel about the modulo operator? :)
This is a common math operation, like finding change or such. Think of it this way, if you have a large number of days, say 397, you can get number of years by doing integer division (1), then you can get the number of days left by doing modulo by a year to get the remainder (in days) 397%365 = 32. Then you can repeat the process to get number of months remaining (1...assuming 30 day month) in that and again, modulo to get the final number of days 2 ...
I'm no javascript pro, but I think you need to use Math.floor(quotient) to get the result of division in integer format.

this example compares between the current date and the date 2100/0/14 try the same concept in the example and i hope it helps:
var today, someday, text;
today = new Date();
someday = new Date();
someday.setFullYear(2100, 0, 14);
if (someday > today) {
text = "Today is before January 14, 2100.";
} else {
text = "Today is after January 14, 2100.";
}
document.getElementById("demo").innerHTML = text;

Working with dates and differences can be difficult because there are a lot of edge cases. which is why I prefer to let a dedicated library handle this, like https://momentjs.com/
moment has a plugin (https://www.npmjs.com/package/moment-precise-range-plugin) which does exactly what you are looking for:
import moment from 'moment';
import 'moment-precise-range-plugin';
var m1 = moment('2014-01-01 12:00:00','YYYY-MM-DD HH:mm:ss');
var m2 = moment('2014-02-03 15:04:05','YYYY-MM-DD HH:mm:ss');
var diff = moment.preciseDiff(m1, m2, true); // {years : 0, months : 1, days : 2, hours : 3, minutes : 4, seconds : 5}
var str = `Years: ${diff.years}, Months: ${diff.months}, Days: ${diff.days} `; // 'Years: 0, Months: 1, Days: 2'

If I got you right, I've done it this way.
Haven't touched your original code, but added a function that calculates the dateTime output of the total days of difference.
const birthday = new Date('11-20-2021').getTime();
const today = new Date().getTime();
const dys = (1000 * 60 * 60 * 24);
const months = (dys * 30);
let totalDayserance = birthday - today;
const formatted = daysToDateTime(totalDayserance / dys);
console.log(formatted);
function daysToDateTime(totalDays) {
var baseVal = '';
var formedValues = [
['Years', 365],
['Months', 30],
['Days', 1]
];
for (var i = 0; i < formedValues.length; i++) {
var valueByGroup = Math.floor(totalDays / formedValues[i][1]); //by months
if (valueByGroup >= 1) {
baseVal += (valueByGroup + formedValues[i][0]) + ', ';
totalDays -= valueByGroup * formedValues[i][1];
}
}
return baseVal;
}

Related

Using Arrays & Map Method to add days to an array of date

I am working on a script in which I am trying to use Arrays & Map Method to add numdays to an array in google Sheets.
The following image is an example of the data
function new_date() {
var ss = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var lastRow = ss.getMaxRows();
var data = ss.getRange(2, 5, lastRow).getValues();
// Logger.log(data)
var newData = data.map(adding_days);
ss.getRange(2, 5, lastRow).setValues(newData);
}
function adding_days(row){
var millis_per_day = 1000 * 60 * 60 * 24;
var days = 7 ;
var date = new Date(row[0]);
var date2 = Utilities.formatDate(date, "GMT+05:30" , "MM-dd-yyyy");
var numdays = days * millis_per_day
return [ date2 + numdays ];
}
When I run the code its only returning the data again in another format, I dont understand why its not being able to add the numdays to the data. I am new to using arrays in app script so I am very confused about whats going wrong here.
Thanks in advance!
Adding years, months, days, hours, minutes, seconds and milliseconds to a date
In this particular case days:
function new_date() {
const ss=SpreadsheetApp.getActive()
const sh=ss.getActiveSheet();
const v=sh.getRange(2,5,sh.getLastRow()-1,1).getValues();
const ndt=v.map(function(r,i){
let dt=new Date(r[0]);
let days=7;
return [new Date(dt.getFullYear(),dt.getMonth(),dt.getDate()+days,dt.getHours(),dt.getMinutes(),dt.getMilliseconds())];
});
sh.getRange(2,5,ndt.length,ndt[0].length).setValues(ndt);
}
The problem with adding in milliseconds to the date value is that it does compensate for special situations like leap years and such. While this requires one very long line it now allows you to add numbers of days and hours and such directly to the date with simple integer math by adding it to the appropriate section of the date constructor.
Date Constructor

Get date of exactly 6 days ago from today in JS [duplicate]

This question already has answers here:
How to subtract days from a plain Date?
(36 answers)
Closed 3 years ago.
Thank you in advance
I would like your help with getting 'days ago' from a particular date. I don't want to use any library.
Although I have tried moment JS.
Use getDate() and subtract the number of days from it
var d = new Date();
d.setDate(d.getDate() - 6);
console.log(d);
First, make a new Date with your date:
const date = new Date('December 17, 1995 03:24:00');
Second, subtract 6 days like so:
date.setDate(date.getDate() - 6);
Third, use date.toString() :
console.log(date.toString());
You question title and description contradict with each other.
The following function that return number of days ago can help if this is what you need:
function getDaysAgo(date, now = new Date()) {
//first calculating start of the day
const start = now.setHours(0, 0, 0, 0);
//then calculating difference in miliseconds
const diff = start - date.getTime();
//finally rounding to a bigger whole days
const result = Math.ceil(diff/(1000*60*60*24));
//as a bonus returning today/yesterday/future when necessary
if (result < 0) {
return 'in future';
}
if (result === 0) {
return 'today';
}
return result === 1 ? 'yesterday' : result + ' days ago';
}
For example getDaysAgo(new Date(Date.parse('2019-9-28 23:59')), new Date(Date.parse('2019-9-30 10:59'))) returns 2 days ago.
It is a simple function that returns a new desire past date.
function getNthDate(nthDate){
let date = new Date();
return new Date(date.setDate(date.getDate() - nthDate))
}
Live example

MomentJs get "time until" with two variables

I am trying to get moment.js to show me time until a specific date. I have that done doing this:
let date = 2017-03-27T12:00:00;
moment().to(date);
This shows: "in 10 days".
I'd really like this to show "in 10 days and 2 hours" or the two highest values. For example, 1 year and 5 months, 4 minutes and 30 seconds.
Is there a simple way to do this? I am currently working on a complicated method to handle this...
let years = moment(date).local().diff(moment(), 'years');
let months = (moment(date).local().diff(moment(), 'months'));
let days = (moment(date).local().diff(moment(), 'days'));
let hours = (moment(date).local().diff(moment(), 'hours'));
let minutes = (moment(date).local().diff(moment(), 'minutes'));
let seconds = (moment(date).local().diff(moment(), 'seconds'));
//The above values return total number each,
//For example, this could show 1 year, 14 months, 435 days, etc.
//The math below is supposed to make this say
//1 year, 2 months, 14 days, etc.
let yearsRemain = years;
let monthsRemain = months - (years *12);
let daysRemain = days - (Math.floor(months * 30));
let hoursRemain = hours - (days * 24);
let minutesRemain = minutes - (hours * 60);
let secondsRemain = seconds - (minutes * 60);
var dateArray = [
yearsRemain,
monthsRemain,
daysRemain,
hoursRemain,
minutesRemain,
secondsRemain
]
console.log(dateArray);
/*
returns [1, 1, 3, 23, 16, 46] for example
*/
the problem with this is when it comes to days. Since days in a year and days in a month vary, I was hoping moment.js would help me out. Is there a better way of doing this?
Eventually, I will be able to iterate through the array and find the two largest values to display how I'd like.
You can use moment.duration to calculate the dateArray value. Duration has years(), months(), days(), hours(), minutes(), seconds() getters.
Here a live example:
let date = '2017-03-27T12:00:00';
var dur = moment.duration( moment(date).diff(moment()) );
let yearsRemain = dur.years();
let monthsRemain = dur.months();
let daysRemain = dur.days();
let hoursRemain = dur.hours();
let minutesRemain = dur.minutes();
let secondsRemain = dur.seconds();
var dateArray = [
yearsRemain,
monthsRemain,
daysRemain,
hoursRemain,
minutesRemain,
secondsRemain
]
console.log(dateArray);
<script src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.17.1/moment.min.js"></script>
You can use moment-duration-format plug-in to show duration in a custom format. The plugin has a template option that lets you customize the format.
let date = '2017-03-27T12:00:00';
let dur = moment.duration( moment(date).diff(moment()) );
console.log( dur.format() );
console.log( dur.format('M [months and] d [days]') );
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.17.1/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-duration-format/1.3.0/moment-duration-format.min.js"></script>
Note that moments has relativeTime, relativeTimeRounding and relativeTimeThreshold that lets you customize how moment shows relative time (so you can change to output).

Need to calculate months between two dates in JQuery

I need to count total no of months between the two dates in months and years if not just months either any php snippet or ether js or jquery.
I display the data from backend using php tags {{ $job->job_start_date }} job_start_date is for start date and {{ $job->job_expiry_date }}) job_expiry_date is for end date.
I get my output as in this format 13-Oct-2016.
I tried this thing putting the values as hidden but couldn't get it work with parsing properly while adding new Date() to them
$(document).ready(function(){
var sDate = $("#monthStart").val();
var nDate = $("#monthEnd").val();
var sd = new Date(sDate );
var ed = new Date(nDate );
ed.setDate(ed.getDate() - sd.getDate());
alert(monthDiff(sd,ed));
});
function monthDiff(d1, d2) {
var months;
months = (d2.getFullYear() - d1.getFullYear()) * 12;
months -= d1.getMonth() + 1;
months += d2.getMonth();
return months <= 0 ? 0 : months;
}
need a easy solution in js jquery or php.
function MonthDiff(date1, date2) {
var Nomonths;
Nomonths= (date2.getFullYear() - date1.getFullYear()) * 12;
Nomonths-= date1.getMonth() + 1;
Nomonths+= date2.getMonth() +1; // we should add + 1 to get correct month number
return Nomonths <= 0 ? 0 : Nomonths;
}
function differenceInMonths($startDate, $endDate)
{
$date1 = new DateTime($startDate);
$date2 = new DateTime($endDate);
$interval = date_diff($date1, $date2);
return $interval->m + ($interval->y * 12) . ' months';
}
This way you get no. of months. Now you can calculate years if months >= 11.
Well in this case you can take advantage of moment.js library.
Assuming you have Date String in format like "1-Sept-2016" then we need to convert it to date and then apply moment. If you already have Date then you can directly apply the moment.
Demo :
var startDate = new Date('01-Sept-2016' );
var endDate = new Date('30-Oct-2016' );
var endMoment = moment(endDate);
var startMoment = moment(startDate);
//[days, years, months, seconds, ...]
console.log(endMoment.diff(startMoment, 'months'));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.15.1/moment.js"></script>
You can even specify the difference you want like days, months,years, seconds as specified above.
Reference : http://momentjs.com/
Here is a php solution:
$noMonth = 1 + (date('Y',strtotime($job->job_expiry_date)) - date('Y',strtotime($job->job_start_date))) * 12 + (date('m',strtotime($job->job_expiry_date)) - date('m',strtotime($job->job_start_date)))
The first part calculates the difference in years, multiplied by 12 results the number of month:
1 + (date('Y',strtotime($job->job_expiry_date)) -
date('Y',strtotime($job->job_start_date))) * 12
The second part calculates the number of months to be added or subtracted, as if the dates were in the same year:
(date('m',strtotime($job->job_expiry_date)) -
date('m',strtotime($job->job_start_date)))

How to get difference between 2 Dates in Years, Months and days using moment.js

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";
}

Categories