build_timestamp.h (4726B)
1 /* 2 * 3 * Created: 29.03.2018 4 * 5 * Authors: 6 * 7 * Assembled from the code released on Stackoverflow by: 8 * Dennis (instructable.com/member/nqtronix) | https://stackoverflow.com/questions/23032002/c-c-how-to-get-integer-unix-timestamp-of-build-time-not-string 9 * and 10 * Alexis Wilke | https://stackoverflow.com/questions/10538444/do-you-know-of-a-c-macro-to-compute-unix-time-and-date 11 * 12 * Assembled by Jean Rabault 13 * 14 * BUILD_UNIX_TIMESTAMP gives the UNIX timestamp (unsigned long integer of seconds since 1st Jan 1970) of compilation from macros using the compiler defined __TIME__ macro. 15 * This should include Gregorian calendar leap days, in particular the 29ths of February, 100 and 400 years modulo leaps. 16 * 17 * Careful: __TIME__ is the local time of the computer, NOT the UTC time in general! 18 * 19 */ 20 21 #ifndef COMPILE_TIME_H_ 22 #define COMPILE_TIME_H_ 23 24 // Some definitions for calculation 25 #define SEC_PER_MIN 60UL 26 #define SEC_PER_HOUR 3600UL 27 #define SEC_PER_DAY 86400UL 28 #define SEC_PER_YEAR (SEC_PER_DAY*365) 29 30 // extracts 1..4 characters from a string and interprets it as a decimal value 31 #define CONV_STR2DEC_1(str, i) (str[i]>'0'?str[i]-'0':0) 32 #define CONV_STR2DEC_2(str, i) (CONV_STR2DEC_1(str, i)*10 + str[i+1]-'0') 33 #define CONV_STR2DEC_3(str, i) (CONV_STR2DEC_2(str, i)*10 + str[i+2]-'0') 34 #define CONV_STR2DEC_4(str, i) (CONV_STR2DEC_3(str, i)*10 + str[i+3]-'0') 35 36 // Custom "glue logic" to convert the month name to a usable number 37 #define GET_MONTH(str, i) (str[i]=='J' && str[i+1]=='a' && str[i+2]=='n' ? 1 : \ 38 str[i]=='F' && str[i+1]=='e' && str[i+2]=='b' ? 2 : \ 39 str[i]=='M' && str[i+1]=='a' && str[i+2]=='r' ? 3 : \ 40 str[i]=='A' && str[i+1]=='p' && str[i+2]=='r' ? 4 : \ 41 str[i]=='M' && str[i+1]=='a' && str[i+2]=='y' ? 5 : \ 42 str[i]=='J' && str[i+1]=='u' && str[i+2]=='n' ? 6 : \ 43 str[i]=='J' && str[i+1]=='u' && str[i+2]=='l' ? 7 : \ 44 str[i]=='A' && str[i+1]=='u' && str[i+2]=='g' ? 8 : \ 45 str[i]=='S' && str[i+1]=='e' && str[i+2]=='p' ? 9 : \ 46 str[i]=='O' && str[i+1]=='c' && str[i+2]=='t' ? 10 : \ 47 str[i]=='N' && str[i+1]=='o' && str[i+2]=='v' ? 11 : \ 48 str[i]=='D' && str[i+1]=='e' && str[i+2]=='c' ? 12 : 0) 49 50 // extract the information from the time string given by __TIME__ and __DATE__ 51 #define __TIME_SECONDS__ CONV_STR2DEC_2(__TIME__, 6) 52 #define __TIME_MINUTES__ CONV_STR2DEC_2(__TIME__, 3) 53 #define __TIME_HOURS__ CONV_STR2DEC_2(__TIME__, 0) 54 #define __TIME_DAYS__ CONV_STR2DEC_2(__DATE__, 4) 55 #define __TIME_MONTH__ GET_MONTH(__DATE__, 0) 56 #define __TIME_YEARS__ CONV_STR2DEC_4(__DATE__, 7) 57 58 // Days in February 59 #define _UNIX_TIMESTAMP_FDAY(year) \ 60 (((year) % 400) == 0UL ? 29UL : \ 61 (((year) % 100) == 0UL ? 28UL : \ 62 (((year) % 4) == 0UL ? 29UL : \ 63 28UL))) 64 65 // Days in the year 66 #define _UNIX_TIMESTAMP_YDAY(year, month, day) \ 67 ( \ 68 /* January */ day \ 69 /* February */ + (month >= 2 ? 31UL : 0UL) \ 70 /* March */ + (month >= 3 ? _UNIX_TIMESTAMP_FDAY(year) : 0UL) \ 71 /* April */ + (month >= 4 ? 31UL : 0UL) \ 72 /* May */ + (month >= 5 ? 30UL : 0UL) \ 73 /* June */ + (month >= 6 ? 31UL : 0UL) \ 74 /* July */ + (month >= 7 ? 30UL : 0UL) \ 75 /* August */ + (month >= 8 ? 31UL : 0UL) \ 76 /* September */+ (month >= 9 ? 31UL : 0UL) \ 77 /* October */ + (month >= 10 ? 30UL : 0UL) \ 78 /* November */ + (month >= 11 ? 31UL : 0UL) \ 79 /* December */ + (month >= 12 ? 30UL : 0UL) \ 80 ) 81 82 // get the UNIX timestamp from a digits representation 83 #define _UNIX_TIMESTAMP(year, month, day, hour, minute, second) \ 84 ( /* time */ second \ 85 + minute * SEC_PER_MIN \ 86 + hour * SEC_PER_HOUR \ 87 + /* year day (month + day) */ (_UNIX_TIMESTAMP_YDAY(year, month, day) - 1) * SEC_PER_DAY \ 88 + /* year */ (year - 1970UL) * SEC_PER_YEAR \ 89 + ((year - 1969UL) / 4UL) * SEC_PER_DAY \ 90 - ((year - 1901UL) / 100UL) * SEC_PER_DAY \ 91 + ((year - 1601UL) / 400UL) * SEC_PER_DAY \ 92 ) 93 94 // the UNIX timestamp 95 #define BUILD_UNIX_TIMESTAMP (_UNIX_TIMESTAMP(__TIME_YEARS__, __TIME_MONTH__, __TIME_DAYS__, __TIME_HOURS__, __TIME_MINUTES__, __TIME_SECONDS__)) 96 97 #endif