自 1970 年 1 月 1 日以来的年、月、周、日、小时

Years, Months, Weeks, Days, Hours since Jan 1st, 1970

我需要编写一个程序来计算自 1970 年 1 月 1 日以来的年数、月数、周数、天数和小时数。唯一的问题是,月数不能超过 12,周数不能超过 4,等等...

我一直在尝试不同的方法,例如使用模数运算符,并尝试使用总秒数,但此时我无法理解逻辑。
这是我的代码

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

我的说明告诉我假设一个月有 30.42 天,一年有 365 天。

我能够得到年数,但月数是 9,根据我看过的一些在线计算器,这是不正确的。这对我来说主要是一个逻辑问题,我似乎无法理解我将如何做到这一点。

示例输出为

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

显然这不是实际的时间量,而只是我的输出需要采用的格式的示例。感谢任何帮助。

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

下面的代码存在浮点数不精确的问题。最好用整数数学形成常量。在这里,我们还利用一天中的秒数是 100 的倍数,因此 secondsInMonth 是精确的,给定“一个月中的 30.42 天”。

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

鉴于每年有 365 天,每月有 30.42 天,所以每年没有 12 个月
不要使用 12 来构成年份常量,而是 SEC_PER_YEAR (365LL*SEC_PER_DAY)

让宏成为你的朋友。
要在 yearmonth 等较大单位中查找总秒数,请不要编写 #define SEC_PER_YEAR 31536000 之类的代码,这样很容易弄错了,它没有记录代码是如何得出幻数的。而是建立价值。确保计算使用 。这与 OP 所做的很接近。

假设 time() returns 自 1970 年 1 月 1 日以来的整数秒数并且可以忽略通常的异常值(闰秒、夏令时、时区、纪元、分辨率... ), ...

从最大单位开始执行一系列 / 和 %`

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

输出

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

“月数为 9”--> 差不多是这样。

“月数不能超过 12”--> 365 < 12*30.42 (365.04) 所以没问题。

“周(不能)超过 4”--> 30.42 < 5*7 所以也没有问题。