aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--NEWS4
-rw-r--r--bootstrap.conf1
-rw-r--r--doc/coreutils.texi6
-rw-r--r--src/date.c40
4 files changed, 49 insertions, 2 deletions
diff --git a/NEWS b/NEWS
index b9d36c724..79320820f 100644
--- a/NEWS
+++ b/NEWS
@@ -34,6 +34,10 @@ GNU coreutils NEWS -*- outline -*-
** Changes in behavior
+ date +'%-N' now suppresses excess trailing digits, instead of always
+ padding them with zeros to 9 digits. It uses clock_getres and
+ clock_gettime to infer the clock resolution.
+
timeout --foreground --kill-after=... will now exit with status 137
if the kill signal was sent, which is consistent with the behavior
when the --foreground option is not specified. This allows users to
diff --git a/bootstrap.conf b/bootstrap.conf
index c2f74f406..afa2cdcb9 100644
--- a/bootstrap.conf
+++ b/bootstrap.conf
@@ -119,6 +119,7 @@ gnulib_modules="
getpass-gnu
gettext-h
gettime
+ gettime-res
getugroups
getusershell
git-version-gen
diff --git a/doc/coreutils.texi b/doc/coreutils.texi
index 49d2afbe2..aa970da6c 100644
--- a/doc/coreutils.texi
+++ b/doc/coreutils.texi
@@ -16227,6 +16227,12 @@ The following optional flags can appear after the @samp{%}:
(hyphen) Do not pad the field; useful if the output is intended for
human consumption.
This is a GNU extension.
+As a special case, @samp{%-N} outputs only enough trailing digits to
+not lose information, assuming that the timestamp's resolution is the
+same as the current hardware clock. For example, if the hardware
+clock resolution is 1 microsecond, @samp{%s.%-N} outputs something
+like @samp{1640890100.395710}.
+
@item _
(underscore) Pad with spaces; useful if you need a fixed
number of characters in the output, but zeros are too distracting.
diff --git a/src/date.c b/src/date.c
index 4a7a4e243..b0a53ba6c 100644
--- a/src/date.c
+++ b/src/date.c
@@ -281,6 +281,39 @@ Show the local time for 9AM next Friday on the west coast of the US\n\
exit (status);
}
+/* Yield the number of decimal digits needed to output a time with the
+ nanosecond resolution RES, without losing information. */
+
+static int
+res_width (long int res)
+{
+ int i = 9;
+ for (long long int r = 1; (r *= 10) <= res; )
+ i--;
+ return i;
+}
+
+/* Return a newly allocated copy of FORMAT with each "%-N" adjusted to
+ be "%9N", "%6N", or whatever other resolution is appropriate for
+ the current platform. If no "%-N" appears, return NULL. */
+
+static char *
+adjust_resolution (char const *format)
+{
+ char *copy = NULL;
+
+ for (char const *f = format; *f; f++)
+ if (f[0] == '%' && f[1] == '-' && f[2] == 'N')
+ {
+ if (!copy)
+ copy = xstrdup (format);
+ copy[f + 1 - format] = '0' + res_width (gettime_res ());
+ f += 2;
+ }
+
+ return copy;
+}
+
/* Parse each line in INPUT_FILENAME as with --date and display each
resulting time and date. If the file cannot be opened, tell why
then exit. Issue a diagnostic for any lines that cannot be parsed.
@@ -505,11 +538,13 @@ main (int argc, char **argv)
}
}
+ char *format_copy = adjust_resolution (format);
+ char const *format_res = format_copy ? format_copy : format;
char const *tzstring = getenv ("TZ");
timezone_t tz = tzalloc (tzstring);
if (batch_file != NULL)
- ok = batch_convert (batch_file, format, tz, tzstring);
+ ok = batch_convert (batch_file, format_res, tz, tzstring);
else
{
bool valid_date = true;
@@ -568,10 +603,11 @@ main (int argc, char **argv)
}
}
- ok &= show_date (format, when, tz);
+ ok &= show_date (format_res, when, tz);
}
IF_LINT (tzfree (tz));
+ IF_LINT (free (format_copy));
return ok ? EXIT_SUCCESS : EXIT_FAILURE;
}