Transform number of days in Years-Months-Days in javascript
Asked Answered
B

3

7

Hi I've been searching for a while now and I cant seem to find the answer to this.

I have to code a function in javascript that takes in a numbers of days in parameter and then transforms it into a more understandable string.

Ex :

function getFormatedStringFromDays(days)
{
var formatedString = "";
//... logic
return formatedString;
}

So getFormatedStringFromDays(183) is returning something like 6 months 3 days.

Bipolar answered 12/6, 2017 at 15:11 Comment(1)
What kind of help do you need from us?Gang
S
9

Supposing that year contains 365 days and month - 30 days the answer could look as follows. Otherwise there should be more input params

function getFormatedStringFromDays(numberOfDays) {
    var years = Math.floor(numberOfDays / 365);
    var months = Math.floor(numberOfDays % 365 / 30);
    var days = Math.floor(numberOfDays % 365 % 30);

    var yearsDisplay = years > 0 ? years + (years == 1 ? " year, " : " years, ") : "";
    var monthsDisplay = months > 0 ? months + (months == 1 ? " month, " : " months, ") : "";
    var daysDisplay = days > 0 ? days + (days == 1 ? " day" : " days") : "";
    return yearsDisplay + monthsDisplay + daysDisplay; 
}

//==== examples ========

console.log(getFormatedStringFromDays(0));
console.log(getFormatedStringFromDays(1));
console.log(getFormatedStringFromDays(31));
console.log(getFormatedStringFromDays(310));
console.log(getFormatedStringFromDays(365));
console.log(getFormatedStringFromDays(3100));

Not the most elegant solution but it should work

Saturated answered 12/6, 2017 at 15:19 Comment(7)
Hey @Sergey Mell thanks for the quick answer. I tried the code and I have an error in the console saying that h is not defined.Bipolar
@Bipolar Are you sure you've checked the last version? I've edited it a couple of times. The last version works - I've checked thisSaturated
Ok, checked the last version and it's working great indeed ! ThanksBipolar
Asking to learn - is there a particular reason Math.floor is used here, or could it be just as easily replaced with Math.round?Inseverable
Math.round would be not correct for sure. Because 550 days for example is not "2 years" and this is not the answer expected as can be seen from the task requirementsSaturated
Several years late, but I thought I make a comment for people coming after me anyway as this was the first google hit for me anyway. The code works great, but it isn't precise enough. A year is 365.242199 days. A month is 30.147 days (common years) and 30.5 on leap-years. A weighted average over a century gives us 30.43692 days. Using these numbers instead gave me the accurate results.Talishatalisman
@SergeyMell Added test example but a comma is always shown at end of some lines.Spake
A
2

Pure js:

function getFormatedStringFromDays(days) {
  days = +days;
  if(Number.isInteger(+days)){
var years = Math.floor(days / 365);
    var year_text = years === 1 ? ' year ' : ' years ';
    days %= 365;
    var months = Math.floor(days / 30);
    var mon_text = months <= 1 ? ' month ' : ' months ';
    var days = days % 30;
    var day_text = days <= 1 ? ' day' : ' days';
    return years + year_text + months + mon_text + days + day_text;
  } else {
    return 'not a number';
  }
}

console.log(getFormatedStringFromDays(1));
console.log(getFormatedStringFromDays(35));
console.log(getFormatedStringFromDays(383));
console.log(getFormatedStringFromDays('abc'));
console.log(getFormatedStringFromDays('11123'));
Adelina answered 12/6, 2017 at 15:24 Comment(2)
@Bipolar Cool. I also added a validation for number in case the input is like abcAdelina
This doesn't provide support for years so doesn't actually answer the question.Inseverable
S
0

You can make use of the Intl.NumberFormat() and the Intl.ListFormat() to format the output in different locales and languages.

The array can be expanded to convert milliseconds or seconds if needed.

The years and months calculations from the days use 365.2425 days in a year which is a very good approximation.

Here is an example:

// formats days duration into years, months, and days
//
function formatDurationDays(days,{locale="en-US",unitDisplay='long', style='long',type='conjunction'}={}) {
let divMod=(v,days)=>[Math.floor(v/days),v%days],v;
return new Intl.ListFormat(locale,{style:style, type:type}).format(
["year","month","day"].map((unit,i)=>{
    [v,days] = i<2 ? divMod(days,[365.2425,30.436875][i]) : [Math.ceil(days)];
    return v?Intl.NumberFormat(locale,{style:'unit', unit, unitDisplay }).format(v):0;
}).filter(v=>v));
}


console.log(formatDurationDays(1200));
console.log(formatDurationDays(370));
console.log(formatDurationDays(21));
console.log(formatDurationDays(1200,{locale:"fr-FR"}));
console.log(formatDurationDays(271,{locale:"ar-QA"}));
Spake answered 25/11, 2023 at 15:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.