HiveBrain v1.2.0
Get Started
← Back to all entries
patterncppModerate

Calculating epoch seconds

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
calculatingsecondsepoch

Problem

Below I have code that calculates epoch seconds. It is built to try to change run time checks into asserts in order to give performance in production. I want to make sure all the edge cases are correct, though.

```
#define DAYSPERWEEK (7)
#define DAYSPERNORMYEAR (365U)
#define DAYSPERLEAPYEAR (366U)

#define SECSPERDAY (86400UL) / == ( 24 60 60) /
#define SECSPERHOUR (3600UL) / == ( 60 60) */
#define SECSPERMIN (60UL) / == ( 60) /
#define USECPERSEC (1000000UL)
#define USECPERMILLI (1000UL)

#define LEAPYEAR(year) (!((year) % 4) && (((year) % 100) || !((year) % 400)))

inline static uint32_t getSecsSinceEpoch(uint32_t aMonth,
uint32_t aDay,
uint32_t aYear,
uint8_t aHour=0,
uint8_t aMinute=0,
uint8_t aSecond=0) {

const static int leapYearMonthTable[2][12] = {
{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
};

assert(aMonth 1969 && aYear 1) {

Solution

In C++, you should use const instead of macros for constants:

const int DAYS_PER_WEEK = 7;                                                                    
const int DAYS_PER_NORM_YEAR = 365;                                                               
const int DAYS_PER_LEAPYEAR = 366;                                                               

const long int SECS_PER_DAY = 24 * 60 * 60;                               
const long int SECS_PER_HOUR = 60 * 60;
const unsigned long int SECS_PER_MIN = 60;
const unsigned long int USEC_PER_SEC = 1000000;
const unsigned long int USEC_PER_MILLI = 1000;


This will allow you to use explicit types instead of adding type literals. I've also added underscores to the names as that's the proper convention for compound words in all-uppercase macro names. If these are to be reused, then they could also be wrapped in a namespace to prevent any name-clashing.

As for LEAPYEAR, use a function instead:

int getLeapYear(int year)
{
    return !((year) % 4) && (((year) % 100) || !((year) % 400))
}


Overall, this code looks extremely C-like. If you must use macros for whatever reason, then just program this in C. But if you're indeed using C++, and you have C++11, you can even utilize some newer features from the `` library.

Code Snippets

const int DAYS_PER_WEEK = 7;                                                                    
const int DAYS_PER_NORM_YEAR = 365;                                                               
const int DAYS_PER_LEAPYEAR = 366;                                                               

const long int SECS_PER_DAY = 24 * 60 * 60;                               
const long int SECS_PER_HOUR = 60 * 60;
const unsigned long int SECS_PER_MIN = 60;
const unsigned long int USEC_PER_SEC = 1000000;
const unsigned long int USEC_PER_MILLI = 1000;
int getLeapYear(int year)
{
    return !((year) % 4) && (((year) % 100) || !((year) % 400))
}

Context

StackExchange Code Review Q#78652, answer score: 10

Revisions (0)

No revisions yet.