82 lines
1.8 KiB
C
82 lines
1.8 KiB
C
/* libiso8601/src/libiso8601/c_library.c
|
|
*
|
|
* (c)2006, Laurence Withers, <l@lwithers.me.uk>.
|
|
* Released under the GNU GPLv2. See file COPYING or
|
|
* http://www.gnu.org/copyleft/gpl.html for details.
|
|
*/
|
|
|
|
// days between 0000-001 and 1970-001 (the unix epoch)
|
|
#define EPOCH_GDAY (719528)
|
|
|
|
|
|
|
|
void iso8601_now(struct iso8601_date* date, struct iso8601_details* details)
|
|
{
|
|
struct timespec ts;
|
|
struct tm tm;
|
|
|
|
clock_gettime(CLOCK_REALTIME, &ts);
|
|
|
|
// populate the `struct iso8601_date' if it was passed
|
|
if(date) {
|
|
iso8601_from_ts(date, &ts);
|
|
}
|
|
|
|
// populate the `struct iso8601_details' if it was passed
|
|
if(details) {
|
|
memset(details, 0, sizeof(struct iso8601_details));
|
|
details->date_prec = iso8601_prec_day;
|
|
details->time_prec = iso8601_prec_secfrac;
|
|
|
|
// this is silly, but it's the only way to recover the timezone
|
|
localtime_r(&ts.tv_sec, &tm);
|
|
details->tz_sec = tm.tm_gmtoff;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void iso8601_from_ts(struct iso8601_date* date, const struct timespec* ts)
|
|
{
|
|
ldiv_t qr;
|
|
|
|
qr = ldiv(ts->tv_sec, 86400);
|
|
date->day = EPOCH_GDAY + qr.quot;
|
|
date->sec = qr.rem;
|
|
date->nsec = ts->tv_nsec;
|
|
}
|
|
|
|
|
|
|
|
void iso8601_to_ts(struct timespec* ts, const struct iso8601_date* date)
|
|
{
|
|
ts->tv_sec = 86400L * (date->day - EPOCH_GDAY) + date->sec;
|
|
ts->tv_nsec = date->nsec;
|
|
}
|
|
|
|
|
|
|
|
void iso8601_from_time_t(struct iso8601_date* date, const time_t* t)
|
|
{
|
|
ldiv_t qr;
|
|
|
|
qr = ldiv(*t, 86400);
|
|
date->day = EPOCH_GDAY + qr.quot;
|
|
date->sec = qr.rem;
|
|
date->nsec = 0;
|
|
}
|
|
|
|
|
|
|
|
void iso8601_to_time_t(time_t* t, const struct iso8601_date* date)
|
|
{
|
|
*t = 86400L * (date->day - EPOCH_GDAY) + date->sec;
|
|
}
|
|
|
|
|
|
|
|
/* options for text editors
|
|
kate: replace-trailing-space-save true; space-indent true; tab-width 4;
|
|
vim: expandtab:ts=4:sw=4
|
|
*/
|