If you have a 64-bit system such as Mac OS X (10.11 El Capitan used), then this works:
#include <inttypes.h>
#include <stdio.h>
#include <time.h>
int main(void)
{
int y1 = 27440;
int m1 = 5;
int d1 = 1;
int y2 = 5660;
int m2 = 1;
int d2 = 24;
struct tm tm1 = { .tm_year = y1 - 1900, .tm_mon = m1 - 1, .tm_mday = d1 };
struct tm tm2 = { .tm_year = y2 - 1900, .tm_mon = m2 - 1, .tm_mday = d2 };
time_t t1 = mktime(&tm1);
time_t t2 = mktime(&tm2);
size_t dt = t1 - t2; // Dodgy assignment…I get away with it, but…
char buffer[128];
strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", &tm1);
printf("t1 = %20s\n", buffer);
strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", &tm2);
printf("t2 = %20s\n", buffer);
printf("t1 = %" PRIdMAX "\n", (intmax_t)t1);
printf("t2 = %" PRIdMAX "\n", (intmax_t)t2);
printf("dt = %zu seconds\n", dt);
printf("dt = %zu hours\n", dt / 3600);
printf("dt = %zu days\n", dt / (24 * 3600));
return 0;
}
The output I get is:
t1 = 27440-05-01 00:00:00
t2 = 5660-01-24 00:00:00
t1 = 803766009600
t2 = 116447184000
dt = 687318825600 seconds
dt = 190921896 hours
dt = 7955079 days
Things are not quite so good trying to go retrospective. Dividing both year values by 10 yields:
t1 = 2744-05-01 00:00:00
t2 = 0566-01-24 00:00:00
t1 = 24435504000
t2 = -1
dt = 24435504001 seconds
dt = 6787640 hours
dt = 282818 days
Note that the -1
indicates an error; the system is not willing to play with dates in the first millennium (which renders the dt
calculations inaccurate). AFAICT, on a Mac, mktime()
does not go further back in time than 32-bit signed values could go — it accepts 1902-01-01 but rejects 1901-01-01. The 32-bit limit is:
-2147483647 = Fri Dec 13 12:45:53 1901 (US/Pacific)
Test code:
static int test_year(int year)
{
struct tm tm1 = { .tm_year = year - 1900, .tm_mon = 0, .tm_mday = 1 };
time_t t1 = mktime(&tm1);
return (t1 != -1);
}
static void early_year(void)
{
int y_lo = 566;
int y_hi = 1902;
assert(test_year(y_lo) == 0);
assert(test_year(y_hi) == 1);
while (y_lo != y_hi)
{
int y_md = (y_lo + y_hi) / 2;
printf("lo = %4d; hi = %4d; md = %4d\n", y_lo, y_hi, y_md);
if (test_year(y_md) == 0)
y_lo = y_md + 1;
else
y_hi = y_md - 1;
}
printf("Valid back to %4d\n", y_lo);
}
Result of calling that code:
lo = 566; hi = 1902; md = 1234
lo = 1235; hi = 1902; md = 1568
lo = 1569; hi = 1902; md = 1735
lo = 1736; hi = 1902; md = 1819
lo = 1820; hi = 1902; md = 1861
lo = 1862; hi = 1902; md = 1882
lo = 1883; hi = 1902; md = 1892
lo = 1893; hi = 1902; md = 1897
lo = 1898; hi = 1902; md = 1900
lo = 1901; hi = 1902; md = 1901
Valid back to 1902
YMMV, as the saying goes; it will depend on the system you're working on. Note that the further back you go in time, the less dependable clocks and calendars become. Ignoring such niceties as 30th February 1712 (in Sweden), you get a wide variety of dates between 1584 and the 20th Century for dates when countries switched from the Julian calendar to the Gregorian calendar (1752 was the switch date for Britain and her colonies, for example). People typically apply the 'proleptic Gregorian' calendar backwards.