5

Is there any simple way to summarize a day value like (1327 days) to the format:

xx years; xx month; xx days

without having to use a separate variable for each value.
Preferably with one command.

  • 2
    Not really. What month are you thinking of? Does it include February? Months can have 28, 29, 30 or 31 days. How can we convert an arbitrary number of days to months? – terdon Sep 25 '17 at 15:15
  • 1
    September of 1752 had 19 days in the US/UK/Canada. Calendars can be weird sometimes. – Kusalananda Sep 25 '17 at 15:43
  • @terdon good point. The sollution I used now is: echo "1324 365" | awk '{printf "%.2f", $1 / $2}' | awk -F'.' '{print $1 " years and " $2 " days"}' – nath Sep 25 '17 at 16:12
  • 1
    Yes, that will work if you don't care about leap years. Although if that's what you want, you may as well do it in one command: echo "1324 365" | awk '{y=sprintf("%.2f", $1 / $2); sub(/\./, " years and ", y); print y,"days"}' – terdon Sep 25 '17 at 16:19
  • 1
    @nath You have to count from a date. The days of the months are to irregular to come up with a generic answer. – Kusalananda Sep 25 '17 at 18:24
9

For a duration that includes a number of months or years, that has to make reference to a particular date, as different months or different years have different lengths.

To know how many years/months/days from now to 1327 days from now, with dateutils:

$ ddiff -f '%Y years, %m months, %d days' today "$(dadd now 1327)"
3 years, 7 months, 19 days

(you may sometimes find ddiff available as datediff or dateutils.ddiff; same for dadd).

That's what I get now on 2017-09-25 (because that's from 2017-09-25 to 2021-05-14). If I were to run that on 2018-03-01, I'd get:

3 years, 7 months, 17 days

because that's from 2018-03-01 to 2021-10-18.

And on that 2018-03-01 day, 1327 days ago would give 3 years, 7 months, 16 days.

More info at How can I calculate and format a date duration using GNU tools, not a result date?

| improve this answer | |
3

I think that's a bit too complicated for a reasonably accurate solution (i. e. regarding calendar oddities like leap days) in Bash. Try something with a programming library for calendars like Python instead:

#!/usr/bin/env python3
import sys, calendar
from datetime import *

difference = timedelta(days=int(sys.argv[1]))
now = datetime.now(timezone.utc).astimezone()
then = now - difference

years = now.year - then.year
months = now.month - then.month
days = now.day - then.day
if days < 0:
    days += calendar.monthrange(then.year, then.month)[1]
    months -= 1
if months < 0:
    months += 12
    years -= 1

print('{} year(s); {} month(s); {} day(s)'.format(years, months, days))

Example invocation:

$ ./human-redable-date-difference.py 1327
3 year(s); 7 month(s); 19 day(s)

Of course you can adjust the input and output format to your liking to select time differences based on other things than the number of days.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.