0

Im trying something like Andris answer in this post: Convert seconds to days, hours, minutes and seconds but i need this in years, month and weeks as well.

im running this

getDateStrings() {
  console.log(req_creation_date);
  const today = new Date();

  const creation_date = new Date('2020-01-06T20:24:00.000Z');

  const creation_date_diff = Math.abs(today.getTime() - creation_date.getTime());
  const creation_date_diffDays = Math.ceil((creation_date_diff / 1000));
  console.log(creation_date_diffDays);
  const creation_date_diffDays_days = Math.ceil((creation_date_diff / (1000 * 3600 * 24)) - 1);
  console.log(creation_date_diffDays_days);
  const y = Math.floor(creation_date_diffDays / (31536000));
  const ms = Math.floor(creation_date_diffDays % (3600 * 24 * 7 * 4.34524 * 12) / 2592000);
  const w = Math.floor(creation_date_diffDays % (3600 * 24 * 7 * 4.34524) /  604800);
  const d = Math.floor(creation_date_diffDays % (3600 * 24 * 7) / 86400);
  const h = Math.floor(creation_date_diffDays % (3600 * 24) / 3600);
  const m = Math.floor(creation_date_diffDays % 3600 / 60);
  const s = Math.floor(creation_date_diffDays % 60);

  const yDisplay = y > 0 ? y + (y === 1 ? ' year, ' : ' years, ') : '';
  const msDisplay = ms > 0 ? ms + (ms === 1 ? ' month, ' : ' months, ') : '';
  const wDisplay = w > 0 ? w + (w === 1 ? ' week, ' : ' weeks, ') : '';
  const dDisplay = d > 0 ? d + (d === 1 ? ' day, ' : ' days, ') : '';
  const hDisplay = h > 0 ? h + (h === 1 ? ' hour, ' : ' hours, ') : '';
  const mDisplay = m > 0 ? m + (m === 1 ? ' minute, ' : ' minutes, ') : '';
  const sDisplay = s > 0 ? s + (s === 1 ? ' second ' : ' seconds') : '' ;
  console.log(yDisplay, msDisplay, wDisplay, dDisplay + hDisplay + mDisplay + sDisplay);
}

60 days have passed since 06-06-2020 until today.

It is returning "2 months, 4 weeks, 4 days, 21 minutes, 10 seconds" what is wrong, should be something like "2 months, 21 minutes, 10 seconds"

I don't know what I'm doing wrong, I'm trying also with January-15-2020. 51 days have passed but it is returning "1 month, 2 weeks, 2 days, 41 minutes, 43 seconds" what is in total 46 days and not 51 as it should be "1 month, 3 weeks, 0 days, 41 minutes, 43 seconds"

thank you very much!

Jun Zhou
  • 1,077
  • 1
  • 6
  • 19
  • 1
    Converting seconds into Months is a problem, since they can be one of {28, 30, 31} days. To get an accurate conversion you will need to account for exactly WHAT months the seconds are being translated over. – BryanOfEarth Mar 06 '20 at 21:28
  • Does this answer your question? [JavaScript year,month,day,hour,minute,second difference](https://stackoverflow.com/questions/16597509/javascript-year-month-day-hour-minute-second-difference) – Heretic Monkey Mar 06 '20 at 22:07
  • @BryanOfEarth It shouldn't be a problem because I don't care if a month has 31 or 28 days, I'm specifying how many days a month (30 days). If the difference between two dates is greater is 7 days. It should not show days, such as 8 days, it should show you somenthing like (1 week and 1 day). – Andres Plaza Marqués Mar 06 '20 at 22:18
  • 1
    Please, please, **please** don't try to roll your own date/time handling code. There are numerous libraries available that can handle this for you, moment.js being one of the better-known ones. – Ian Kemp Mar 06 '20 at 22:26
  • I have struggled all day to solve this, I came here for help and I get a -1 = / ... I'm looking at moment.js but I still haven't found a proper way to read the ISO formats and use the .fromNow () function The posts you suggested don't give me the answer I'm looking for (I already read all of them) – Andres Plaza Marqués Mar 06 '20 at 22:56

1 Answers1

0

I created this sandbox using moment.js. I tried to replicate your code as much as possible. Here is the code:

import "./styles.css";
import moment from "moment";

const getDuration = (startDate, endDate) =>
  moment.duration(moment(endDate).diff(moment(startDate)));

function getDurationText(startDate, endDate) {
  const duration = getDuration(startDate, endDate);
  const years = duration.years();
  const months = duration.months();
  const weeks = duration.weeks();
  const days = duration.subtract(weeks, "w").days();
  const hours = duration.hours();
  const seconds = duration.seconds();
  const milliseconds = duration.milliseconds();

  const yearsText = getDurationTextOrDefault(years, "Year");
  const monthsText = getDurationTextOrDefault(months, "Month");
  const weeksText = getDurationTextOrDefault(weeks, "Week");
  const daysText = getDurationTextOrDefault(days, "Day");
  const hoursText = getDurationTextOrDefault(hours, "Hour");
  const secondsText = getDurationTextOrDefault(seconds, "Second");
  const millisecondsText = getDurationTextOrDefault(
    milliseconds,
    "Millisecond"
  );

  return `${yearsText}${monthsText}${weeksText}${daysText}${hoursText}${secondsText}${millisecondsText}`;
}

function getDurationTextOrDefault(duration, unit) {
  if (duration <= 0) return "";
  unit = duration === 1 ? unit : unit + "s";
  return `${duration} ${unit} `;
}

const start = new Date("2020-01-07T20:24:00.000Z");
const end = new Date();

document.getElementById("app").innerHTML = `
<h1>Duration</h1>
<div>
  ${getDurationText(start, end)}
</div>
`;

Is the output what you expected?

EDIT Substract weeks from days, since moment doesn't do this automatically.

oemera
  • 3,223
  • 1
  • 19
  • 33
  • If I put "const start = new Date (" 2020-01-15T20: 24: 00.000Z ");" returns: ("1 month 2 weeks 20 days 3 hours 39 seconds 897 milliseconds") I think this means "30 days + 14 days + 20 days" and it's wrong because it's only been 52 days until today – Andres Plaza Marqués Mar 07 '20 at 00:13
  • You are absolutely right. Moment doesn't automatically transform overflow of days into weeks. You have to do this manually. I adjusted the code above and the sandbox accordingly. How ever, I would probably only display days and no weeks, if that is an option. It looks more readable to me. – oemera Mar 07 '20 at 08:11