X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fdate.c;h=af9485b7436f2210181f5ff4bb8c6ca29d78e049;hb=158d982669d3d05079da2b9cc8d8fcd8adf35a4b;hp=b24e09c0a19c075f0f9e8bb998ffed0ba5d43f81;hpb=2e308957d452b440cf404b914ce1cb53c9e739a9;p=platform%2Fupstream%2Fcoreutils.git diff --git a/src/date.c b/src/date.c index b24e09c..af9485b 100644 --- a/src/date.c +++ b/src/date.c @@ -1,6 +1,5 @@ /* date - print or set the system date and time - Copyright (C) 89, 90, 91, 92, 93, 94, 95, 96, 1997 - Free Software Foundation, Inc. + Copyright (C) 1989-2005 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -14,7 +13,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, - Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. David MacKenzie */ @@ -22,99 +21,243 @@ #include #include #include +#if HAVE_LANGINFO_CODESET +# include +#endif #include "system.h" -#include "getline.h" +#include "argmatch.h" #include "error.h" #include "getdate.h" +#include "getline.h" +#include "inttostr.h" +#include "posixtm.h" +#include "quote.h" +#include "stat-time.h" +#include "fprintftime.h" -#ifndef STDC_HEADERS -size_t strftime (); -time_t time (); -#endif +/* The official name of this program (e.g., no `g' prefix). */ +#define PROGRAM_NAME "date" + +#define AUTHORS "David MacKenzie" int putenv (); -int stime (); -char *xstrdup (); -time_t posixtime (); +static bool show_date (const char *format, struct timespec when); -static void show_date PARAMS ((const char *format, time_t when)); -static void usage PARAMS ((int status)); +enum Time_spec +{ + /* Display only the date. */ + TIME_SPEC_DATE, + /* Display date, hours, minutes, and seconds. */ + TIME_SPEC_SECONDS, + /* Similar, but display nanoseconds. */ + TIME_SPEC_NS, + + /* Put these last, since they aren't valid for --rfc-3339. */ + + /* Display date and hour. */ + TIME_SPEC_HOURS, + /* Display date, hours, and minutes. */ + TIME_SPEC_MINUTES +}; -/* The name this program was run with, for error messages. */ -char *program_name; +static char const *const time_spec_string[] = +{ + /* Put "hours" and "minutes" first, since they aren't valid for + --rfc-3339. */ + "hours", "minutes", + "date", "seconds", "ns", NULL +}; +static enum Time_spec const time_spec[] = +{ + TIME_SPEC_HOURS, TIME_SPEC_MINUTES, + TIME_SPEC_DATE, TIME_SPEC_SECONDS, TIME_SPEC_NS +}; +ARGMATCH_VERIFY (time_spec_string, time_spec); -/* If nonzero, display usage information and exit. */ -static int show_help; +/* A format suitable for Internet RFC 2822. */ +static char const rfc_2822_format[] = "%a, %d %b %Y %H:%M:%S %z"; -/* If nonzero, print the version on standard output and exit. */ -static int show_version; +/* The name this program was run with, for error messages. */ +char *program_name; -/* If non-zero, display time in RFC-822 format for mail or news. */ -static int rfc_format = 0; +/* For long options that have no equivalent short option, use a + non-character as a pseudo short option, starting with CHAR_MAX + 1. */ +enum +{ + RFC_3339_OPTION = CHAR_MAX + 1 +}; -/* If nonzero, print or set Coordinated Universal Time. */ -static int universal_time = 0; +static char const short_options[] = "d:f:I::r:Rs:u"; static struct option const long_options[] = { {"date", required_argument, NULL, 'd'}, {"file", required_argument, NULL, 'f'}, - {"help", no_argument, &show_help, 1}, + {"iso-8601", optional_argument, NULL, 'I'}, /* Deprecated. */ {"reference", required_argument, NULL, 'r'}, {"rfc-822", no_argument, NULL, 'R'}, + {"rfc-2822", no_argument, NULL, 'R'}, + {"rfc-3339", required_argument, NULL, RFC_3339_OPTION}, {"set", required_argument, NULL, 's'}, {"uct", no_argument, NULL, 'u'}, {"utc", no_argument, NULL, 'u'}, {"universal", no_argument, NULL, 'u'}, - {"version", no_argument, &show_version, 1}, + {GETOPT_HELP_OPTION_DECL}, + {GETOPT_VERSION_OPTION_DECL}, {NULL, 0, NULL, 0} }; -#define TZ_UTC0 "TZ=UTC0" - #if LOCALTIME_CACHE # define TZSET tzset () #else # define TZSET /* empty */ #endif -#define MAYBE_SET_TZ_UTC0 \ - do { if (universal_time) set_tz (TZ_UTC0); } while (0) - -/* Set the TZ environment variable. */ +#ifdef _DATE_FMT +# define DATE_FMT_LANGINFO() nl_langinfo (_DATE_FMT) +#else +# define DATE_FMT_LANGINFO() "" +#endif -static void -set_tz (const char *tz_eq_zone) +void +usage (int status) { - if (putenv (tz_eq_zone) != 0) - error (1, 0, "memory exhausted"); - TZSET; + if (status != EXIT_SUCCESS) + fprintf (stderr, _("Try `%s --help' for more information.\n"), + program_name); + else + { + printf (_("\ +Usage: %s [OPTION]... [+FORMAT]\n\ + or: %s [-u|--utc|--universal] [MMDDhhmm[[CC]YY][.ss]]\n\ +"), + program_name, program_name); + fputs (_("\ +Display the current time in the given FORMAT, or set the system date.\n\ +\n\ + -d, --date=STRING display time described by STRING, not `now'\n\ + -f, --file=DATEFILE like --date once for each line of DATEFILE\n\ +"), stdout); + fputs (_("\ + -r, --reference=FILE display the last modification time of FILE\n\ + -R, --rfc-2822 output date and time in RFC 2822 format\n\ + --rfc-3339=TIMESPEC output date and time in RFC 3339 format.\n\ + TIMESPEC=`date', `seconds', or `ns' for\n\ + date and time to the indicated precision.\n\ + -s, --set=STRING set time described by STRING\n\ + -u, --utc, --universal print or set Coordinated Universal Time\n\ +"), stdout); + fputs (HELP_OPTION_DESCRIPTION, stdout); + fputs (VERSION_OPTION_DESCRIPTION, stdout); + fputs (_("\ +\n\ +FORMAT controls the output. The only valid option for the second form\n\ +specifies Coordinated Universal Time. Interpreted sequences are:\n\ +\n\ + %% a literal %\n\ + %a locale's abbreviated weekday name (e.g., Sun)\n\ +"), stdout); + fputs (_("\ + %A locale's full weekday name (e.g., Sunday)\n\ + %b locale's abbreviated month name (e.g., Jan)\n\ + %B locale's full month name (e.g., January)\n\ + %c locale's date and time (e.g., Thu Mar 3 23:05:25 2005)\n\ +"), stdout); + fputs (_("\ + %C century; like %Y, except omit last two digits (e.g., 21)\n\ + %d day of month (e.g, 01)\n\ + %D date; same as %m/%d/%y\n\ + %e day of month, space padded; same as %_d\n\ +"), stdout); + fputs (_("\ + %F full date; same as %Y-%m-%d\n\ + %g the last two digits of the year corresponding to the %V week number\n\ + %G the year corresponding to the %V week number\n\ +"), stdout); + fputs (_("\ + %h same as %b\n\ + %H hour (00..23)\n\ + %I hour (01..12)\n\ + %j day of year (001..366)\n\ +"), stdout); + fputs (_("\ + %k hour ( 0..23)\n\ + %l hour ( 1..12)\n\ + %m month (01..12)\n\ + %M minute (00..59)\n\ +"), stdout); + fputs (_("\ + %n a newline\n\ + %N nanoseconds (000000000..999999999)\n\ + %p locale's equivalent of either AM or PM; blank if not known\n\ + %P like %p, but lower case\n\ + %r locale's 12-hour clock time (e.g., 11:11:04 PM)\n\ + %R 24-hour hour and minute; same as %H:%M\n\ + %s seconds since 1970-01-01 00:00:00 UTC\n\ +"), stdout); + fputs (_("\ + %S second (00..60)\n\ + %t a tab\n\ + %T time; same as %H:%M:%S\n\ + %u day of week (1..7); 1 is Monday\n\ +"), stdout); + fputs (_("\ + %U week number of year with Sunday as first day of week (00..53)\n\ + %V week number of year with Monday as first day of week (01..53)\n\ + %w day of week (0..6); 0 is Sunday\n\ + %W week number of year with Monday as first day of week (00..53)\n\ +"), stdout); + fputs (_("\ + %x locale's date representation (e.g., 12/31/99)\n\ + %X locale's time representation (e.g., 23:13:48)\n\ + %y last two digits of year (00..99)\n\ + %Y year\n\ +"), stdout); + fputs (_("\ + %z +hhmm numeric timezone (e.g., -0400)\n\ + %:z +hh:mm numeric timezone (e.g., -04:00)\n\ + %::z +hh:mm:ss numeric time zone (e.g., -04:00:00)\n\ + %:::z numeric time zone with : to necessary precision (e.g., -04, +05:30)\n\ + %Z alphabetic time zone abbreviation (e.g., EDT)\n\ +\n\ +By default, date pads numeric fields with zeroes.\n\ +The following optional flags may follow `%':\n\ +\n\ + - (hyphen) do not pad the field\n\ + _ (underscore) pad with spaces\n\ + 0 (zero) pad with zeros\n\ + ^ use upper case if possible\n\ + # use opposite case if possible\n\ +"), stdout); + fputs (_("\ +\n\ +After any flags comes an optional field width, as a decimal number;\n\ +then an optional modifier, which is either\n\ +E to use the locale's alternate representations if available, or\n\ +O to use the locale's alternate numeric symbols if available.\n\ +"), stdout); + printf (_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT); + } + exit (status); } /* 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. - If any line cannot be parsed, return nonzero; otherwise return zero. */ + Return true if successful. */ -static int +static bool batch_convert (const char *input_filename, const char *format) { - int status; + bool ok; FILE *in_stream; char *line; - int line_length; size_t buflen; - time_t when; - char *initial_TZ; + struct timespec when; -#ifdef lint - /* Suppress `may be used before initialized' warning. */ - initial_TZ = NULL; -#endif - - if (strcmp (input_filename, "-") == 0) + if (STREQ (input_filename, "-")) { input_filename = _("standard input"); in_stream = stdin; @@ -124,71 +267,41 @@ batch_convert (const char *input_filename, const char *format) in_stream = fopen (input_filename, "r"); if (in_stream == NULL) { - error (1, errno, "`%s'", input_filename); + error (EXIT_FAILURE, errno, "%s", quote (input_filename)); } } line = NULL; buflen = 0; - - if (universal_time) - { - initial_TZ = getenv ("TZ"); - if (initial_TZ == NULL) - { - initial_TZ = xstrdup ("TZ="); - } - else - { - size_t tz_len = strlen (initial_TZ); - char *buf = xmalloc (3 + tz_len + 1); - mempcpy (mempcpy (buf, "TZ=", 3), initial_TZ, tz_len + 1); - initial_TZ = buf; - } - } - - status = 0; + ok = true; while (1) { - line_length = getline (&line, &buflen, in_stream); + ssize_t line_length = getline (&line, &buflen, in_stream); if (line_length < 0) { /* FIXME: detect/handle error here. */ break; } - if (universal_time) - { - /* When given a universal time option, restore the initial - value of TZ before parsing each string. */ - set_tz (initial_TZ); - } - - when = get_date (line, NULL); - - if (when == -1) + if (! get_date (&when, line, NULL)) { if (line[line_length - 1] == '\n') line[line_length - 1] = '\0'; - error (0, 0, _("invalid date ` %s'"), line); - status = 1; + error (0, 0, _("invalid date %s"), quote (line)); + ok = false; } else { - MAYBE_SET_TZ_UTC0; - show_date (format, when); + ok &= show_date (format, when); } } - free (initial_TZ); - if (fclose (in_stream) == EOF) - error (2, errno, input_filename); + error (EXIT_FAILURE, errno, "%s", quote (input_filename)); - if (line != NULL) - free (line); + free (line); - return status; + return ok; } int @@ -197,60 +310,98 @@ main (int argc, char **argv) int optc; const char *datestr = NULL; const char *set_datestr = NULL; - time_t when; - int set_date = 0; - char *format; + struct timespec when; + bool set_date = false; + char const *format = NULL; char *batch_file = NULL; char *reference = NULL; struct stat refstats; - int n_args; - int status; + bool ok; int option_specified_date; + initialize_main (&argc, &argv); program_name = argv[0]; setlocale (LC_ALL, ""); bindtextdomain (PACKAGE, LOCALEDIR); textdomain (PACKAGE); - while ((optc = getopt_long (argc, argv, "d:f:r:Rs:u", long_options, NULL)) + atexit (close_stdout); + + while ((optc = getopt_long (argc, argv, short_options, long_options, NULL)) != -1) - switch (optc) - { - case 0: - break; - case 'd': - datestr = optarg; - break; - case 'f': - batch_file = optarg; - break; - case 'r': - reference = optarg; - break; - case 'R': - rfc_format = 1; - break; - case 's': - set_datestr = optarg; - set_date = 1; - break; - case 'u': - universal_time = 1; - break; - default: - usage (1); - } - - if (show_version) { - printf ("date (%s) %s\n", GNU_PACKAGE, VERSION); - exit (0); - } + char const *new_format = NULL; - if (show_help) - usage (0); + switch (optc) + { + case 'd': + datestr = optarg; + break; + case 'f': + batch_file = optarg; + break; + case RFC_3339_OPTION: + { + static char const rfc_3339_format[][32] = + { + "%Y-%m-%d", + "%Y-%m-%d %H:%M:%S%:z", + "%Y-%m-%d %H:%M:%S.%N%:z" + }; + enum Time_spec i = + XARGMATCH ("--rfc-3339", optarg, + time_spec_string + 2, time_spec + 2); + new_format = rfc_3339_format[i]; + break; + } + case 'I': + { + static char const iso_8601_format[][32] = + { + "%Y-%m-%d", + "%Y-%m-%dT%H:%M:%S%z", + "%Y-%m-%dT%H:%M:%S,%N%z", + "%Y-%m-%dT%H%z", + "%Y-%m-%dT%H:%M%z" + }; + enum Time_spec i = + (optarg + ? XARGMATCH ("--iso-8601", optarg, time_spec_string, time_spec) + : TIME_SPEC_DATE); + new_format = iso_8601_format[i]; + break; + } + case 'r': + reference = optarg; + break; + case 'R': + new_format = rfc_2822_format; + break; + case 's': + set_datestr = optarg; + set_date = true; + break; + case 'u': + /* POSIX says that `date -u' is equivalent to setting the TZ + environment variable, so this option should do nothing other + than setting TZ. */ + if (putenv ("TZ=UTC0") != 0) + xalloc_die (); + TZSET; + break; + case_GETOPT_HELP_CHAR; + case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS); + default: + usage (EXIT_FAILURE); + } - n_args = argc - optind; + if (new_format) + { + if (format) + error (EXIT_FAILURE, 0, _("multiple output formats specified")); + format = new_format; + } + } option_specified_date = ((datestr ? 1 : 0) + (batch_file ? 1 : 0) @@ -260,62 +411,82 @@ main (int argc, char **argv) { error (0, 0, _("the options to specify dates for printing are mutually exclusive")); - usage (1); + usage (EXIT_FAILURE); } if (set_date && option_specified_date) { error (0, 0, _("the options to print and set the time may not be used together")); - usage (1); + usage (EXIT_FAILURE); } - if (n_args > 1) + if (optind < argc) { - error (0, 0, _("too many non-option arguments")); - usage (1); + if (optind + 1 < argc) + { + error (0, 0, _("extra operand %s"), quote (argv[optind + 1])); + usage (EXIT_FAILURE); + } + + if (argv[optind][0] == '+') + { + if (format) + error (EXIT_FAILURE, 0, _("multiple output formats specified")); + format = argv[optind++] + 1; + } + else if (set_date || option_specified_date) + { + error (0, 0, + _("the argument %s lacks a leading `+';\n" + "When using an option to specify date(s), any non-option\n" + "argument must be a format string beginning with `+'."), + quote (argv[optind])); + usage (EXIT_FAILURE); + } } - if ((set_date || option_specified_date) - && n_args == 1 && argv[optind][0] != '+') + if (!format) { - error (0, 0, _("\ -the argument `%s' lacks a leading `+';\n\ -When using an option to specify date(s), any non-option\n\ -argument must be a format string beginning with `+'."), - argv[optind]); - usage (1); + format = DATE_FMT_LANGINFO (); + if (! *format) + { + /* Do not wrap the following literal format string with _(...). + For example, suppose LC_ALL is unset, LC_TIME="POSIX", + and LANG="ko_KR". In that case, POSIX says that LC_TIME + determines the format and contents of date and time strings + written by date, which means "date" must generate output + using the POSIX locale; but adding _() would cause "date" + to use a Korean translation of the format. */ + format = "%a %b %e %H:%M:%S %Z %Y"; + } } - if (set_date) - datestr = set_datestr; - if (batch_file != NULL) - { - status = batch_convert (batch_file, - (n_args == 1 ? argv[optind] + 1 : NULL)); - } + ok = batch_convert (batch_file, format); else { - status = 0; + bool valid_date = true; + ok = true; if (!option_specified_date && !set_date) { - if (n_args == 1 && argv[optind][0] != '+') + if (optind < argc) { /* Prepare to set system clock to the specified date/time given in the POSIX-format. */ - set_date = 1; + set_date = true; datestr = argv[optind]; - when = posixtime (datestr); - format = NULL; + valid_date = posixtime (&when.tv_sec, + datestr, + (PDS_TRAILING_YEAR + | PDS_CENTURY | PDS_SECONDS)); + when.tv_nsec = 0; /* FIXME: posixtime should set this. */ } else { /* Prepare to print the current date/time. */ - datestr = _("undefined"); - time (&when); - format = (n_args == 1 ? argv[optind] + 1 : NULL); + gettime (&when); } } else @@ -323,165 +494,66 @@ argument must be a format string beginning with `+'."), /* (option_specified_date || set_date) */ if (reference != NULL) { - if (stat (reference, &refstats)) - error (1, errno, "%s", reference); - when = refstats.st_mtime; + if (stat (reference, &refstats) != 0) + error (EXIT_FAILURE, errno, "%s", reference); + when = get_stat_mtime (&refstats); } else { - when = get_date (datestr, NULL); + if (set_datestr) + datestr = set_datestr; + valid_date = get_date (&when, datestr, NULL); } - - format = (n_args == 1 ? argv[optind] + 1 : NULL); } - if (when == -1) - error (1, 0, _("invalid date `%s'"), datestr); + if (! valid_date) + error (EXIT_FAILURE, 0, _("invalid date %s"), quote (datestr)); if (set_date) { /* Set the system clock to the specified date, then regardless of the success of that operation, format and print that date. */ - if (stime (&when) == -1) - error (0, errno, _("cannot set date")); + if (settime (&when) != 0) + { + error (0, errno, _("cannot set date")); + ok = false; + } } - /* When given a universal time option, set TZ to UTC0 after - parsing the specified date, but before printing it. */ - MAYBE_SET_TZ_UTC0; - - show_date (format, when); + ok &= show_date (format, when); } - if (fclose (stdout) == EOF) - error (2, errno, _("write error")); - - exit (status); + exit (ok ? EXIT_SUCCESS : EXIT_FAILURE); } /* Display the date and/or time in WHEN according to the format specified in FORMAT, followed by a newline. If FORMAT is NULL, use the - standard output format (ctime style but with a timezone inserted). */ + standard output format (ctime style but with a timezone inserted). + Return true if successful. */ -static void -show_date (const char *format, time_t when) +static bool +show_date (const char *format, struct timespec when) { struct tm *tm; - char *out = NULL; - size_t out_length = 0; - - tm = localtime (&when); - if (format == NULL) + tm = localtime (&when.tv_sec); + if (! tm) { - /* Print the date in the default format. Vanilla ANSI C strftime - doesn't support %e, but POSIX requires it. If you don't use - a GNU strftime, make sure yours supports %e. - If you are not using GNU strftime, you want to change %z - in the RFC format to %Z; this gives, however, an invalid - RFC time format outside the continental United States and GMT. */ - - format = (rfc_format - ? (universal_time - ? "%a, %_d %b %Y %H:%M:%S GMT" - : "%a, %_d %b %Y %H:%M:%S %z") - : "%a %b %e %H:%M:%S %Z %Y"); + char buf[INT_BUFSIZE_BOUND (intmax_t)]; + error (0, 0, _("time %s is out of range"), + (TYPE_SIGNED (time_t) + ? imaxtostr (when.tv_sec, buf) + : umaxtostr (when.tv_sec, buf))); + return false; } - else if (*format == '\0') - { - printf ("\n"); - return; - } - - do - { - out_length += 200; - out = (char *) xrealloc (out, out_length); - - /* Mark the first byte of the buffer so we can detect the case - of strftime producing an empty string. Otherwise, this loop - would not terminate when date was invoked like this - `LANG=de date +%p' on a system with good language support. */ - out[0] = '\1'; - } - while (strftime (out, out_length, format, tm) == 0 && out[0] != '\0'); - - printf ("%s\n", out); - free (out); -} -static void -usage (int status) -{ - if (status != 0) - fprintf (stderr, _("Try `%s --help' for more information.\n"), - program_name); - else - { - printf (_("\ -Usage: %s [OPTION]... [+FORMAT]\n\ - or: %s [OPTION] [MMDDhhmm[[CC]YY][.ss]]\n\ -"), - program_name, program_name); - printf (_("\ -Display the current time in the given FORMAT, or set the system date.\n\ -\n\ - -d, --date=STRING display time described by STRING, not `now'\n\ - -f, --file=DATEFILE like --date once for each line of DATEFILE\n\ - -r, --reference=FILE display the last modification time of FILE\n\ - -R, --rfc-822 output RFC-822 compliant date string\n\ - -s, --set=STRING set time described by STRING\n\ - -u, --utc, --universal print or set Coordinated Universal Time\n\ - --help display this help and exit\n\ - --version output version information and exit\n\ -")); - printf (_("\ -\n\ -FORMAT controls the output. The only valid option for the second form\n\ -specifies Coordinated Universal Time. Interpreted sequences are:\n\ -\n\ - %%%% a literal %%\n\ - %%a locale's abbreviated weekday name (Sun..Sat)\n\ - %%A locale's full weekday name, variable length (Sunday..Saturday)\n\ - %%b locale's abbreviated month name (Jan..Dec)\n\ - %%B locale's full month name, variable length (January..December)\n\ - %%c locale's date and time (Sat Nov 04 12:02:33 EST 1989)\n\ - %%d day of month (01..31)\n\ - %%D date (mm/dd/yy)\n\ - %%e day of month, blank padded ( 1..31)\n\ - %%h same as %%b\n\ - %%H hour (00..23)\n\ - %%I hour (01..12)\n\ - %%j day of year (001..366)\n\ - %%k hour ( 0..23)\n\ - %%l hour ( 1..12)\n\ - %%m month (01..12)\n\ - %%M minute (00..59)\n\ - %%n a newline\n\ - %%p locale's AM or PM\n\ - %%r time, 12-hour (hh:mm:ss [AP]M)\n\ - %%s seconds since 00:00:00, Jan 1, 1970 (a GNU extension)\n\ - %%S second (00..61)\n\ - %%t a horizontal tab\n\ - %%T time, 24-hour (hh:mm:ss)\n\ - %%U week number of year with Sunday as first day of week (00..53)\n\ - %%V week number of year with Monday as first day of week (01..52)\n\ - %%w day of week (0..6); 0 represents Sunday\n\ - %%W week number of year with Monday as first day of week (00..53)\n\ - %%x locale's date representation (mm/dd/yy)\n\ - %%X locale's time representation (%%H:%%M:%%S)\n\ - %%y last two digits of year (00..99)\n\ - %%Y year (1970...)\n\ - %%z RFC-822 style numeric timezone (-0500) (a nonstandard extension)\n\ - %%Z time zone (e.g., EDT), or nothing if no time zone is determinable\n\ -\n\ -By default, date pads numeric fields with zeroes. GNU date recognizes\n\ -the following modifiers between `%%' and a numeric directive.\n\ -\n\ - `-' (hyphen) do not pad the field\n\ - `_' (underscore) pad the field with spaces\n\ -")); - puts (_("\nReport bugs to .")); - } - exit (status); + { + if (format == rfc_2822_format) + setlocale (LC_TIME, "C"); + fprintftime (stdout, format, tm, 0, when.tv_nsec); + fputc ('\n', stdout); + if (format == rfc_2822_format) + setlocale (LC_TIME, ""); + } + return true; }