1

I need to write a program that calculates the number of years, months, weeks, days, and hours since January 1st, 1970. The only catch is, the number of months cannot exceed 12, weeks exceed 4, etc...

I have been trying different methods like using the modulus operator, and doing some playing around with total seconds, but the logic is beyond me at this point.
Here's my code

#include <stdio.h>
#include <time.h>

int main() {
    long now = time(NULL);

    long secondsInMinute = 60;
    long secondsInHour = secondsInMinute * 60;
    long secondsInDay = secondsInHour * 24;
    long secondsInWeek = secondsInDay * 7;
    long secondsInMonth = secondsInDay * 30.42;
    long secondsInYear = secondsInMonth * 12;

    long years = now/secondsInYear;
    long months = (now-(years*secondsInYear))/secondsInMonth;
    long weeks = (now-((years*secondsInYear)+(months*secondsInMonth)))/secondsInWeek;
    long days;
    long hours;

    printf("Since Jan 1st, 1970: ");
    printf("\n%ld years have passed!", years);
    printf("\n%ld months have passed!", months);
    printf("\n%ld weeks have passed", weeks);
    printf("\n%ld days have passed", days);
    printf("\n%ld hours have passed", hours);

    return 0;
}

My instructions tell me to assume there are 30.42 days in a month and 365 days in a year.

I was able to get the number of years, but the number of months comes out to 9, which would be incorrect based on a few online calculators that I've looked at. This is mainly a logic issue with me and I can't seem to wrap my head around how I would do this.

An example output would be

30 years, 4 months, 2 weeks, 4 days, 5 hours  

Obviously this isn't the actual amount of time, but just an example for the format my output needs to be in. Any help is appreciated.

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
slinky55
  • 33
  • 6
  • 4
    Hello and welcome. First observation: you instructions are not exact, but most calculators are, so comparing the results to them might not work. Also, your instructions say that there is 365 day in a year, not that there is 12 month in a year. These two will not give the same result. The rest looks ok as far as the logic is concerned but I would witre it in a way that I would have a seconds remaining variable instead, and update that, so that the lines don't get longer and longer. – g_bor Sep 21 '20 at 19:13
  • The reason that you get 9 months instead of 8 is because your year is 365 days, whereas the actual length of a year is roughly 365.25 days on average. If you divide `now` by the seconds in 365.25 days, you'll end up with the same number of years, but a smaller remainder. If you were to divide that smaller remainder by `secondsInMonth`, you *would* get 8 as you expected. In other words, don't worry about the fact that the result doesn't match reality. – user3386109 Sep 21 '20 at 19:41

1 Answers1

1

My instructions tell me to assume there are 30.42 days in a month and 365 days in a year.

Code below is subject floating point inexactitudes. Best to form constants with integer math. Here we also take advantage that the number of seconds in a day is a multiple of 100, so secondsInMonth is exact given "30.42 days in a month".

// long secondsInMonth = secondsInDay * 30.42;
long secondsInMonth = secondsInDay * 3042 / 100;

Given 365 days per year and 30.42 days per month, there are not 12 months per year @g_bor.
Do not use 12 to form the year constant, instead SEC_PER_YEAR (365LL*SEC_PER_DAY)

Let macros be your friend.
To find the total number of seconds in a larger unit like year or month, do not code something like #define SEC_PER_YEAR 31536000, to easy to get wrong and it does not document how code arrived at the magic number. Instead build up the value. Insure the calculation uses wide enough constants. This is close to what OP did.

Assume time() returns the integer count of seconds since Jan 1, 1970 and the usual oddities can be ignored (leap seconds, daylight savings, time zone, epoch, resolution, ...), ...

perform a series of / and %` starting with the largest unit.

#include <stdio.h>
#include <time.h>

#define SEC_PER_MIN 60
#define SEC_PER_HOUR (60*SEC_PER_MIN)
#define SEC_PER_DAY (24L*SEC_PER_HOUR)
#define SEC_PER_WEEK (7L*SEC_PER_DAY)
#define SEC_PER_MONTH (3042LL*SEC_PER_DAY/100)
#define SEC_PER_YEAR (365LL*SEC_PER_DAY)

int main(void) {
  time_t now = time(NULL);
  printf("%s", ctime(&now));
  long long t = now;
  printf("Since Jan 1st, 1970:\n");
  printf("%lld years have passed!\n", t / SEC_PER_YEAR);
  t %= SEC_PER_YEAR;
  printf("%lld months have passed!\n", t / SEC_PER_MONTH);
  t %= SEC_PER_MONTH;
  printf("%lld weeks have passed\n", t / SEC_PER_WEEK);
  t %= SEC_PER_WEEK;
  printf("%lld days have passed\n", t / SEC_PER_DAY);
  t %= SEC_PER_DAY;
  printf("%lld hours have passed\n", t / SEC_PER_HOUR);
  t %= SEC_PER_HOUR;
}

Output

Mon Sep 21 20:40:26 2020  (local time)
Since Jan 1st, 1970:
50 years have passed!
9 months have passed!
0 weeks have passed
3 days have passed
6 hours have passed

"number of months comes out to 9" --> that is about right.

"the number of months cannot exceed 12" --> 365 < 12*30.42 (365.04) so no problem.

"weeks (cannot) exceed 4" --> 30.42 < 5*7 so no problem there either.

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256