39 #if defined(HAVE_STRUCT_TM_TM_GMTOFF)    40 #  define GMTOFF(tm) ((tm)->tm_gmtoff)    43 #  define GMTOFF(tm) (-timezone+daylight)    46 #define HOUR_SECONDS    (60 * 60)    47 #define DAY_SECONDS     (HOUR_SECONDS * 24)    59 static crm_time_t *parse_date(
const char *date_str);
    72     utc->years = dt->years;
    74     utc->seconds = dt->seconds;
    81         utc->months = dt->months;
    98     if (date_time == NULL) {
   103         dt = parse_date(date_time);
   135     return (t != NULL) && (t->years || t->months || t->days || t->seconds
   136                            || t->offset || t->duration);
   170     int YY = (year - 1) % 100;
   171     int C = (year - 1) - YY;
   173     int jan1 = 1 + (((((C / 100) % 4) * 5) + G) % 7);
   175     crm_trace(
"YY=%d, C=%d, G=%d", YY, C, G);
   176     crm_trace(
"January 1 %.4d: %d", year, jan1);
   201 static int month_days[13] = {
   202     31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 29
   216     if ((month < 1) || (month > 12)) {
   222     return month_days[month - 1];
   228     gboolean is_leap = FALSE;
   233     if (year % 100 == 0 && year % 400 != 0) {
   240 get_ordinal_days(uint32_t y, uint32_t m, uint32_t d)
   244     for (lpc = 1; lpc < m; lpc++) {
   258                (prefix? prefix : 
""), (prefix? 
": " : 
""), date_s);
   261                          (prefix? prefix : 
""), (prefix? 
": " : 
""), date_s);
   267 crm_time_get_sec(
int sec, uint * h, uint * m, uint * s)
   269     uint hours, minutes, seconds;
   280     minutes = seconds / 60;
   281     seconds -= 60 * minutes;
   283     crm_trace(
"%d == %.2d:%.2d:%.2d", sec, hours, minutes, seconds);
   293     crm_time_get_sec(dt->seconds, h, m, s);
   302     crm_time_get_sec(dt->seconds, h, m, &s);
   311     long long in_seconds = 0;
   317     utc = crm_get_utc_time(dt);
   322     for (lpc = 1; lpc < utc->years; lpc++) {
   323         long long dmax = year_days(lpc);
   335     if (utc->months > 0) {
   336         in_seconds += 
DAY_SECONDS * 30 * (
long long) (utc->months);
   340         in_seconds += 
DAY_SECONDS * (
long long) (utc->days - 1);
   342     in_seconds += utc->seconds;
   348 #define EPOCH_SECONDS 62135596800ULL       362         for (months = 1; months <= 12 && days > 0; months++) {
   372     } 
else if (dt->months) {
   383     crm_trace(
"%.4d-%.3d -> %.4d-%.2d-%.2d", dt->years, dt->days, dt->years, months, days);
   409     h = dt->days + jan1 - 1;
   410     *d = 1 + ((h - 1) % 7);
   413     if (dt->days <= (8 - jan1) && jan1 > 4) {
   415         year_num = dt->years - 1;
   419         year_num = dt->years;
   423     if (year_num == dt->years) {
   424         int dmax = year_days(year_num);
   425         int correction = 4 - *d;
   427         if ((dmax - dt->days) < correction) {
   428             crm_trace(
"year++, jan1=%d, i=%d vs. %d", jan1, dmax - dt->days, correction);
   429             year_num = dt->years + 1;
   435     if (year_num == dt->years) {
   436         int j = dt->days + (7 - *d) + (jan1 - 1);
   445     crm_trace(
"Converted %.4d-%.3d to %.4d-W%.2d-%d", dt->years, dt->days, *y, *w, *d);
   452 crm_duration_as_string(
crm_time_t *dt, 
char *result)
   457         offset += snprintf(result + offset, 
DATE_MAX - offset, 
"%4d year%s ",
   461         offset += snprintf(result + offset, 
DATE_MAX - offset, 
"%2d month%s ",
   465         offset += snprintf(result + offset, 
DATE_MAX - offset, 
"%2d day%s ",
   469     if (((offset == 0) || (dt->seconds != 0))
   470         && (dt->seconds > -60) && (dt->seconds < 60)) {
   471         offset += snprintf(result + offset, 
DATE_MAX - offset, 
"%d second%s",
   473     } 
else if (dt->seconds) {
   474         uint h = 0, m = 0, s = 0;
   476         offset += snprintf(result + offset, 
DATE_MAX - offset, 
"%d seconds (",
   478         crm_time_get_sec(dt->seconds, &h, &m, &s);
   480             offset += snprintf(result + offset, 
DATE_MAX - offset, 
"%u hour%s%s",
   484             offset += snprintf(result + offset, 
DATE_MAX - offset, 
"%u minute%s%s",
   488             offset += snprintf(result + offset, 
DATE_MAX - offset, 
"%u second%s",
   491         offset += snprintf(result + offset, 
DATE_MAX - offset, 
")");
   501     char *result_copy = NULL;
   505     if (date_time && date_time->offset
   508         utc = crm_get_utc_time(date_time);
   515         strcpy(result, 
"<undefined time>");
   522         crm_duration_as_string(date_time, result);
   544                 offset += snprintf(result + offset, 
DATE_MAX - offset,
   545                                    "%u-W%.2u-%u", y, w, d);
   552                 offset += snprintf(result + offset, 
DATE_MAX - offset,
   560                 offset += snprintf(result + offset, 
DATE_MAX - offset,
   561                                    "%.4u-%.2u-%.2u", y, m, d);
   567         uint h = 0, m = 0, s = 0;
   570             offset += snprintf(result + offset, 
DATE_MAX - offset, 
" ");
   574             offset += snprintf(result + offset, 
DATE_MAX - offset,
   575                                "%.2u:%.2u:%.2u", h, m, s);
   579             crm_time_get_sec(dt->offset, &h, &m, &s);
   580             offset += snprintf(result + offset, 
DATE_MAX - offset,
   582                                ((dt->offset < 0)? 
'-' : 
'+'), h, m);
   584             offset += snprintf(result + offset, 
DATE_MAX - offset, 
"Z");
   591     result_copy = strdup(result);
   608 crm_time_parse_sec(
const char *time_str, 
int *result)
   618     rc = sscanf(time_str, 
"%d:%d:%d", &hour, &minute, &second);
   620         rc = sscanf(time_str, 
"%2d%2d%2d", &hour, &minute, &second);
   623         crm_err(
"%s is not a valid ISO 8601 time specification", time_str);
   628     crm_trace(
"Got valid time: %.2d:%.2d:%.2d", hour, minute, second);
   630     if ((hour == 24) && (minute == 0) && (second == 0)) {
   632     } 
else if (hour >= 24) {
   633         crm_err(
"%s is not a valid ISO 8601 time specification "   634                 "because %d is not a valid hour", time_str, hour);
   639         crm_err(
"%s is not a valid ISO 8601 time specification "   640                 "because %d is not a valid minute", time_str, minute);
   645         crm_err(
"%s is not a valid ISO 8601 time specification "   646                 "because %d is not a valid second", time_str, second);
   651     *result = (hour * 
HOUR_SECONDS) + (minute * 60) + second;
   656 crm_time_parse_offset(
const char *offset_str, 
int *offset)
   660     if (offset_str == NULL) {
   662 #if defined(HAVE_STRUCT_TM_TM_GMTOFF)   663         time_t now = time(NULL);
   664         struct tm *now_tm = localtime(&now);
   669         if (h_offset < 0 && m_offset < 0) {
   670             m_offset = 0 - m_offset;
   676     if (offset_str[0] == 
'Z') { 
   682     if ((offset_str[0] == 
'+') || (offset_str[0] == 
'-')
   683         || isdigit((
int)offset_str[0])) {
   685         gboolean negate = FALSE;
   687         if (offset_str[0] == 
'+') {
   689         } 
else if (offset_str[0] == 
'-') {
   693         if (crm_time_parse_sec(offset_str, offset) == FALSE) {
   697             *offset = 0 - *offset;
   714 crm_time_parse(
const char *time_str, 
crm_time_t *a_time)
   717     char *offset_s = NULL;
   722         if (crm_time_parse_sec(time_str, &(a_time->seconds)) == FALSE) {
   725         offset_s = strstr(time_str, 
"Z");
   726         if (offset_s == NULL) {
   727             offset_s = strstr(time_str, 
" ");
   729                 while (isspace(offset_s[0])) {
   736     if (crm_time_parse_offset(offset_s, &(a_time->offset)) == FALSE) {
   739     crm_time_get_sec(a_time->offset, &h, &m, &s);
   740     crm_trace(
"Got tz: %c%2.d:%.2d", ((a_time->offset < 0)? 
'-' : 
'+'), h, m);
   759 parse_date(
const char *date_str)
   761     const char *time_s = NULL;
   770     if (pcmk__str_empty(date_str)) {
   771         crm_err(
"No ISO 8601 date/time specification given");
   775     if ((date_str[0] == 
'T') || (date_str[2] == 
':')) {
   778         if (date_str[0] == 
'T') {
   779             time_s = date_str + 1;
   788     if (!strncasecmp(
"epoch", date_str, 5)
   789         && ((date_str[5] == 
'\0') || (date_str[5] == 
'/') || isspace(date_str[5]))) {
   797     rc = sscanf(date_str, 
"%d-%d-%d", &year, &month, &day);
   800         rc = sscanf(date_str, 
"%4d%2d%2d", &year, &month, &day);
   804             crm_err(
"'%s' is not a valid ISO 8601 date/time specification "   805                     "because '%d' is not a valid month", date_str, month);
   808             crm_err(
"'%s' is not a valid ISO 8601 date/time specification "   809                     "because '%d' is not a valid day of the month",
   814             dt->days = get_ordinal_days(year, month, day);
   815             crm_trace(
"Parsed Gregorian date '%.4d-%.3d' from date string '%s'",
   816                       year, dt->days, date_str);
   822     rc = sscanf(date_str, 
"%d-%d", &year, &day);
   824         if (day > year_days(year)) {
   825             crm_err(
"'%s' is not a valid ISO 8601 date/time specification "   826                     "because '%d' is not a valid day of the year (max %d)",
   827                     date_str, day, year_days(year));
   830         crm_trace(
"Parsed ordinal year %d and days %d from date string '%s'",
   831                   year, day, date_str);
   838     rc = sscanf(date_str, 
"%d-W%d-%d", &year, &week, &day);
   841             crm_err(
"'%s' is not a valid ISO 8601 date/time specification "   842                     "because '%d' is not a valid week of the year (max %d)",
   845         } 
else if (day < 1 || day > 7) {
   846             crm_err(
"'%s' is not a valid ISO 8601 date/time specification "   847                     "because '%d' is not a valid day of the week",
   863             crm_trace(
"Got year %d (Jan 1 = %d), week %d, and day %d from date string '%s'",
   864                       year, jan1, week, day, date_str);
   880     crm_err(
"'%s' is not a valid ISO 8601 date/time specification", date_str);
   885     if (time_s == NULL) {
   886         time_s = date_str + strspn(date_str, 
"0123456789-W");
   887         if ((time_s[0] == 
' ') || (time_s[0] == 
'T')) {
   893     if ((time_s != NULL) && (crm_time_parse(time_s, dt) == FALSE)) {
   899         crm_err(
"'%s' is not a valid ISO 8601 date/time specification",
   916 parse_int(
const char *str, 
int field_width, 
int upper_bound, 
int *result)
   920     int intermediate = 0;
   921     gboolean fraction = FALSE;
   922     gboolean negate = FALSE;
   929     if (str[offset] == 
'T') {
   933     if (str[offset] == 
'.' || str[offset] == 
',') {
   937     } 
else if (str[offset] == 
'-') {
   940     } 
else if (str[offset] == 
'+' || str[offset] == 
':') {
   944     for (; (fraction || lpc < field_width) && isdigit((
int)str[offset]); lpc++) {
   946             intermediate = (str[offset] - 
'0') / (10 ^ lpc);
   949             intermediate = str[offset] - 
'0';
   951         *result += intermediate;
   955         *result = (int)(*result * upper_bound);
   957     } 
else if (upper_bound > 0 && *result > upper_bound) {
   958         *result = upper_bound;
   961         *result = 0 - *result;
   964         crm_trace(
"Found int: %d.  Stopped at str[%d]='%c'", *result, lpc, str[lpc]);
   984     gboolean is_time = FALSE;
   987     if (pcmk__str_empty(period_s)) {
   988         crm_err(
"No ISO 8601 time duration given");
   991     if (period_s[0] != 
'P') {
   992         crm_err(
"'%s' is not a valid ISO 8601 time duration "   993                 "because it does not start with a 'P'", period_s);
   996     if ((period_s[1] == 
'\0') || isspace(period_s[1])) {
   997         crm_err(
"'%s' is not a valid ISO 8601 time duration "   998                 "because nothing follows 'P'", period_s);
  1003     diff->duration = TRUE;
  1005     for (
const char *current = period_s + 1;
  1006          current[0] && (current[0] != 
'/') && !isspace(current[0]);
  1011         if (current[0] == 
'T') {
  1021         rc = parse_int(current, 10, 0, &an_int);
  1023             crm_err(
"'%s' is not a valid ISO 8601 time duration "  1024                     "because no integer at '%s'", period_s, current);
  1030         switch (current[0]) {
  1032                 diff->years = an_int;
  1037                     diff->seconds += an_int * 60;
  1039                     diff->months = an_int;
  1043                 diff->days += an_int * 7;
  1046                 diff->days += an_int;
  1052                 diff->seconds += an_int;
  1055                 crm_err(
"'%s' is not a valid ISO 8601 time duration "  1056                         "because no units after %d", period_s, an_int);
  1059                 crm_err(
"'%s' is not a valid ISO 8601 time duration "  1060                         "because '%c' is not a valid time unit",
  1061                         period_s, current[0]);
  1067         crm_err(
"'%s' is not a valid ISO 8601 time duration "  1068                 "because no amounts and units given", period_s);
  1092     const char *original = period_str;
  1095     if (pcmk__str_empty(period_str)) {
  1096         crm_err(
"No ISO 8601 time period given");
  1104     if (period_str[0] == 
'P') {
  1106         if (period->
diff == NULL) {
  1110         period->
start = parse_date(period_str);
  1111         if (period->
start == NULL) {
  1116     period_str = strstr(original, 
"/");
  1119         if (period_str[0] == 
'P') {
  1120             if (period->
diff != NULL) {
  1121                 crm_err(
"'%s' is not a valid ISO 8601 time period "  1122                         "because it has two durations",
  1127             if (period->
diff == NULL) {
  1131             period->
end = parse_date(period_str);
  1132             if (period->
end == NULL) {
  1137     } 
else if (period->
diff != NULL) {
  1143         crm_err(
"'%s' is not a valid ISO 8601 time period "  1144                 "because it has no duration or ending time",
  1149     if (period->
start == NULL) {
  1152     } 
else if (period->
end == NULL) {
  1157         crm_err(
"'%s' is not a valid ISO 8601 time period "  1158                 "because the start is invalid", period_str);
  1162         crm_err(
"'%s' is not a valid ISO 8601 time period "  1163                 "because the end is invalid", period_str);
  1198     target->years = source->years;
  1199     target->days = source->days;
  1200     target->months = source->months;    
  1201     target->seconds = source->seconds;
  1202     target->offset = source->offset;
  1222     target->duration = FALSE;
  1224     if (source->tm_year > 0) {
  1226         target->years = 1900 + source->tm_year;
  1229     if (source->tm_yday >= 0) {
  1231         target->days = 1 + source->tm_yday;
  1234     if (source->tm_hour >= 0) {
  1237     if (source->tm_min >= 0) {
  1238         target->seconds += 60 * source->tm_min;
  1240     if (source->tm_sec >= 0) {
  1241         target->seconds += source->tm_sec;
  1247     crm_trace(
"Offset (s): %ld, offset (hh:mm): %.2d:%.2d", 
GMTOFF(source), h_offset, m_offset);
  1250     target->offset += 60 * m_offset;
  1256     ha_set_tm_time(
target, localtime(source));
  1274     if ((dt == NULL) || (value == NULL)) {
  1281     utc = crm_get_utc_time(value);
  1287     answer->years += utc->years;
  1302     if ((dt == NULL) || (value == NULL)) {
  1307     utc = crm_get_utc_time(value);
  1312     answer = crm_get_utc_time(dt);
  1313     if (answer == NULL) {
  1317     answer->duration = TRUE;
  1319     answer->years -= utc->years;
  1320     if(utc->months != 0) {
  1336     if ((dt == NULL) || (value == NULL)) {
  1341     utc = crm_get_utc_time(value);
  1347     answer->years -= utc->years;
  1348     if(utc->months != 0) {
  1368            && (dt->days > 0) && (dt->days <= year_days(dt->years))
  1369            && (dt->seconds >= 0) && (dt->seconds < 
DAY_SECONDS);
  1372 #define do_cmp_field(l, r, field)                   \  1374         if(l->field > r->field) {               \  1375             crm_trace("%s: %d > %d",            \  1376                     #field, l->field, r->field);    \  1378         } else if(l->field < r->field) {            \  1379             crm_trace("%s: %d < %d",            \  1380                     #field, l->field, r->field);    \  1392     if ((t1 == NULL) && (t2 == NULL)) {
  1394     } 
else if (t1 == NULL) {
  1396     } 
else if (t2 == NULL) {
  1420     crm_trace(
"Adding %d seconds to %d (max=%d)",
  1422     a_time->seconds += extra;
  1427     if (a_time->seconds < 0) {
  1438     int lower_bound = 1;
  1441     crm_trace(
"Adding %d days to %.4d-%.3d", extra, a_time->years, a_time->days);
  1443     a_time->days += extra;
  1444     while (a_time->days > ydays) {
  1446         a_time->days -= ydays;
  1450     if(a_time->duration) {
  1454     while (a_time->days < lower_bound) {
  1464     uint32_t y, m, d, dmax;
  1467     crm_trace(
"Adding %d months to %.4d-%.2d-%.2d", extra, y, m, d);
  1470         for (lpc = extra; lpc > 0; lpc--) {
  1478         for (lpc = -extra; lpc > 0; lpc--) {
  1493     crm_trace(
"Calculated %.4d-%.2d-%.2d", y, m, d);
  1496     a_time->days = get_ordinal_days(y, m, d);
  1499     crm_trace(
"Got %.4d-%.2d-%.2d", y, m, d);
  1523     a_time->years += extra;
  1530         .tm_year = source->years - 1900,
  1531         .tm_mday = source->days,
  1532         .tm_sec = source->seconds % 60,
  1533         .tm_min = ( source->seconds / 60 ) % 60,
  1538         .tm_gmtoff = source->offset
  1564             .months = dt->months,
  1566             .seconds = dt->seconds,
  1567             .offset = dt->offset,
  1568             .duration = dt->duration
  1580         .years = hr_dt->
years,
  1582         .days = hr_dt->
days,
  1607     struct timeval tv_now;
  1610         if (gettimeofday(&tv_now, NULL) == 0) {
  1616         dt = parse_date(date_time);
  1633     int max = 128, scanned_pos = 0, printed_pos = 0, fmt_pos = 0,
  1634         date_len = 0, nano_digits = 0;
  1635     char nano_s[10], date_s[max+1], nanofmt_s[5] = 
"%", *tmp_fmt_s;
  1643     ha_get_tm_time(&tm, &dt);
  1644     sprintf(nano_s, 
"%06d000", hr_dt->
useconds);
  1646     while ((format[scanned_pos]) != 
'\0') {
  1647         mark_s = strchr(&format[scanned_pos], 
'%');
  1651             fmt_pos = mark_s - format;
  1652             while ((format[fmt_pos+fmt_len] != 
'\0') &&
  1653                 (format[fmt_pos+fmt_len] >= 
'0') &&
  1654                 (format[fmt_pos+fmt_len] <= 
'9')) {
  1657             scanned_pos = fmt_pos + fmt_len + 1;
  1658             if (format[fmt_pos+fmt_len] == 
'N') {
  1659                 nano_digits = atoi(&format[fmt_pos+1]);
  1660                 nano_digits = (nano_digits > 6)?6:nano_digits;
  1661                 nano_digits = (nano_digits < 0)?0:nano_digits;
  1662                 sprintf(&nanofmt_s[1], 
".%ds", nano_digits);
  1664                 if (format[scanned_pos] != 
'\0') {
  1667                 fmt_pos = scanned_pos; 
  1670             scanned_pos = strlen(format);
  1671             fmt_pos = scanned_pos; 
  1673         tmp_fmt_s = 
strndup(&format[printed_pos], fmt_pos - printed_pos);
  1674 #ifdef GCC_FORMAT_NONLITERAL_CHECKING_ENABLED  1675 #pragma GCC diagnostic push  1676 #pragma GCC diagnostic ignored "-Wformat-nonliteral"  1678         date_len += strftime(&date_s[date_len], max-date_len, tmp_fmt_s, &tm);
  1679 #ifdef GCC_FORMAT_NONLITERAL_CHECKING_ENABLED  1680 #pragma GCC diagnostic pop  1682         printed_pos = scanned_pos;
  1685 #ifdef GCC_FORMAT_NONLITERAL_CHECKING_ENABLED  1686 #pragma GCC diagnostic push  1687 #pragma GCC diagnostic ignored "-Wformat-nonliteral"  1689             date_len += snprintf(&date_s[date_len], max-date_len,
  1691 #ifdef GCC_FORMAT_NONLITERAL_CHECKING_ENABLED  1692 #pragma GCC diagnostic pop  1698     return (date_len == 0)?NULL:strdup(date_s);
  1716     char *since_epoch = NULL;
  1719         time_t a_time = time(NULL);
  1721         if (a_time == (time_t) -1) {
  1724             since_epoch = ctime(&a_time);
  1727         since_epoch = ctime(when);
  1730     if (since_epoch == NULL) {
  1751 #define MS_IN_S (1000)  1752 #define MS_IN_M (MS_IN_S * 60)  1753 #define MS_IN_H (MS_IN_M * 60)  1754 #define MS_IN_D (MS_IN_H * 24)  1755 #define MAXSTR sizeof("..d..h..m..s...ms")  1756     static char str[
MAXSTR] = { 
'\0', };
  1760         offset += snprintf(str + offset, 
MAXSTR - offset, 
"%ud",
  1765         offset += snprintf(str + offset, 
MAXSTR - offset, 
"%uh",
  1770         offset += snprintf(str + offset, 
MAXSTR - offset, 
"%um",
  1777         offset += snprintf(str + offset, 
MAXSTR - offset, 
"%u",
  1780         if (interval_ms > 0) {
  1781             offset += snprintf(str + offset, 
MAXSTR - offset, 
".%03u",
  1784         (void) snprintf(str + offset, 
MAXSTR - offset, 
"s");
  1786     } 
else if (interval_ms > 0) {
  1787         (void) snprintf(str + offset, 
MAXSTR - offset, 
"%ums", interval_ms);
  1789     } 
else if (str[0] == 
'\0') {
 
#define CRM_CHECK(expr, failure_action)
 
crm_time_t * crm_time_new_undefined()
Allocate memory for an uninitialized time object. 
 
crm_time_t * pcmk_copy_time(crm_time_t *source)
 
bool crm_time_leapyear(int year)
 
crm_time_t * crm_time_subtract(crm_time_t *dt, crm_time_t *value)
 
void pcmk__time_hr_free(pcmk__time_hr_t *hr_dt)
 
void crm_time_set_timet(crm_time_t *target, time_t *source)
 
crm_time_t * crm_time_add(crm_time_t *dt, crm_time_t *value)
 
#define crm_time_log_timeofday
 
crm_time_t * crm_time_new(const char *date_time)
 
int crm_time_compare(crm_time_t *a, crm_time_t *b)
 
struct crm_time_s crm_time_t
 
void crm_time_add_minutes(crm_time_t *a_time, int extra)
 
const char * pcmk__readable_interval(guint interval_ms)
 
void crm_time_add_weeks(crm_time_t *a_time, int extra)
 
void crm_time_free(crm_time_t *dt)
 
#define do_cmp_field(l, r, field)
 
#define do_crm_log_alias(level, file, function, line, fmt, args...)
Log a message as if it came from a different code location. 
 
pcmk__time_hr_t * pcmk__time_timeval_hr_convert(pcmk__time_hr_t *target, struct timeval *tv)
 
#define crm_time_log_duration
 
char * strndup(const char *str, size_t len)
 
void crm_time_log_alias(int log_level, const char *file, const char *function, int line, const char *prefix, crm_time_t *date_time, int flags)
 
pcmk__time_hr_t * pcmk__time_hr_new(const char *date_time)
 
struct pcmk__time_us pcmk__time_hr_t
 
crm_time_period_t * crm_time_parse_period(const char *period_str)
Parse a time period from an ISO 8601 interval specification. 
 
int crm_time_get_gregorian(crm_time_t *dt, uint *y, uint *m, uint *d)
 
void crm_time_add_seconds(crm_time_t *a_time, int extra)
Add a given number of seconds to a date/time or duration. 
 
bool crm_time_check(crm_time_t *dt)
Check whether a time object represents a sensible date/time. 
 
long long crm_time_get_seconds(crm_time_t *dt)
 
void crm_time_add_days(crm_time_t *a_time, int extra)
 
#define crm_trace(fmt, args...)
 
#define pcmk_is_set(g, f)
Convenience alias for pcmk_all_flags_set(), to check single flag. 
 
int crm_time_get_isoweek(crm_time_t *dt, uint *y, uint *w, uint *d)
 
crm_time_t * crm_time_parse_duration(const char *period_s)
Parse a time duration from an ISO 8601 duration specification. 
 
void crm_time_add_hours(crm_time_t *a_time, int extra)
 
#define crm_time_log(level, prefix, dt, flags)
 
int crm_time_days_in_month(int month, int year)
Return number of days in given month of given year. 
 
#define crm_time_log_with_timezone
 
int crm_time_get_timezone(crm_time_t *dt, uint *h, uint *m)
 
char * pcmk__time_format_hr(const char *format, pcmk__time_hr_t *hr_dt)
 
void crm_time_add_years(crm_time_t *a_time, int extra)
 
bool crm_time_is_defined(const crm_time_t *t)
Check whether a time object has been initialized yet. 
 
#define HAVE_STRUCT_TM_TM_GMTOFF
 
long long crm_time_get_seconds_since_epoch(crm_time_t *dt)
 
#define crm_err(fmt, args...)
 
void crm_time_add_months(crm_time_t *a_time, int extra)
 
int crm_time_weeks_in_year(int year)
 
int crm_time_january1_weekday(int year)
 
const char * pcmk__epoch2str(time_t *when)
 
#define pcmk__plural_s(i)
 
void pcmk__time_set_hr_dt(crm_time_t *target, pcmk__time_hr_t *hr_dt)
 
crm_time_t * crm_time_calculate_duration(crm_time_t *dt, crm_time_t *value)
 
int crm_time_get_ordinal(crm_time_t *dt, uint *y, uint *d)
 
char * pcmk__trim(char *str)
 
char * crm_time_as_string(crm_time_t *date_time, int flags)
 
void crm_time_free_period(crm_time_period_t *period)
Free a dynamically allocated time period object. 
 
#define crm_time_log_date
 
pcmk__time_hr_t * pcmk__time_hr_convert(pcmk__time_hr_t *target, crm_time_t *dt)
 
int crm_time_get_timeofday(crm_time_t *dt, uint *h, uint *m, uint *s)
 
void crm_time_set(crm_time_t *target, crm_time_t *source)