snippetcModerate
Convert between date/time and time-stamp without using standard library routines
Viewed 0 times
withoutconverttimedatestandardbetweenstampusinglibraryroutines
Problem
I am trying to implement two simple convertors: date/time to time-stamp and vice-versa, without any dependencies on time library routines (such as
I have the following date/time structure:
I would like to have a second opinion on the following conversion routines (given a legal input):
```
static unsigned short days[4][12] =
{
{ 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335},
{ 366, 397, 425, 456, 486, 517, 547, 578, 609, 639, 670, 700},
{ 731, 762, 790, 821, 851, 882, 912, 943, 974,1004,1035,1065},
{1096,1127,1155,1186,1216,1247,1277,1308,1339,1369,1400,1430},
};
unsigned int date_time_to_epoch(date_time_t* date_time)
{
unsigned int second = date_time->second; // 0-59
unsigned int minute = date_time->minute; // 0-59
unsigned int hour = date_time->hour; // 0-23
unsigned int day = date_time->day-1; // 0-30
unsigned int month = date_time->month-1; // 0-11
unsigned int year = date_time->year; // 0-99
return (((year/4(3654+1)+days[year%4][month]+day)24+hour)60+minute)*60+second;
}
void epoch_to_date_time(date_time_t* date_time,unsigned int epoch)
{
date_time->second = epoch%60; epoch /= 60;
date_time->minute = epoch%60; epoch /= 60;
date_time->hour = epoch%24; epoch /= 24;
unsigned int years = epoch/(3654+1)4; epoch %= 365*4+1;
unsigned int year;
for (year=3; year>0; year--)
{
if (epoch >= days[year][0])
break;
}
unsigned int month;
for (month=11; month>0; month--)
{
if (epoch >= days[year][month])
break;
}
date_time->year = years+yea
localtime, mktime, etc, mainly due to the fact that some of them are not thread-safe).I have the following date/time structure:
typedef struct
{
unsigned char second; // 0-59
unsigned char minute; // 0-59
unsigned char hour; // 0-23
unsigned char day; // 1-31
unsigned char month; // 1-12
unsigned char year; // 0-99 (representing 2000-2099)
}
date_time_t;I would like to have a second opinion on the following conversion routines (given a legal input):
```
static unsigned short days[4][12] =
{
{ 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335},
{ 366, 397, 425, 456, 486, 517, 547, 578, 609, 639, 670, 700},
{ 731, 762, 790, 821, 851, 882, 912, 943, 974,1004,1035,1065},
{1096,1127,1155,1186,1216,1247,1277,1308,1339,1369,1400,1430},
};
unsigned int date_time_to_epoch(date_time_t* date_time)
{
unsigned int second = date_time->second; // 0-59
unsigned int minute = date_time->minute; // 0-59
unsigned int hour = date_time->hour; // 0-23
unsigned int day = date_time->day-1; // 0-30
unsigned int month = date_time->month-1; // 0-11
unsigned int year = date_time->year; // 0-99
return (((year/4(3654+1)+days[year%4][month]+day)24+hour)60+minute)*60+second;
}
void epoch_to_date_time(date_time_t* date_time,unsigned int epoch)
{
date_time->second = epoch%60; epoch /= 60;
date_time->minute = epoch%60; epoch /= 60;
date_time->hour = epoch%24; epoch /= 24;
unsigned int years = epoch/(3654+1)4; epoch %= 365*4+1;
unsigned int year;
for (year=3; year>0; year--)
{
if (epoch >= days[year][0])
break;
}
unsigned int month;
for (month=11; month>0; month--)
{
if (epoch >= days[year][month])
break;
}
date_time->year = years+yea
Solution
-
Good that OP is using 4 simplifications: year 2000-2099, no DST, no leap second, no timezone. So OP knows of code limitations concerning these. Various elements of this function break without those givens.
-
Make
-
Use a
as
-
For various functions, consider adding
-
There exist equation based (non-loop) solutions to the year-day that do not need a table like your
-
Most of the magic numbers like 60, 24 are so well-known that constant or macro substitution seems superfluous. But
Good that OP is using 4 simplifications: year 2000-2099, no DST, no leap second, no timezone. So OP knows of code limitations concerning these. Various elements of this function break without those givens.
-
Make
static unsigned short days a const.-
Use a
long for your epoch as in:void epoch_to_date_time(date_time_t* date_time,unsigned long epoch)as
unsigned is only guaranteed to range form 0 to at least 65535 which is insufficient here.-
For various functions, consider adding
const. There are pros and cons to this, but may be beneficial in your case:// unsigned int date_time_to_epoch(date_time_t* date_time)
unsigned int date_time_to_epoch(const date_time_t* date_time)-
There exist equation based (non-loop) solutions to the year-day that do not need a table like your
unsigned short days[4][12]. Code then looks more complicated, but is faster. Please advise if interested.-
Most of the magic numbers like 60, 24 are so well-known that constant or macro substitution seems superfluous. But
(365*4+1) may benefit with something like "DaysPer4Years".Code Snippets
void epoch_to_date_time(date_time_t* date_time,unsigned long epoch)// unsigned int date_time_to_epoch(date_time_t* date_time)
unsigned int date_time_to_epoch(const date_time_t* date_time)Context
StackExchange Code Review Q#38275, answer score: 13
Revisions (0)
No revisions yet.