📄 date.c
字号:
/* date - print or set the system date and time
Copyright (C) 1989-2002 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
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
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.
David MacKenzie <djm@gnu.ai.mit.edu> */
#include <config.h>
#include <stdio.h>
#include <getopt.h>
#include <sys/types.h>
#if HAVE_LANGINFO_CODESET
# include <langinfo.h>
#endif
#include "system.h"
#include "argmatch.h"
#include "closeout.h"
#include "error.h"
#include "getdate.h"
#include "getline.h"
#include "posixtm.h"
#include "posixver.h"
#include "timespec.h"
/* The official name of this program (e.g., no `g' prefix). */
#define PROGRAM_NAME "date"
#define AUTHORS "David MacKenzie"
int putenv ();
size_t nstrftime PARAMS ((char *, size_t, char const *,
struct tm const *, int, int));
static void show_date PARAMS ((const char *format, struct timespec when));
enum Time_spec
{
/* display only the date: 1999-03-25 */
TIME_SPEC_DATE=1,
/* display date and hour: 1999-03-25T03-0500 */
TIME_SPEC_HOURS,
/* display date, hours, and minutes: 1999-03-25T03:23-0500 */
TIME_SPEC_MINUTES,
/* display date, hours, minutes, and seconds: 1999-03-25T03:23:14-0500 */
TIME_SPEC_SECONDS
};
static char const *const time_spec_string[] =
{
"date", "hours", "minutes", "seconds", 0
};
static enum Time_spec const time_spec[] =
{
TIME_SPEC_DATE, TIME_SPEC_HOURS, TIME_SPEC_MINUTES, TIME_SPEC_SECONDS
};
/* The name this program was run with, for error messages. */
char *program_name;
/* If nonzero, display an ISO 8601 format date/time string */
static int iso_8601_format = 0;
/* If non-zero, display time in RFC-(2)822 format for mail or news. */
static int rfc_format = 0;
#define COMMON_SHORT_OPTIONS "Rd:f:r:s:u"
static struct option const long_options[] =
{
{"date", required_argument, NULL, 'd'},
{"file", required_argument, NULL, 'f'},
{"iso-8601", optional_argument, NULL, 'I'},
{"reference", required_argument, NULL, 'r'},
{"rfc-822", no_argument, NULL, 'R'},
{"set", required_argument, NULL, 's'},
{"uct", no_argument, NULL, 'u'},
{"utc", no_argument, NULL, 'u'},
{"universal", no_argument, NULL, 'u'},
{GETOPT_HELP_OPTION_DECL},
{GETOPT_VERSION_OPTION_DECL},
{NULL, 0, NULL, 0}
};
#if LOCALTIME_CACHE
# define TZSET tzset ()
#else
# define TZSET /* empty */
#endif
#ifdef _DATE_FMT
# define DATE_FMT_LANGINFO() nl_langinfo (_DATE_FMT)
#else
# define DATE_FMT_LANGINFO() ""
#endif
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 [-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\
-ITIMESPEC, --iso-8601[=TIMESPEC] output date/time in ISO 8601 format.\n\
TIMESPEC=`date' for date only,\n\
`hours', `minutes', or `seconds' for date and\n\
time to the indicated precision.\n\
--iso-8601 without TIMESPEC defaults to `date'.\n\
"), stdout);
fputs (_("\
-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\
"), 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 (Sun..Sat)\n\
"), stdout);
fputs (_("\
%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\
"), stdout);
fputs (_("\
%C century (year divided by 100 and truncated to an integer) [00-99]\n\
%d day of month (01..31)\n\
%D date (mm/dd/yy)\n\
%e day of month, blank padded ( 1..31)\n\
"), stdout);
fputs (_("\
%F same as %Y-%m-%d\n\
%g the 2-digit year corresponding to the %V week number\n\
%G the 4-digit 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 upper case AM or PM indicator (blank in many locales)\n\
%P locale's lower case am or pm indicator (blank in many locales)\n\
%r time, 12-hour (hh:mm:ss [AP]M)\n\
%R time, 24-hour (hh:mm)\n\
%s seconds since `00:00:00 1970-01-01 UTC' (a GNU extension)\n\
"), stdout);
fputs (_("\
%S second (00..60); the 60 is necessary to accommodate a leap second\n\
%t a horizontal tab\n\
%T time, 24-hour (hh:mm:ss)\n\
%u day of week (1..7); 1 represents 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 represents Sunday\n\
%W week number of year with Monday as first day of week (00..53)\n\
"), stdout);
fputs (_("\
%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\
"), stdout);
fputs (_("\
%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\
"), 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. */
static int
batch_convert (const char *input_filename, const char *format)
{
int status;
FILE *in_stream;
char *line;
int line_length;
size_t buflen;
struct timespec when;
if (strcmp (input_filename, "-") == 0)
{
input_filename = _("standard input");
in_stream = stdin;
}
else
{
in_stream = fopen (input_filename, "r");
if (in_stream == NULL)
{
error (EXIT_FAILURE, errno, "`%s'", input_filename);
}
}
line = NULL;
buflen = 0;
status = 0;
while (1)
{
line_length = getline (&line, &buflen, in_stream);
if (line_length < 0)
{
/* FIXME: detect/handle error here. */
break;
}
when.tv_sec = get_date (line, NULL);
when.tv_nsec = 0; /* FIXME: get_date should set this. */
if (when.tv_sec == -1)
{
if (line[line_length - 1] == '\n')
line[line_length - 1] = '\0';
error (0, 0, _("invalid date `%s'"), line);
status = 1;
}
else
{
show_date (format, when);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -