libiso8601/src/libiso8601/c_library.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
*/