partially implemented qse_gmtime()

- still need to enhance to support msec in the broken-down time
This commit is contained in:
hyung-hwan 2008-12-22 08:31:30 +00:00
parent 7fe07c5ca4
commit 311e3bf4e7
3 changed files with 101 additions and 51 deletions

View File

@ -8,30 +8,32 @@
#include <qse/types.h> #include <qse/types.h>
#include <qse/macros.h> #include <qse/macros.h>
#define QSE_EPOCH_YEAR ((qse_ntime_t)1970) #define QSE_EPOCH_YEAR (1970)
#define QSE_EPOCH_MON ((qse_ntime_t)1) #define QSE_EPOCH_MON (1)
#define QSE_EPOCH_DAY ((qse_ntime_t)1) #define QSE_EPOCH_DAY (1)
#define QSE_EPOCH_WDAY ((qse_ntime_t)4) #define QSE_EPOCH_WDAY (4)
#define QSE_DAY_IN_WEEK ((qse_ntime_t)7) #define QSE_BTIME_YEAR_BASE (1900)
#define QSE_MON_IN_YEAR ((qse_ntime_t)12)
#define QSE_HOUR_IN_DAY ((qse_ntime_t)24)
#define QSE_MIN_IN_HOUR ((qse_ntime_t)60)
#define QSE_MIN_IN_DAY (QSE_MIN_IN_HOUR * QSE_HOUR_IN_DAY)
#define QSE_SEC_IN_MIN ((qse_ntime_t)60)
#define QSE_SEC_IN_HOUR (QSE_SEC_IN_MIN * QSE_MIN_IN_HOUR)
#define QSE_SEC_IN_DAY (QSE_SEC_IN_MIN * QSE_MIN_IN_DAY)
#define QSE_MSEC_IN_SEC ((qse_ntime_t)1000)
#define QSE_MSEC_IN_MIN (QSE_MSEC_IN_SEC * QSE_SEC_IN_MIN)
#define QSE_MSEC_IN_HOUR (QSE_MSEC_IN_SEC * QSE_SEC_IN_HOUR)
#define QSE_MSEC_IN_DAY (QSE_MSEC_IN_SEC * QSE_SEC_IN_DAY)
#define QSE_USEC_IN_MSEC ((qse_ntime_t)1000) #define QSE_DAYS_PER_WEEK (7)
#define QSE_NSEC_IN_USEC ((qse_ntime_t)1000) #define QSE_MONS_PER_YEAR (12)
#define QSE_USEC_IN_SEC ((qse_ntime_t)QSE_USEC_IN_MSEC * QSE_MSEC_IN_SEC) #define QSE_HOURS_PER_DAY (24)
#define QSE_MINS_PER_HOUR (60)
#define QSE_MINS_PER_DAY (QSE_MINS_PER_HOUR*QSE_HOURS_PER_DAY)
#define QSE_SECS_PER_MIN (60)
#define QSE_SECS_PER_HOUR (QSE_SECS_PER_MIN*QSE_MINS_PER_HOUR)
#define QSE_SECS_PER_DAY (QSE_SECS_PER_MIN*QSE_MINS_PER_DAY)
#define QSE_MSECS_PER_SEC (1000)
#define QSE_MSECS_PER_MIN (QSE_MSECS_PER_SEC*QSE_SECS_PER_MIN)
#define QSE_MSECS_PER_HOUR (QSE_MSECS_PER_SEC*QSE_SECS_PER_HOUR)
#define QSE_MSECS_PER_DAY (QSE_MSECS_PER_SEC*QSE_SECS_PER_DAY)
#define QSE_USECS_PER_MSEC (1000)
#define QSE_NSECS_PER_USEC (1000)
#define QSE_USECS_PER_SEC (QSE_USECS_PER_MSEC*QSE_MSECS_PER_SEC)
#define QSE_IS_LEAPYEAR(year) (!((year)%4) && (((year)%100) || !((year)%400))) #define QSE_IS_LEAPYEAR(year) (!((year)%4) && (((year)%100) || !((year)%400)))
#define QSE_DAY_IN_YEAR(year) (QSE_IS_LEAPYEAR(year)? 366: 365) #define QSE_DAYS_PER_YEAR(year) (QSE_IS_LEAPYEAR(year)? 366: 365)
/* number of milliseconds since the Epoch (00:00:00 UTC, Jan 1, 1970) */ /* number of milliseconds since the Epoch (00:00:00 UTC, Jan 1, 1970) */
typedef qse_long_t qse_ntime_t; typedef qse_long_t qse_ntime_t;
@ -39,6 +41,7 @@ typedef struct qse_btime_t qse_btime_t;
struct qse_btime_t struct qse_btime_t
{ {
int msec;
int sec; /* 0-61 */ int sec; /* 0-61 */
int min; /* 0-59 */ int min; /* 0-59 */
int hour; /* 0-23 */ int hour; /* 0-23 */
@ -48,6 +51,7 @@ struct qse_btime_t
int wday; /* 0(sun)-6(sat) */ int wday; /* 0(sun)-6(sat) */
int yday; /* 0(jan 1) to 365 */ int yday; /* 0(jan 1) to 365 */
int isdst; int isdst;
int offset;
}; };
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -1061,7 +1061,7 @@ static int bfn_systime (qse_awk_run_t* run, const qse_char_t* fnm, qse_size_t fn
if (qse_gettime(&now) == -1) if (qse_gettime(&now) == -1)
r = qse_awk_makeintval (run, QSE_TYPE_MIN(qse_long_t)); r = qse_awk_makeintval (run, QSE_TYPE_MIN(qse_long_t));
else else
r = qse_awk_makeintval (run, now / QSE_MSEC_IN_SEC); r = qse_awk_makeintval (run, now / QSE_MSECS_PER_SEC);
if (r == QSE_NULL) if (r == QSE_NULL)
{ {
@ -1073,6 +1073,18 @@ static int bfn_systime (qse_awk_run_t* run, const qse_char_t* fnm, qse_size_t fn
return 0; return 0;
} }
static int bfn_gmtime (qse_awk_run_t* run, const qse_char_t* fnm, qse-size_t fnl)
{
qse_ntime_t nt;
qse_btime_t bt;
qse_gmtime (nt, &bt);
/* TODO: create an array containing
* .....
*/
}
#define ADD_FUNC(awk,name,min,max,bfn) \ #define ADD_FUNC(awk,name,min,max,bfn) \
if (qse_awk_addfunc (\ if (qse_awk_addfunc (\
(awk), (name), qse_strlen(name), \ (awk), (name), qse_strlen(name), \
@ -1092,6 +1104,7 @@ static int add_functions (qse_awk_t* awk)
ADD_FUNC (awk, QSE_T("rand"), 0, 0, bfn_rand); ADD_FUNC (awk, QSE_T("rand"), 0, 0, bfn_rand);
ADD_FUNC (awk, QSE_T("srand"), 0, 1, bfn_srand); ADD_FUNC (awk, QSE_T("srand"), 0, 1, bfn_srand);
ADD_FUNC (awk, QSE_T("systime"), 0, 0, bfn_systime); ADD_FUNC (awk, QSE_T("systime"), 0, 0, bfn_systime);
ADD_FUNC (awk, QSE_T("gmtime"), 0, 0, bfn_gmtime);
/* /*
ADD_FUNC (awk, QSE_T("strftime"), 0, 2, bfn_strftime); ADD_FUNC (awk, QSE_T("strftime"), 0, 2, bfn_strftime);
ADD_FUNC (awk, QSE_T("strfgmtime"), 0, 2, bfn_strfgmtime); ADD_FUNC (awk, QSE_T("strfgmtime"), 0, 2, bfn_strfgmtime);

View File

@ -23,10 +23,10 @@
#define EPOCH_DIFF_YEARS (QSE_EPOCH_YEAR-WIN_EPOCH_YEAR) #define EPOCH_DIFF_YEARS (QSE_EPOCH_YEAR-WIN_EPOCH_YEAR)
#define EPOCH_DIFF_DAYS (EPOCH_DIFF_YEARS*365+EPOCH_DIFF_YEARS/4-3) #define EPOCH_DIFF_DAYS (EPOCH_DIFF_YEARS*365+EPOCH_DIFF_YEARS/4-3)
#define EPOCH_DIFF_SECS (EPOCH_DIFF_DAYS*24*60*60) #define EPOCH_DIFF_SECS (EPOCH_DIFF_DAYS*24*60*60)
#define EPOCH_DIFF_MSECS (EPOCH_DIFF_SECS*QSE_MSEC_IN_SEC) #define EPOCH_DIFF_MSECS (EPOCH_DIFF_SECS*QSE_MSECS_PER_SEC)
#endif #endif
static int mdays[2][QSE_MON_IN_YEAR] = static int mdays[2][QSE_MONS_PER_YEAR] =
{ {
{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
{ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
@ -59,7 +59,8 @@ int qse_gettime (qse_ntime_t* t)
#endif #endif
if (n == -1) return -1; if (n == -1) return -1;
*t = tv.tv_sec * QSE_MSEC_IN_SEC + tv.tv_usec / QSE_USEC_IN_MSEC; *t = (qse_ntime_t)tv.tv_sec*QSE_MSECS_PER_SEC +
(qse_ntime_t)tv.tv_usec/QSE_USECS_PER_MSEC;
return 0; return 0;
#endif #endif
} }
@ -78,8 +79,8 @@ int qse_settime (qse_ntime_t t)
struct timeval tv; struct timeval tv;
int n; int n;
tv.tv_sec = t / QSE_MSEC_IN_SEC; tv.tv_sec = t / QSE_MSECS_PER_SEC;
tv.tv_usec = (t % QSE_MSEC_IN_SEC) * QSE_USEC_IN_MSEC; tv.tv_usec = (t % QSE_MSECS_PER_SEC) * QSE_USECS_PER_MSEC;
/* /*
#if defined CLOCK_REALTIME && HAVE_CLOCK_SETTIME #if defined CLOCK_REALTIME && HAVE_CLOCK_SETTIME
@ -106,42 +107,74 @@ int qse_settime (qse_ntime_t t)
#endif #endif
} }
void qse_gmtime (qse_ntime_t nt, qse_btime_t* bt) static void brkdntime (qse_ntime_t nt, qse_btime_t* bt, qse_ntime_t offset)
{ {
/* code based on minix 2.0 src/lib/ansi/gmtime.c */ int midx;
qse_ntime_t days; /* total days */ qse_ntime_t days; /* total days */
qse_ntime_t secs; /* number of seconds in the fractional days */ qse_ntime_t secs; /* the remaining seconds */
qse_ntime_t time; /* total seconds */ qse_ntime_t year = QSE_EPOCH_YEAR;
int year = QSE_EPOCH_YEAR;
time = nt / QSE_MSEC_IN_SEC; nt += offset;
days = (unsigned long)time / QSE_SEC_IN_DAY; /* TODO: support bt->msecs */
secs = (unsigned long)time % QSE_SEC_IN_DAY; /*bt->msecs = nt % QSEC_MSECS_PER_SEC;*/
bt->sec = secs % QSE_SEC_IN_MIN;
bt->min = (secs % QSE_SEC_IN_HOUR) / QSE_SEC_IN_MIN;
bt->hour = secs / QSE_SEC_IN_HOUR;
bt->wday = (days + 4) % QSE_DAY_IN_WEEK; secs = nt / QSE_MSECS_PER_SEC;
days = secs / QSE_SECS_PER_DAY;
secs %= QSE_SECS_PER_DAY;
while (days >= QSE_DAY_IN_YEAR(year)) while (secs < 0)
{ {
days -= QSE_DAY_IN_YEAR(year); secs += QSE_SECS_PER_DAY;
year++; --days;
} }
bt->year = year - 1900; while (secs >= QSE_SECS_PER_DAY)
bt->yday = days;
bt->mon = 0;
while (days >= mdays[QSE_IS_LEAPYEAR(year)][bt->mon])
{ {
days -= mdays[QSE_IS_LEAPYEAR(year)][bt->mon]; secs -= QSE_SECS_PER_DAY;
bt->mon++; ++days;
}
bt->hour = secs / QSE_SECS_PER_HOUR;
secs %= QSE_SECS_PER_HOUR;
bt->min = secs / QSE_SECS_PER_MIN;
bt->sec = secs % QSE_SECS_PER_MIN;
bt->wday = (days + QSE_EPOCH_WDAY) % QSE_DAYS_PER_WEEK;
if (bt->wday < 0) bt->wday += QSE_DAYS_PER_WEEK;
if (days >= 0)
{
while (days >= QSE_DAYS_PER_YEAR(year))
{
days -= QSE_DAYS_PER_YEAR(year);
year++;
}
}
else
{
do
{
year--;
days += QSE_DAYS_PER_YEAR(year);
}
while (days < 0);
}
bt->year = year - QSE_BTIME_YEAR_BASE;
bt->yday = days;
midx = QSE_IS_LEAPYEAR(year)? 1: 0;
for (bt->mon = 0; days >= mdays[midx][bt->mon]; bt->mon++)
{
days -= mdays[midx][bt->mon];
} }
bt->mday = days + 1; bt->mday = days + 1;
bt->isdst = 0; bt->isdst = 0;
bt->offset = offset;
}
void qse_gmtime (qse_ntime_t nt, qse_btime_t* bt)
{
brkdntime (nt, bt, 0);
} }