Subject: bug#17451: Let's patch 'date' to suggest the FAQ for invalid date formats

From: Paul Eggert <[email-masked]>
Date: Sat, 10 May 2014 12:23:19 -0700

This topic comes up often enough that I'm inclined to add an FAQ pointer 
into that diagnostic issued by 'date'.  Proposed patch is attached.  I 
suppose we could try for a more-stable URL, but one step at a time.
From 71f4e27b983b84589c06af234a071e1b36846699 Mon Sep 17 00:00:00 2001
From: Paul Eggert <[email-masked]>
Date: Sat, 10 May 2014 12:15:22 -0700
Subject: [PATCH] date: point people at the FAQ for invalid date formats

* src/date.c (invalid_date): New function.
(batch_convert, main): Use it.
---
 src/date.c | 41 +++++++++++++++++++++++++----------------
 1 file changed, 25 insertions(+), 16 deletions(-)

diff --git a/src/date.c b/src/date.c
index ef04cb5..d241228 100644
--- a/src/date.c
+++ b/src/date.c
@@ -260,6 +260,16 @@ Show the local time for 9AM next Friday on the west coast of the US\n\
   exit (status);
 }
 
+static void
+invalid_date (char const *date, bool show_help)
+{
+  error (0, 0, _("invalid date %s"), quote (date));
+  if (show_help)
+    error (0, 0, _("For help with date formats, please see:\n%s"),
+           ("http://www.gnu.org/software/coreutils/faq/coreutils-faq.html"
+            "#The-date-command-is-not-working-right_002e"));
+}
+
 /* 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.
@@ -268,11 +278,7 @@ Show the local time for 9AM next Friday on the west coast of the US\n\
 static bool
 batch_convert (const char *input_filename, const char *format)
 {
-  bool ok;
   FILE *in_stream;
-  char *line;
-  size_t buflen;
-  struct timespec when;
 
   if (STREQ (input_filename, "-"))
     {
@@ -288,9 +294,10 @@ batch_convert (const char *input_filename, const char *format)
         }
     }
 
-  line = NULL;
-  buflen = 0;
-  ok = true;
+  char *line = NULL;
+  size_t buflen = 0;
+  bool ok = true;
+  bool show_help = true;
   while (1)
     {
       ssize_t line_length = getline (&line, &buflen, in_stream);
@@ -300,16 +307,15 @@ batch_convert (const char *input_filename, const char *format)
           break;
         }
 
-      if (! parse_datetime (&when, line, NULL))
+      struct timespec when;
+      if (parse_datetime (&when, line, NULL))
+        ok &= show_date (format, when);
+      else
         {
           if (line[line_length - 1] == '\n')
             line[line_length - 1] = '\0';
-          error (0, 0, _("invalid date %s"), quote (line));
-          ok = false;
-        }
-      else
-        {
-          ok &= show_date (format, when);
+          invalid_date (line, show_help);
+          ok = show_help = false;
         }
     }
 
@@ -524,7 +530,10 @@ main (int argc, char **argv)
         }
 
       if (! valid_date)
-        error (EXIT_FAILURE, 0, _("invalid date %s"), quote (datestr));
+        {
+          invalid_date (datestr, true);
+          return EXIT_FAILURE;
+        }
 
       if (set_date)
         {
@@ -540,7 +549,7 @@ main (int argc, char **argv)
       ok &= show_date (format, when);
     }
 
-  exit (ok ? EXIT_SUCCESS : EXIT_FAILURE);
+  return ok ? EXIT_SUCCESS : EXIT_FAILURE;
 }
 
 /* Display the date and/or time in WHEN according to the format specified
-- 
1.9.0