Further WIP on tidy up and merge beginning of new manipulation infrastructur
This commit is contained in:
parent
603b067310
commit
35c4455bc2
|
@ -103,6 +103,22 @@ struct iso8601_details {
|
|||
|
||||
|
||||
|
||||
/*! \brief Short period elapsed time.
|
||||
|
||||
This structure contains the details of an elapsed time period, split into seconds and nanoseconds.
|
||||
None of its components can ever be negative. This is only capable of representing short (compared to
|
||||
struct iso8601_date's range) periods of up to approximately 136 years.
|
||||
|
||||
*/
|
||||
struct iso8601_elapsed {
|
||||
/* number of whole days elapsed */
|
||||
uint32_t day;
|
||||
uint32_t sec;
|
||||
uint32_t nsec;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* options for text editors
|
||||
kate: replace-trailing-space-save true; space-indent true; tab-width 4;
|
||||
vim: expandtab:ts=4:sw=4
|
||||
|
|
|
@ -37,6 +37,7 @@ int iso8601_parse(const char* str, struct iso8601_date* earliest, struct iso8601
|
|||
int num = 0, neg = 0, dig = 0, tz_neg = 0, nsec = -1, nsec_dig = -1, leap_sec_req = 0;
|
||||
int y = 0, m = -1, d = -1, w = -1, wd = -1, hour = -1, min = -1, sec = -1, tz_sec = 0;
|
||||
double frac;
|
||||
struct iso8601_elapsed elapsed;
|
||||
|
||||
if(earliest) memset(earliest, 0, sizeof(struct iso8601_date));
|
||||
if(latest) memset(latest, 0, sizeof(struct iso8601_date));
|
||||
|
@ -651,8 +652,16 @@ done:
|
|||
/* correct for timezone offset (note trickery to end up at 23:59:60 iff a leap second was
|
||||
* requested), and ensure that any leap second requested was a valid leap second. */
|
||||
if(details) details->tz_sec = tz_sec;
|
||||
if(tz_sec && earliest) iso8601_add_seconds(earliest, - leap_sec_req - tz_sec);
|
||||
if(tz_sec && latest) iso8601_add_seconds(latest, - leap_sec_req - tz_sec);
|
||||
if(tz_sec && earliest) {
|
||||
elapsed.sec = leap_sec_req + tz_sec;
|
||||
elapsed.nsec = 0;
|
||||
iso8601_subtract_elapsed(earliest, &elapsed);
|
||||
}
|
||||
if(tz_sec && latest) {
|
||||
elapsed.sec = leap_sec_req + tz_sec;
|
||||
elapsed.nsec = 0;
|
||||
iso8601_subtract_elapsed(latest, &elapsed);
|
||||
}
|
||||
if(leap_sec_req) {
|
||||
ERROR_IF(earliest && earliest->sec != 86400);
|
||||
ERROR_IF(latest && latest->sec != 86400);
|
||||
|
|
|
@ -23,6 +23,7 @@ char* iso8601_print(char* str, int amt, const struct iso8601_date* date,
|
|||
struct iso8601_date dttz;
|
||||
double frac;
|
||||
char* str_orig;
|
||||
struct iso8601_elapsed elapsed;
|
||||
|
||||
str_orig = str;
|
||||
|
||||
|
@ -31,7 +32,11 @@ char* iso8601_print(char* str, int amt, const struct iso8601_date* date,
|
|||
|
||||
// adjust output for timezone
|
||||
dttz = *date;
|
||||
if(details->tz_sec) iso8601_add_seconds(&dttz, details->tz_sec);
|
||||
if(details->tz_sec) {
|
||||
elapsed.sec = details ? details->tz_sec : 0;
|
||||
elapsed.nsec = 0;
|
||||
iso8601_add_elapsed(&dttz, &elapsed);
|
||||
}
|
||||
|
||||
// determine whether or not to force extended output
|
||||
iso8601_to_cal(&y, &m, &d, &dttz);
|
||||
|
|
|
@ -0,0 +1,151 @@
|
|||
/* libiso8601/src/libiso8601/400_calc.h
|
||||
*
|
||||
* (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.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/*! \defgroup manip Conversion and calculation routines.
|
||||
|
||||
This set of functions is useful for converting dates and times into formats understood by humans,
|
||||
and vice versa.
|
||||
|
||||
*/
|
||||
/*!@{*/
|
||||
|
||||
|
||||
|
||||
/*! \brief Is year a leap year?
|
||||
|
||||
\param year Year to examine.
|
||||
\retval 0 if not leap year.
|
||||
\retval non-0 if leap year.
|
||||
|
||||
Returns non-0 if \a year is a leap year.
|
||||
|
||||
*/
|
||||
int iso8601_isleap(int year);
|
||||
|
||||
|
||||
|
||||
/*! \brief Convert date to calendar format.
|
||||
|
||||
\param[out] year Calendar year.
|
||||
\param[out] month Calendar month (1 to 12).
|
||||
\param[out] day Calendar day (starting from 1).
|
||||
\param date Date to convert.
|
||||
|
||||
*/
|
||||
void iso8601_to_cal(int* year, int* month, int* day, const struct iso8601_date* date);
|
||||
|
||||
|
||||
|
||||
/*! \brief Convert date from calendar format.
|
||||
|
||||
\param[out] date Output date.
|
||||
\param year Calendar year.
|
||||
\param month Calendar month (1 to 12).
|
||||
\param day Calenday day (starting from 1).
|
||||
\retval 0 on success.
|
||||
\retval -1 on error (and see \a errno).
|
||||
|
||||
Converts the date specified in \a year, \a month and \a day into \a date. Does not touch the \a sec
|
||||
or \a nsec time members of \a date.
|
||||
|
||||
*/
|
||||
int iso8601_from_cal(struct iso8601_date* date, int year, int month, int day);
|
||||
|
||||
|
||||
|
||||
/*! \brief Convert date to ordinal format.
|
||||
|
||||
\param[out] year Calendar year.
|
||||
\param[out] oday Ordinal day (from 1).
|
||||
\param date Date to convert.
|
||||
|
||||
*/
|
||||
void iso8601_to_ord(int* year, int* oday, const struct iso8601_date* date);
|
||||
|
||||
|
||||
|
||||
/*! \brief Convert date from ordinal format.
|
||||
|
||||
\param[out] date Output date.
|
||||
\param year Calendar year.
|
||||
\param day Ordinal day (from 1).
|
||||
\retval 0 on success.
|
||||
\retval -1 on error (and see \a errno).
|
||||
|
||||
Converts the date specified into \a year and \a oday into \a date. Does not touch the \a sec or
|
||||
\a nsec time members of \a date.
|
||||
|
||||
*/
|
||||
int iso8601_from_ord(struct iso8601_date* date, int year, int oday);
|
||||
|
||||
|
||||
|
||||
/*! \brief Convert date to week format.
|
||||
|
||||
\param[out] year Calendar year.
|
||||
\param[out] week ISO week number (from 1).
|
||||
\param[out] wday ISO week day number (1 = Monday, 7 = Sunday).
|
||||
\param date Date to convert.
|
||||
|
||||
*/
|
||||
void iso8601_to_week(int* year, int* week, int* wday, const struct iso8601_date* date);
|
||||
|
||||
|
||||
|
||||
/*! \brief Convert date from week format.
|
||||
|
||||
\param [out] date Output date.
|
||||
\param year Calendar year.
|
||||
\param week ISO week number (from 1).
|
||||
\param wday ISO week day number (1 = Monday, 7 = Sunday).
|
||||
\retval 0 on success.
|
||||
\retval -1 on error (and see \a errno).
|
||||
|
||||
*/
|
||||
int iso8601_from_week(struct iso8601_date* date, int year, int week, int wday);
|
||||
|
||||
|
||||
|
||||
/*! \brief Convert time to wall clock format.
|
||||
|
||||
\param[out] hour Output hour.
|
||||
\param[out] min Output minute.
|
||||
\param[out] sec Output second.
|
||||
\param date Date/time to convert.
|
||||
|
||||
Converts the time stored in \a date into wall clock format, storing the result in \a hour, \a min
|
||||
and \a sec.
|
||||
|
||||
*/
|
||||
void iso8601_to_clocktime(int* hour, int* min, int* sec, const struct iso8601_date* date);
|
||||
|
||||
|
||||
|
||||
/*! \brief Convert time from wall clock format.
|
||||
|
||||
\param[out] Output time.
|
||||
\param hour Hour.
|
||||
\param min Minute.
|
||||
\param sec Second.
|
||||
\retval 0 on success.
|
||||
\retval -1 on error (and see \a errno).
|
||||
|
||||
Converts the time as specified by \a hour, \a min and \a sec, storing the result in \a date. Does
|
||||
not touch the \a day (date) member of \a date.
|
||||
|
||||
*/
|
||||
int iso8601_from_clocktime(struct iso8601_date* date, int hour, int min, int sec);
|
||||
|
||||
|
||||
|
||||
/*!@}*/
|
||||
/* options for text editors
|
||||
kate: replace-trailing-space-save true; space-indent true; tab-width 4;
|
||||
vim: expandtab:ts=4:sw=4
|
||||
*/
|
|
@ -1,33 +0,0 @@
|
|||
/* libiso8601/src/libiso8601/functions.h
|
||||
*
|
||||
* (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.
|
||||
*/
|
||||
|
||||
/* calc.c */
|
||||
int iso8601_isleap(int year);
|
||||
void iso8601_to_cal(int* year, int* month, int* day, const struct iso8601_date* date);
|
||||
int iso8601_from_cal(struct iso8601_date* date, int year, int month, int day);
|
||||
void iso8601_to_ord(int* year, int* oday, const struct iso8601_date* date);
|
||||
int iso8601_from_ord(struct iso8601_date* date, int year, int oday);
|
||||
void iso8601_to_week(int* year, int* week, int* wday, const struct iso8601_date* date);
|
||||
int iso8601_from_week(struct iso8601_date* date, int year, int week, int wday);
|
||||
void iso8601_to_clocktime(int* hour, int* min, int* sec, const struct iso8601_date* date);
|
||||
int iso8601_from_clocktime(struct iso8601_date* date, int hour, int min, int sec);
|
||||
|
||||
/* manip.c */
|
||||
int iso8601_lt(const struct iso8601_date* d1, const struct iso8601_date* d2);
|
||||
int iso8601_lte(const struct iso8601_date* d1, const struct iso8601_date* d2);
|
||||
int iso8601_eq(const struct iso8601_date* d1, const struct iso8601_date* d2);
|
||||
void iso8601_add_seconds(struct iso8601_date* date, long seconds);
|
||||
void iso8601_add_nanoseconds(struct iso8601_date* date, long nano);
|
||||
|
||||
/* leap.c */
|
||||
int iso8601_seconds_leap(const struct iso8601_date* date);
|
||||
int iso8601_leap_elapsed(const struct iso8601_date* start, const struct iso8601_date* end);
|
||||
|
||||
/* options for text editors
|
||||
kate: replace-trailing-space-save true; space-indent true; tab-width 4;
|
||||
vim: expandtab:ts=4:sw=4
|
||||
*/
|
|
@ -1,4 +1,4 @@
|
|||
/* libiso8601/src/libiso8601/manip.c
|
||||
/* libiso8601/src/libiso8601/400_manip.c
|
||||
*
|
||||
* (c)2006, Laurence Withers, <l@lwithers.me.uk>.
|
||||
* Released under the GNU GPLv2. See file COPYING or
|
||||
|
@ -38,51 +38,16 @@ int iso8601_eq(const struct iso8601_date* d1, const struct iso8601_date* d2)
|
|||
|
||||
|
||||
|
||||
void iso8601_add_seconds(struct iso8601_date* date, long seconds)
|
||||
void iso8601_add_elapsed(struct iso8601_date* date, const struct iso8601_elapsed* per)
|
||||
{
|
||||
int sday;
|
||||
ldiv_t qr;
|
||||
|
||||
sday = date->day;
|
||||
qr = ldiv(seconds + date->sec, 86400);
|
||||
date->day += qr.quot;
|
||||
|
||||
date->sec = qr.rem;
|
||||
if(date->sec < 0) {
|
||||
--date->day;
|
||||
date->sec += 86400;
|
||||
}
|
||||
|
||||
/* leap second correction */
|
||||
if(sday != date->day) {
|
||||
date->sec += _leap_elapsed_day(sday, date->day);
|
||||
if(date->sec < 0) {
|
||||
--date->day;
|
||||
date->sec += iso8601_seconds_leap(date);
|
||||
} else if(date->sec >= iso8601_seconds_leap(date)) {
|
||||
date->sec -= iso8601_seconds_leap(date);
|
||||
++date->day;
|
||||
}
|
||||
}
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
|
||||
|
||||
void iso8601_add_nanoseconds(struct iso8601_date* date, long nsec)
|
||||
void iso8601_subtract_elapsed(struct iso8601_date* date, const struct iso8601_elapsed* per)
|
||||
{
|
||||
ldiv_t qr;
|
||||
|
||||
qr = ldiv(nsec, BILLION);
|
||||
date->nsec += qr.rem;
|
||||
if(date->nsec > BILLION) {
|
||||
date->nsec -= BILLION;
|
||||
++qr.quot;
|
||||
} else if(date->nsec < 0) {
|
||||
date->nsec += BILLION;
|
||||
--qr.quot;
|
||||
}
|
||||
|
||||
iso8601_add_seconds(date, qr.quot);
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
/* libiso8601/src/libiso8601/400_manip.h
|
||||
*
|
||||
* (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.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/*! \defgroup manip Manipulation routines.
|
||||
|
||||
This set of functions is useful for converting dates and times into formats understood by humans,
|
||||
and vice versa.
|
||||
|
||||
*/
|
||||
/*!@{*/
|
||||
|
||||
|
||||
|
||||
/*! \brief Comparison (less than).
|
||||
|
||||
\param d1 First date to compare.
|
||||
\param d2 Second date to compare.
|
||||
\retval non-0 if \a d1 < \a d2
|
||||
\retval 0 otherwise
|
||||
|
||||
*/
|
||||
int iso8601_lt(const struct iso8601_date* d1, const struct iso8601_date* d2);
|
||||
|
||||
|
||||
|
||||
/*! \brief Comparison (less than or equal to).
|
||||
|
||||
\param d1 First date to compare.
|
||||
\param d2 Second date to compare.
|
||||
\retval non-0 if \a d1 <e; \a d2
|
||||
\retval 0 otherwise
|
||||
|
||||
*/
|
||||
int iso8601_lte(const struct iso8601_date* d1, const struct iso8601_date* d2);
|
||||
|
||||
|
||||
|
||||
/*! \brief Comparison (equality).
|
||||
|
||||
\param d1 First date to compare.
|
||||
\param d2 Second date to compare.
|
||||
\retval non-0 if \a d1 == \a d2
|
||||
\retval 0 otherwise
|
||||
|
||||
*/
|
||||
int iso8601_eq(const struct iso8601_date* d1, const struct iso8601_date* d2);
|
||||
|
||||
|
||||
|
||||
/*! \brief Add a period to a date.
|
||||
|
||||
\param[in,out] date Date to modify.
|
||||
\param per Period to advance date/time by.
|
||||
|
||||
*/
|
||||
void iso8601_add_elapsed(struct iso8601_date* date, const struct iso8601_elapsed* per);
|
||||
|
||||
|
||||
|
||||
/*! \brief Subtract a period from a date.
|
||||
|
||||
\param[in,out] date Date to modify.
|
||||
\param per Period to regress date/time by.
|
||||
|
||||
*/
|
||||
void iso8601_subtract_elapsed(struct iso8601_date* date, const struct iso8601_elapsed* per);
|
||||
|
||||
|
||||
|
||||
/*!@}*/
|
||||
/* options for text editors
|
||||
kate: replace-trailing-space-save true; space-indent true; tab-width 4;
|
||||
vim: expandtab:ts=4:sw=4
|
||||
*/
|
Loading…
Reference in New Issue