From 311e3bf4e7ec14718a3111f5d9751492d00f1e14 Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Mon, 22 Dec 2008 08:31:30 +0000 Subject: [PATCH] partially implemented qse_gmtime() - still need to enhance to support msec in the broken-down time --- qse/include/qse/cmn/time.h | 44 ++++++++++-------- qse/lib/awk/std.c | 15 +++++- qse/lib/cmn/time.c | 93 ++++++++++++++++++++++++++------------ 3 files changed, 101 insertions(+), 51 deletions(-) diff --git a/qse/include/qse/cmn/time.h b/qse/include/qse/cmn/time.h index 55c16f24..436f0e1d 100644 --- a/qse/include/qse/cmn/time.h +++ b/qse/include/qse/cmn/time.h @@ -8,30 +8,32 @@ #include #include -#define QSE_EPOCH_YEAR ((qse_ntime_t)1970) -#define QSE_EPOCH_MON ((qse_ntime_t)1) -#define QSE_EPOCH_DAY ((qse_ntime_t)1) -#define QSE_EPOCH_WDAY ((qse_ntime_t)4) +#define QSE_EPOCH_YEAR (1970) +#define QSE_EPOCH_MON (1) +#define QSE_EPOCH_DAY (1) +#define QSE_EPOCH_WDAY (4) -#define QSE_DAY_IN_WEEK ((qse_ntime_t)7) -#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_BTIME_YEAR_BASE (1900) -#define QSE_USEC_IN_MSEC ((qse_ntime_t)1000) -#define QSE_NSEC_IN_USEC ((qse_ntime_t)1000) -#define QSE_USEC_IN_SEC ((qse_ntime_t)QSE_USEC_IN_MSEC * QSE_MSEC_IN_SEC) +#define QSE_DAYS_PER_WEEK (7) +#define QSE_MONS_PER_YEAR (12) +#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_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) */ typedef qse_long_t qse_ntime_t; @@ -39,6 +41,7 @@ typedef struct qse_btime_t qse_btime_t; struct qse_btime_t { + int msec; int sec; /* 0-61 */ int min; /* 0-59 */ int hour; /* 0-23 */ @@ -48,6 +51,7 @@ struct qse_btime_t int wday; /* 0(sun)-6(sat) */ int yday; /* 0(jan 1) to 365 */ int isdst; + int offset; }; #ifdef __cplusplus diff --git a/qse/lib/awk/std.c b/qse/lib/awk/std.c index f33e40b0..12ccc4cc 100644 --- a/qse/lib/awk/std.c +++ b/qse/lib/awk/std.c @@ -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) r = qse_awk_makeintval (run, QSE_TYPE_MIN(qse_long_t)); 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) { @@ -1073,6 +1073,18 @@ static int bfn_systime (qse_awk_run_t* run, const qse_char_t* fnm, qse_size_t fn 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) \ if (qse_awk_addfunc (\ (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("srand"), 0, 1, bfn_srand); 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("strfgmtime"), 0, 2, bfn_strfgmtime); diff --git a/qse/lib/cmn/time.c b/qse/lib/cmn/time.c index 98614b15..8db16284 100644 --- a/qse/lib/cmn/time.c +++ b/qse/lib/cmn/time.c @@ -23,10 +23,10 @@ #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_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 -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, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } @@ -59,7 +59,8 @@ int qse_gettime (qse_ntime_t* t) #endif 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; #endif } @@ -78,8 +79,8 @@ int qse_settime (qse_ntime_t t) struct timeval tv; int n; - tv.tv_sec = t / QSE_MSEC_IN_SEC; - tv.tv_usec = (t % QSE_MSEC_IN_SEC) * QSE_USEC_IN_MSEC; + tv.tv_sec = t / QSE_MSECS_PER_SEC; + tv.tv_usec = (t % QSE_MSECS_PER_SEC) * QSE_USECS_PER_MSEC; /* #if defined CLOCK_REALTIME && HAVE_CLOCK_SETTIME @@ -106,42 +107,74 @@ int qse_settime (qse_ntime_t t) #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 secs; /* number of seconds in the fractional days */ - qse_ntime_t time; /* total seconds */ - - int year = QSE_EPOCH_YEAR; + qse_ntime_t secs; /* the remaining seconds */ + qse_ntime_t year = QSE_EPOCH_YEAR; - time = nt / QSE_MSEC_IN_SEC; - days = (unsigned long)time / QSE_SEC_IN_DAY; - secs = (unsigned long)time % QSE_SEC_IN_DAY; - - 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; + nt += offset; + /* TODO: support bt->msecs */ + /*bt->msecs = nt % QSEC_MSECS_PER_SEC;*/ - 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); - year++; + secs += QSE_SECS_PER_DAY; + --days; } - bt->year = year - 1900; - bt->yday = days; - bt->mon = 0; - - while (days >= mdays[QSE_IS_LEAPYEAR(year)][bt->mon]) + while (secs >= QSE_SECS_PER_DAY) { - days -= mdays[QSE_IS_LEAPYEAR(year)][bt->mon]; - bt->mon++; + secs -= QSE_SECS_PER_DAY; + ++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->isdst = 0; + bt->offset = offset; +} + +void qse_gmtime (qse_ntime_t nt, qse_btime_t* bt) +{ + brkdntime (nt, bt, 0); }