Reputation: 4508
I have a variable which represents a date in number of days since Jan 1 1990. Does anybody know how I can do that? I'm working with MCS 8051, so I can't use any scripts, standard library functions or memory allocation (malloc or calloc). Also this is not a homework. Any help will be appreciated.
Upvotes: 4
Views: 2902
Reputation: 19233
I'll give you a tip:
$ date --date 'jan 1 1990' +%s
631148400
This is the 'epoch date' of Jan 1 1990; expressed in seconds since the Unix epoch. Note this only valid for POSIX systems.
Now, that you made it clear that there are no standard library functions available, you'd probably want to use pre-calculated epoch time as a start and add days * 86400
to it.
Sadly, I guess that you will not have integer types large enough to handle that arithmetic. Since:
log(633826800, 2) = approx. 29.23951342
You'd need at least 32-bit type to hold the value of the Unix epoch itself.
For example, if you had a 32-bit uint32_t
type, you could:
uint32_t days_to_epoch_date(int days)
{
uint32_t ret = 631148400L; /* value for Jan 1 1990 */
ret += 86400 * days;
return ret;
}
If you need to use a different epoch or scale, the values will be different but the method will remain the same. Well, as long as the time measure is linear.
The following example is no longer correct with the new information but I'm leaving it in case anyone being able to use the standard library could find it.
For the code to be portable, you'd first want to assemble the epoch date in a struct tm
:
#include <time.h>
time_t epoch_time_to_time_t(unsigned int days_since_epoch)
{
struct tm t = {0};
t.tm_mday = 1;
t.tm_mon = 0; /* Jan */
t.tm_year = 90; /* since 1900 */
t.tm_isdst = -1;
/* ... */
}
Then, as permitted by *7.23.2.3 The mktime
function:
2 […] The original values of the
tm_wday
andtm_yday
components of the structure are ignored, and the original values of the other components are not restricted to the ranges indicated above.
…add the number of days to the struct tm
, and use mktime()
to obtain the final time_t
:
time_t epoch_time_to_time_t(unsigned int days_since_epoch)
{
/* ... */
t.tm_mday += days_since_epoch;
return mktime(&t);
}
Upvotes: 2
Reputation: 43286
There is a book that collects a huge amount of date and time calculation details and algorithms, that is almost certainly worth checking out. It is supported by source code in standard C (probably C89, certainly not newer).
Standard C Date/Time Library: Programming the World's Calendars and Clocks by Lance Latham, CMP, 1998, ISBN 978-0879304966.
If you needed to start from scratch with date arithmetic, this would be a great resource if only because calenders are full of special cases that are easy to miss.
Upvotes: 1