#include <stdio.h>
#include <string.h>
#include <time.h>
typedef unsigned uint;
typedef unsigned long long uint64 ;
struct tm* SecondsSinceEpochToDateTime( struct tm* pTm, uint64 SecondsSinceEpoch)
{
uint64 sec;
uint quadricentennials, centennials, quadrennials, annuals/*1-ennial?*/ ;
uint year, leap;
uint yday, hour, min;
uint month, mday, wday;
static const uint daysSinceJan1st[ 2 ] [ 13 ] =
{
{ 0 , 31 , 59 , 90 , 120 , 151 , 181 , 212 , 243 , 273 , 304 , 334 , 365 } , // 365 days, non-leap
{ 0 , 31 , 60 , 91 , 121 , 152 , 182 , 213 , 244 , 274 , 305 , 335 , 366 } // 366 days, leap
} ;
/*
400 years:
1st hundred, starting immediately after a leap year that's a multiple of 400:
n n n l \
n n n l } 24 times
... /
n n n l /
n n n n
2nd hundred:
n n n l \
n n n l } 24 times
... /
n n n l /
n n n n
3rd hundred:
n n n l \
n n n l } 24 times
... /
n n n l /
n n n n
4th hundred:
n n n l \
n n n l } 24 times
... /
n n n l /
n n n L <- 97'th leap year every 400 years
*/
// Re-bias from 1970 to 1601:
// 1970 - 1601 = 369 = 3*100 + 17*4 + 1 years (incl. 89 leap days) =
// (3*100*(365+24/100) + 17*4*(365+1/4) + 1*365)*24*3600 seconds
sec = SecondsSinceEpoch + 11644473600 ;
wday = ( uint) ( ( sec / 86400 + 1 ) % 7 ) ; // day of week
// Remove multiples of 400 years (incl. 97 leap days)
quadricentennials = ( uint) ( sec / 12622780800ULL) ; // 400*365.2425*24*3600
sec %= 12622780800ULL;
// Remove multiples of 100 years (incl. 24 leap days), can't be more than 3
// (because multiples of 4*100=400 years (incl. leap days) have been removed)
centennials = ( uint) ( sec / 3155673600ULL) ; // 100*(365+24/100)*24*3600
if ( centennials > 3 )
{
centennials = 3 ;
}
sec -= centennials * 3155673600ULL;
// Remove multiples of 4 years (incl. 1 leap day), can't be more than 24
// (because multiples of 25*4=100 years (incl. leap days) have been removed)
quadrennials = ( uint) ( sec / 126230400 ) ; // 4*(365+1/4)*24*3600
if ( quadrennials > 24 )
{
quadrennials = 24 ;
}
sec -= quadrennials * 126230400ULL;
// Remove multiples of years (incl. 0 leap days), can't be more than 3
// (because multiples of 4 years (incl. leap days) have been removed)
annuals = ( uint) ( sec / 31536000 ) ; // 365*24*3600
if ( annuals > 3 )
{
annuals = 3 ;
}
sec -= annuals * 31536000ULL;
// Calculate the year and find out if it's leap
year = 1601 + quadricentennials * 400 + centennials * 100 + quadrennials * 4 + annuals;
leap = ! ( year % 4 ) && ( year % 100 || ! ( year % 400 ) ) ;
// Calculate the day of the year and the time
yday = sec / 86400 ;
sec %= 86400 ;
hour = sec / 3600 ;
sec %= 3600 ;
min = sec / 60 ;
sec %= 60 ;
// Calculate the month
for ( mday = month = 1 ; month < 13 ; month++ )
{
if ( yday < daysSinceJan1st[ leap] [ month] )
{
mday += yday - daysSinceJan1st[ leap] [ month - 1 ] ;
break ;
}
}
// Fill in C's "struct tm"
pTm-> tm_sec = sec; // [0,59]
pTm-> tm_min = min; // [0,59]
pTm-> tm_hour = hour; // [0,23]
pTm-> tm_mday = mday; // [1,31] (day of month)
pTm-> tm_mon = month - 1 ; // [0,11] (month)
pTm-> tm_year = year - 1900 ; // 70+ (year since 1900)
pTm-> tm_wday = wday; // [0,6] (day since Sunday AKA day of week)
pTm-> tm_yday = yday; // [0,365] (day since January 1st AKA day of year)
pTm-> tm_isdst = - 1 ; // daylight saving time flag
return pTm;
}
int main( void )
{
struct tm t;
time_t tt;
printf ( "%s" , asctime ( SecondsSinceEpochToDateTime
( & t
, 946684799 ) ) ) ; printf ( "%s" , asctime ( SecondsSinceEpochToDateTime
( & t
, 946684799 + 1 ) ) ) ; printf ( "%s\n " , asctime ( SecondsSinceEpochToDateTime
( & t
, 946684799 + 2 ) ) ) ;
printf ( "%s" , asctime ( SecondsSinceEpochToDateTime
( & t
, 978307199 ) ) ) ; printf ( "%s" , asctime ( SecondsSinceEpochToDateTime
( & t
, 978307199 + 1 ) ) ) ; printf ( "%s\n " , asctime ( SecondsSinceEpochToDateTime
( & t
, 978307199 + 2 ) ) ) ;
return 0 ;
}
I2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPHRpbWUuaD4KCnR5cGVkZWYgdW5zaWduZWQgdWludDsKdHlwZWRlZiB1bnNpZ25lZCBsb25nIGxvbmcgdWludDY0OwoKc3RydWN0IHRtKiBTZWNvbmRzU2luY2VFcG9jaFRvRGF0ZVRpbWUoc3RydWN0IHRtKiBwVG0sIHVpbnQ2NCBTZWNvbmRzU2luY2VFcG9jaCkKewogIHVpbnQ2NCBzZWM7CiAgdWludCBxdWFkcmljZW50ZW5uaWFscywgY2VudGVubmlhbHMsIHF1YWRyZW5uaWFscywgYW5udWFscy8qMS1lbm5pYWw/Ki87CiAgdWludCB5ZWFyLCBsZWFwOwogIHVpbnQgeWRheSwgaG91ciwgbWluOwogIHVpbnQgbW9udGgsIG1kYXksIHdkYXk7CiAgc3RhdGljIGNvbnN0IHVpbnQgZGF5c1NpbmNlSmFuMXN0WzJdWzEzXT0KICB7CiAgICB7MCwzMSw1OSw5MCwxMjAsMTUxLDE4MSwyMTIsMjQzLDI3MywzMDQsMzM0LDM2NX0sIC8vIDM2NSBkYXlzLCBub24tbGVhcAogICAgezAsMzEsNjAsOTEsMTIxLDE1MiwxODIsMjEzLDI0NCwyNzQsMzA1LDMzNSwzNjZ9ICAvLyAzNjYgZGF5cywgbGVhcAogIH07Ci8qCiAgNDAwIHllYXJzOgoKICAxc3QgaHVuZHJlZCwgc3RhcnRpbmcgaW1tZWRpYXRlbHkgYWZ0ZXIgYSBsZWFwIHllYXIgdGhhdCdzIGEgbXVsdGlwbGUgb2YgNDAwOgogIG4gbiBuIGwgIFwKICBuIG4gbiBsICAgfSAyNCB0aW1lcwogIC4uLiAgICAgIC8KICBuIG4gbiBsIC8KICBuIG4gbiBuCgogIDJuZCBodW5kcmVkOgogIG4gbiBuIGwgIFwKICBuIG4gbiBsICAgfSAyNCB0aW1lcwogIC4uLiAgICAgIC8KICBuIG4gbiBsIC8KICBuIG4gbiBuCgogIDNyZCBodW5kcmVkOgogIG4gbiBuIGwgIFwKICBuIG4gbiBsICAgfSAyNCB0aW1lcwogIC4uLiAgICAgIC8KICBuIG4gbiBsIC8KICBuIG4gbiBuCgogIDR0aCBodW5kcmVkOgogIG4gbiBuIGwgIFwKICBuIG4gbiBsICAgfSAyNCB0aW1lcwogIC4uLiAgICAgIC8KICBuIG4gbiBsIC8KICBuIG4gbiBMIDwtIDk3J3RoIGxlYXAgeWVhciBldmVyeSA0MDAgeWVhcnMKKi8KCiAgLy8gUmUtYmlhcyBmcm9tIDE5NzAgdG8gMTYwMToKICAvLyAxOTcwIC0gMTYwMSA9IDM2OSA9IDMqMTAwICsgMTcqNCArIDEgeWVhcnMgKGluY2wuIDg5IGxlYXAgZGF5cykgPQogIC8vICgzKjEwMCooMzY1KzI0LzEwMCkgKyAxNyo0KigzNjUrMS80KSArIDEqMzY1KSoyNCozNjAwIHNlY29uZHMKICBzZWMgPSBTZWNvbmRzU2luY2VFcG9jaCArIDExNjQ0NDczNjAwOwoKICB3ZGF5ID0gKHVpbnQpKChzZWMgLyA4NjQwMCArIDEpICUgNyk7IC8vIGRheSBvZiB3ZWVrCgogIC8vIFJlbW92ZSBtdWx0aXBsZXMgb2YgNDAwIHllYXJzIChpbmNsLiA5NyBsZWFwIGRheXMpCiAgcXVhZHJpY2VudGVubmlhbHMgPSAodWludCkoc2VjIC8gMTI2MjI3ODA4MDBVTEwpOyAvLyA0MDAqMzY1LjI0MjUqMjQqMzYwMAogIHNlYyAlPSAxMjYyMjc4MDgwMFVMTDsKCiAgLy8gUmVtb3ZlIG11bHRpcGxlcyBvZiAxMDAgeWVhcnMgKGluY2wuIDI0IGxlYXAgZGF5cyksIGNhbid0IGJlIG1vcmUgdGhhbiAzCiAgLy8gKGJlY2F1c2UgbXVsdGlwbGVzIG9mIDQqMTAwPTQwMCB5ZWFycyAoaW5jbC4gbGVhcCBkYXlzKSBoYXZlIGJlZW4gcmVtb3ZlZCkKICBjZW50ZW5uaWFscyA9ICh1aW50KShzZWMgLyAzMTU1NjczNjAwVUxMKTsgLy8gMTAwKigzNjUrMjQvMTAwKSoyNCozNjAwCiAgaWYgKGNlbnRlbm5pYWxzID4gMykKICB7CiAgICBjZW50ZW5uaWFscyA9IDM7CiAgfQogIHNlYyAtPSBjZW50ZW5uaWFscyAqIDMxNTU2NzM2MDBVTEw7CgogIC8vIFJlbW92ZSBtdWx0aXBsZXMgb2YgNCB5ZWFycyAoaW5jbC4gMSBsZWFwIGRheSksIGNhbid0IGJlIG1vcmUgdGhhbiAyNAogIC8vIChiZWNhdXNlIG11bHRpcGxlcyBvZiAyNSo0PTEwMCB5ZWFycyAoaW5jbC4gbGVhcCBkYXlzKSBoYXZlIGJlZW4gcmVtb3ZlZCkKICBxdWFkcmVubmlhbHMgPSAodWludCkoc2VjIC8gMTI2MjMwNDAwKTsgLy8gNCooMzY1KzEvNCkqMjQqMzYwMAogIGlmIChxdWFkcmVubmlhbHMgPiAyNCkKICB7CiAgICBxdWFkcmVubmlhbHMgPSAyNDsKICB9CiAgc2VjIC09IHF1YWRyZW5uaWFscyAqIDEyNjIzMDQwMFVMTDsKCiAgLy8gUmVtb3ZlIG11bHRpcGxlcyBvZiB5ZWFycyAoaW5jbC4gMCBsZWFwIGRheXMpLCBjYW4ndCBiZSBtb3JlIHRoYW4gMwogIC8vIChiZWNhdXNlIG11bHRpcGxlcyBvZiA0IHllYXJzIChpbmNsLiBsZWFwIGRheXMpIGhhdmUgYmVlbiByZW1vdmVkKQogIGFubnVhbHMgPSAodWludCkoc2VjIC8gMzE1MzYwMDApOyAvLyAzNjUqMjQqMzYwMAogIGlmIChhbm51YWxzID4gMykKICB7CiAgICBhbm51YWxzID0gMzsKICB9CiAgc2VjIC09IGFubnVhbHMgKiAzMTUzNjAwMFVMTDsKCiAgLy8gQ2FsY3VsYXRlIHRoZSB5ZWFyIGFuZCBmaW5kIG91dCBpZiBpdCdzIGxlYXAKICB5ZWFyID0gMTYwMSArIHF1YWRyaWNlbnRlbm5pYWxzICogNDAwICsgY2VudGVubmlhbHMgKiAxMDAgKyBxdWFkcmVubmlhbHMgKiA0ICsgYW5udWFsczsKICBsZWFwID0gISh5ZWFyICUgNCkgJiYgKHllYXIgJSAxMDAgfHwgISh5ZWFyICUgNDAwKSk7CgogIC8vIENhbGN1bGF0ZSB0aGUgZGF5IG9mIHRoZSB5ZWFyIGFuZCB0aGUgdGltZQogIHlkYXkgPSBzZWMgLyA4NjQwMDsKICBzZWMgJT0gODY0MDA7CiAgaG91ciA9IHNlYyAvIDM2MDA7CiAgc2VjICU9IDM2MDA7CiAgbWluID0gc2VjIC8gNjA7CiAgc2VjICU9IDYwOwoKICAvLyBDYWxjdWxhdGUgdGhlIG1vbnRoCiAgZm9yIChtZGF5ID0gbW9udGggPSAxOyBtb250aCA8IDEzOyBtb250aCsrKQogIHsKICAgIGlmICh5ZGF5IDwgZGF5c1NpbmNlSmFuMXN0W2xlYXBdW21vbnRoXSkKICAgIHsKICAgICAgbWRheSArPSB5ZGF5IC0gZGF5c1NpbmNlSmFuMXN0W2xlYXBdW21vbnRoIC0gMV07CiAgICAgIGJyZWFrOwogICAgfQogIH0KCiAgLy8gRmlsbCBpbiBDJ3MgInN0cnVjdCB0bSIKICBtZW1zZXQocFRtLCAwLCBzaXplb2YoKnBUbSkpOwogIHBUbS0+dG1fc2VjID0gc2VjOyAgICAgICAgICAvLyBbMCw1OV0KICBwVG0tPnRtX21pbiA9IG1pbjsgICAgICAgICAgLy8gWzAsNTldCiAgcFRtLT50bV9ob3VyID0gaG91cjsgICAgICAgIC8vIFswLDIzXQogIHBUbS0+dG1fbWRheSA9IG1kYXk7ICAgICAgICAvLyBbMSwzMV0gIChkYXkgb2YgbW9udGgpCiAgcFRtLT50bV9tb24gPSBtb250aCAtIDE7ICAgIC8vIFswLDExXSAgKG1vbnRoKQogIHBUbS0+dG1feWVhciA9IHllYXIgLSAxOTAwOyAvLyA3MCsgICAgICh5ZWFyIHNpbmNlIDE5MDApCiAgcFRtLT50bV93ZGF5ID0gd2RheTsgICAgICAgIC8vIFswLDZdICAgKGRheSBzaW5jZSBTdW5kYXkgQUtBIGRheSBvZiB3ZWVrKQogIHBUbS0+dG1feWRheSA9IHlkYXk7ICAgICAgICAvLyBbMCwzNjVdIChkYXkgc2luY2UgSmFudWFyeSAxc3QgQUtBIGRheSBvZiB5ZWFyKQogIHBUbS0+dG1faXNkc3QgPSAtMTsgICAgICAgICAvLyBkYXlsaWdodCBzYXZpbmcgdGltZSBmbGFnCgogIHJldHVybiBwVG07Cn0KCmludCBtYWluKHZvaWQpCnsKICBzdHJ1Y3QgdG0gdDsKICB0aW1lX3QgdHQ7CiAgcHJpbnRmKCIlcyIsICAgYXNjdGltZShTZWNvbmRzU2luY2VFcG9jaFRvRGF0ZVRpbWUoJnQsIC0xKSkpOwogIHByaW50ZigiJXMiLCAgIGFzY3RpbWUoZ210aW1lKCh0dCA9IDAsICZ0dCkpKSk7CiAgcHJpbnRmKCIlcyIsICAgYXNjdGltZShTZWNvbmRzU2luY2VFcG9jaFRvRGF0ZVRpbWUoJnQsIDApKSk7CiAgcHJpbnRmKCIlc1xuIiwgYXNjdGltZShTZWNvbmRzU2luY2VFcG9jaFRvRGF0ZVRpbWUoJnQsIDEpKSk7CgogIHByaW50ZigiJXMiLCAgIGFzY3RpbWUoU2Vjb25kc1NpbmNlRXBvY2hUb0RhdGVUaW1lKCZ0LCA5NDY2ODQ3OTkpKSk7CiAgcHJpbnRmKCIlcyIsICAgYXNjdGltZShTZWNvbmRzU2luY2VFcG9jaFRvRGF0ZVRpbWUoJnQsIDk0NjY4NDc5OSsxKSkpOwogIHByaW50ZigiJXNcbiIsIGFzY3RpbWUoU2Vjb25kc1NpbmNlRXBvY2hUb0RhdGVUaW1lKCZ0LCA5NDY2ODQ3OTkrMikpKTsKCiAgcHJpbnRmKCIlcyIsICAgYXNjdGltZShTZWNvbmRzU2luY2VFcG9jaFRvRGF0ZVRpbWUoJnQsIDk3ODMwNzE5OSkpKTsKICBwcmludGYoIiVzIiwgICBhc2N0aW1lKFNlY29uZHNTaW5jZUVwb2NoVG9EYXRlVGltZSgmdCwgOTc4MzA3MTk5KzEpKSk7CiAgcHJpbnRmKCIlc1xuIiwgYXNjdGltZShTZWNvbmRzU2luY2VFcG9jaFRvRGF0ZVRpbWUoJnQsIDk3ODMwNzE5OSsyKSkpOwoKICBwcmludGYoIiVzIiwgICBhc2N0aW1lKFNlY29uZHNTaW5jZUVwb2NoVG9EYXRlVGltZSgmdCwgdHQgPSB0aW1lKDApKSkpOwogIHByaW50ZigiJXMiLCAgIGFzY3RpbWUoZ210aW1lKCZ0dCkpKTsKICByZXR1cm4gMDsKfQo=