Commit a244f556 authored by Eric S. Raymond's avatar Eric S. Raymond

RFC3339/ISO8601 date formats everywhere.

As a side effect, we have to give up support for parsing RT-11 timestamps
in ntpq. Farewell, fuzzballs!
parent d0eb77ee
......@@ -95,6 +95,11 @@ object. You can read about JSON at
Be aware that if you present a tool design with a messy output format
and no JSON option it is quite likely to be rejected.
Our preferred format for dates is RFC3339 (a version of ISO8601 for
UTC with some options frozen; full year required, medial T required,
explicit Zulu timezone). Local times should be expressed in ISO8601,
always with full years and timezone offset.
=== Copyrights and licenses ===
Much of the historic code in this distribution is under an "NTP
......
......@@ -27,8 +27,8 @@ humanlogtime(void)
LIB_GETBUF(bp);
snprintf(bp, LIB_BUFLENGTH, "%2d %s %02d:%02d:%02d",
tm->tm_mday, months[tm->tm_mon],
snprintf(bp, LIB_BUFLENGTH, "%02d-%02d%02d:%02d:%02d",
tm->tm_mon+1, tm->tm_mday,
tm->tm_hour, tm->tm_min, tm->tm_sec);
return bp;
......
......@@ -18,15 +18,6 @@
static char *common_prettydate(l_fp *, bool);
const char * const months[12] = {
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};
const char * const daynames[7] = {
"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
};
/* Helper function to handle possible wraparound of the ntp epoch.
*
* Works by periodic extension of the ntp time stamp in the UN*X epoch.
......@@ -132,9 +123,9 @@ common_prettydate(
)
{
static const char pfmt0[] =
"%08lx.%08lx %s, %s %2d %4d %2d:%02d:%02d.%03u";
"%08lx.%08lx %04d-%02d-%02dT%02d:%02d:%02d.%03u";
static const char pfmt1[] =
"%08lx.%08lx [%s, %s %2d %4d %2d:%02d:%02d.%03u UTC]";
"%08lx.%08lx %04d-%02d-%02dT02d:%02d:%02d.%03uZ";
char *bp;
struct tm *tm;
......@@ -162,15 +153,13 @@ common_prettydate(
ntpcal_time_to_date(&jd, &sec);
snprintf(bp, LIB_BUFLENGTH, local ? pfmt1 : pfmt0,
(u_long)ts->l_ui, (u_long)ts->l_uf,
daynames[jd.weekday], months[jd.month-1],
jd.monthday, jd.year, jd.hour,
jd.minute, jd.second, msec);
jd.year, jd.month, jd.monthday,
jd.hour, jd.minute, jd.second, msec);
} else
snprintf(bp, LIB_BUFLENGTH, pfmt0,
(u_long)ts->l_ui, (u_long)ts->l_uf,
daynames[tm->tm_wday], months[tm->tm_mon],
tm->tm_mday, 1900 + tm->tm_year, tm->tm_hour,
tm->tm_min, tm->tm_sec, msec);
1900 + tm->tm_year, tm->tm_mon+1, tm->tm_mday,
tm->tm_hour, tm->tm_min, tm->tm_sec, msec);
return bp;
}
......
......@@ -3141,8 +3141,8 @@ oncore_msg_Gb(
gmtm = buf[13];
oncore_log_f(instance, LOG_NOTICE,
"Date/Time set to: %d%s%d %2d:%02d:%02d GMT (GMT offset is %s%02d:%02d)",
d, months[mo-1], y, h, m, s, gmts, gmth, gmtm);
"Date/Time set to: %02d-%02d-%02dT%2d:%02d:%02d%s%02d%02d",
y, mo, d, h, m, s, gmts, gmth, gmtm);
}
......
......@@ -3723,8 +3723,8 @@ mk_utcinfo(
n += snprintf( t, size, "UTC offset transition from %is to %is due to leap second %s",
dtls, dtlsf, ( dtls < dtlsf ) ? "insertion" : "deletion" );
n += snprintf( t + n, size - n, " at UTC midnight at the end of %s, %04i-%02i-%02i",
daynames[tm->tm_wday], tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday );
n += snprintf( t + n, size - n, " at UTC midnight at the end of %04i-%02i-%02i",
tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday );
}
else
snprintf( t, size, "UTC offset parameter: %is, no leap second announced.\n", dtls );
......
......@@ -165,7 +165,6 @@ static bool getarg (const char *, int, arg_v *);
#endif /* BUILD_AS_LIB */
static int findcmd (const char *, struct xcmd *,
struct xcmd *, struct xcmd **);
static bool rtdatetolfp (char *, l_fp *);
static bool decodearr (char *, int *, l_fp *);
static void help (struct parse *, FILE *);
static int helpsort (const void *, const void *);
......@@ -1951,130 +1950,7 @@ nntohostp(
}
/*
* rtdatetolfp - decode an RT-11 date into an l_fp
*/
static bool
rtdatetolfp(
char *str,
l_fp *lfp
)
{
register char *cp;
register int i;
struct calendar cal;
char buf[4];
cal.yearday = 0;
/*
* An RT-11 date looks like:
*
* d[d]-Mth-y[y] hh:mm:ss
*
* (No docs, but assume 4-digit years are also legal...)
*
* d[d]-Mth-y[y[y[y]]] hh:mm:ss
*/
cp = str;
if (!isdigit((int)*cp)) {
if (*cp == '-') {
/*
* Catch special case
*/
L_CLR(lfp);
return true;
}
return false;
}
cal.monthday = (uint8_t) (*cp++ - '0'); /* ascii dependent */
if (isdigit((int)*cp)) {
cal.monthday = (uint8_t)((cal.monthday << 3) + (cal.monthday << 1));
cal.monthday = (uint8_t)(cal.monthday + *cp++ - '0');
}
if (*cp++ != '-')
return false;
for (i = 0; i < 3; i++)
buf[i] = *cp++;
buf[3] = '\0';
for (i = 0; i < 12; i++)
if (STREQ(buf, months[i]))
break;
if (i == 12)
return false;
cal.month = (uint8_t)(i + 1);
if (*cp++ != '-')
return false;
if (!isdigit((int)*cp))
return false;
cal.year = (u_short)(*cp++ - '0');
if (isdigit((int)*cp)) {
cal.year = (u_short)((cal.year << 3) + (cal.year << 1));
cal.year = (u_short)(*cp++ - '0');
}
if (isdigit((int)*cp)) {
cal.year = (u_short)((cal.year << 3) + (cal.year << 1));
cal.year = (u_short)(cal.year + *cp++ - '0');
}
if (isdigit((int)*cp)) {
cal.year = (u_short)((cal.year << 3) + (cal.year << 1));
cal.year = (u_short)(cal.year + *cp++ - '0');
}
/*
* Catch special case. If cal.year == 0 this is a zero timestamp.
*/
if (cal.year == 0) {
L_CLR(lfp);
return true;
}
if (*cp++ != ' ' || !isdigit((int)*cp))
return false;
cal.hour = (uint8_t)(*cp++ - '0');
if (isdigit((int)*cp)) {
cal.hour = (uint8_t)((cal.hour << 3) + (cal.hour << 1));
cal.hour = (uint8_t)(cal.hour + *cp++ - '0');
}
if (*cp++ != ':' || !isdigit((int)*cp))
return false;
cal.minute = (uint8_t)(*cp++ - '0');
if (isdigit((int)*cp)) {
cal.minute = (uint8_t)((cal.minute << 3) + (cal.minute << 1));
cal.minute = (uint8_t)(cal.minute + *cp++ - '0');
}
if (*cp++ != ':' || !isdigit((int)*cp))
return false;
cal.second = (uint8_t)(*cp++ - '0');
if (isdigit((int)*cp)) {
cal.second = (uint8_t)((cal.second << 3) + (cal.second << 1));
cal.second = (uint8_t)(cal.second + *cp++ - '0');
}
/*
* For RT-11, 1972 seems to be the pivot year
*/
if (cal.year < 72)
cal.year += 2000;
if (cal.year < 100)
cal.year += 1900;
lfp->l_ui = caltontp(&cal);
lfp->l_uf = false;
return true;
}
/*
* decodets - decode a timestamp into an l_fp format number, with
* consideration of fuzzball formats.
* decodets - decode a hex or decimal timestamp into an l_fp format number
*/
bool
decodets(
......@@ -2082,29 +1958,12 @@ decodets(
l_fp *lfp
)
{
char *cp;
char buf[30];
size_t b;
/*
* If it starts with a 0x, decode as hex.
*/
if (*str == '0' && (*(str+1) == 'x' || *(str+1) == 'X'))
return hextolfp(str+2, lfp);
/*
* If it starts with a '"', try it as an RT-11 date.
*/
if (*str == '"') {
cp = str + 1;
b = 0;
while ('"' != *cp && '\0' != *cp &&
b < COUNTOF(buf) - 1)
buf[b++] = *cp++;
buf[b] = '\0';
return rtdatetolfp(buf, lfp);
}
/*
* Might still be hex. Check out the first character. Talk
* about heuristics!
......@@ -2119,7 +1978,7 @@ decodets(
if (atolfp(str, lfp))
return true;
return rtdatetolfp(str, lfp);
return false;
}
......
......@@ -23,5 +23,5 @@ protected:
TEST(prettydate, ConstantDate) {
l_fp time = {3485080800UL, HALF}; // 2010-06-09 14:00:00.5
TEST_ASSERT_EQUAL_STRING("cfba1ce0.80000000 Wed, Jun 9 2010 14:00:00.500", gmprettydate(&time));
TEST_ASSERT_EQUAL_STRING("cfba1ce0.80000000 2010-06-09T14:00:00.500", gmprettydate(&time));
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment