+ if (t == (time_t) -1)
+ {
+ /* Guard against falsely reporting an error when parsing a time
+ stamp that happens to equal (time_t) -1, on a host that
+ supports such a time stamp. */
+ tm1 = localtime (&t);
+ if (!tm1)
+ return false;
+ }
+
+ return ! ((tm0->tm_sec ^ tm1->tm_sec)
+ | (tm0->tm_min ^ tm1->tm_min)
+ | (tm0->tm_hour ^ tm1->tm_hour)
+ | (tm0->tm_mday ^ tm1->tm_mday)
+ | (tm0->tm_mon ^ tm1->tm_mon)
+ | (tm0->tm_year ^ tm1->tm_year));
+}
+
+/* A reasonable upper bound for the size of ordinary TZ strings.
+ Use heap allocation if TZ's length exceeds this. */
+enum { TZBUFSIZE = 100 };
+
+/* Return a copy of TZ, stored in TZBUF if it fits, and heap-allocated
+ otherwise. */
+static char *
+get_tz (char tzbuf[TZBUFSIZE])
+{
+ char *tz = getenv ("TZ");
+ if (tz)
+ {
+ size_t tzsize = strlen (tz) + 1;
+ tz = (tzsize <= TZBUFSIZE
+ ? memcpy (tzbuf, tz, tzsize)
+ : xmemdup (tz, tzsize));
+ }
+ return tz;
+}
+
+/* Parse a date/time string, storing the resulting time value into *RESULT.
+ The string itself is pointed to by P. Return true if successful.
+ P can be an incomplete or relative time specification; if so, use
+ *NOW as the basis for the returned time. */
+bool
+get_date (struct timespec *result, char const *p, struct timespec const *now)
+{
+ time_t Start;
+ long int Start_ns;
+ struct tm const *tmp;