⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 date.c

📁 linux下一些命令的c语言的实现
💻 C
📖 第 1 页 / 共 2 页
字号:
	}
    }

  if (fclose (in_stream) == EOF)
    error (2, errno, "`%s'", input_filename);

  if (line != NULL)
    free (line);

  return status;
}

int
main (int argc, char **argv)
{
  int optc;
  const char *datestr = NULL;
  const char *set_datestr = NULL;
  struct timespec when;
  int set_date = 0;
  char *format;
  char *batch_file = NULL;
  char *reference = NULL;
  struct stat refstats;
  int n_args;
  int status;
  int option_specified_date;
  char const *short_options = (posix2_version () < 200112 ||
                               !getenv ("POSIXLY_CORRECT")
			       ? COMMON_SHORT_OPTIONS "I::"
			       : COMMON_SHORT_OPTIONS "I:");

  program_name = argv[0];
  setlocale (LC_ALL, "");
  bindtextdomain (PACKAGE, LOCALEDIR);
  textdomain (PACKAGE);

  close_stdout_set_status (2);
  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 'I':
	iso_8601_format = (optarg
			   ? XARGMATCH ("--iso-8601", optarg,
					time_spec_string, time_spec)
			   : TIME_SPEC_DATE);
	break;
      case 'r':
	reference = optarg;
	break;
      case 'R':
	setlocale(LC_ALL, "C");
	rfc_format = 1;
	break;
      case 's':
	set_datestr = optarg;
	set_date = 1;
	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;

  option_specified_date = ((datestr ? 1 : 0)
			   + (batch_file ? 1 : 0)
			   + (reference ? 1 : 0));

  if (option_specified_date > 1)
    {
      error (0, 0,
	_("the options to specify dates for printing are mutually exclusive"));
      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 (EXIT_FAILURE);
    }

  if (n_args > 1)
    {
      error (0, 0, _("too many non-option arguments: %s%s"),
	     argv[optind + 1], n_args == 2 ? "" : " ...");
      usage (EXIT_FAILURE);
    }

  if ((set_date || option_specified_date)
      && n_args == 1 && argv[optind][0] != '+')
    {
      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 (EXIT_FAILURE);
    }

  /* Simply ignore --rfc-822 if specified when setting the date.  */
  if (rfc_format && !set_date && n_args > 0)
    {
      error (0, 0,
	     _("a format string may not be specified when using\
 the --rfc-822 (-R) option"));
      usage (EXIT_FAILURE);
    }

  if (set_date)
    datestr = set_datestr;

  if (batch_file != NULL)
    {
      status = batch_convert (batch_file,
			      (n_args == 1 ? argv[optind] + 1 : NULL));
    }
  else
    {
      bool valid_date = true;
      status = 0;

      if (!option_specified_date && !set_date)
	{
	  if (n_args == 1 && argv[optind][0] != '+')
	    {
	      /* Prepare to set system clock to the specified date/time
		 given in the POSIX-format.  */
	      set_date = 1;
	      datestr = argv[optind];
	      valid_date = posixtime (&when.tv_sec,
				      datestr,
				      (PDS_TRAILING_YEAR
				       | PDS_CENTURY | PDS_SECONDS));
	      when.tv_nsec = 0; /* FIXME: posixtime should set this.  */
	      format = NULL;
	    }
	  else
	    {
	      /* Prepare to print the current date/time.  */
	      datestr = _("undefined");
	      if (gettime (&when) != 0)
		error (EXIT_FAILURE, errno, _("cannot get time of day"));
	      format = (n_args == 1 ? argv[optind] + 1 : NULL);
	    }
	}
      else
	{
	  /* (option_specified_date || set_date) */
	  if (reference != NULL)
	    {
	      if (stat (reference, &refstats))
		error (EXIT_FAILURE, errno, "%s", reference);
	      when.tv_sec = refstats.st_mtime;
	      when.tv_nsec = TIMESPEC_NS (refstats.st_mtim);
	    }
	  else
	    {
	      when.tv_sec = get_date (datestr, NULL);
	      when.tv_nsec = 0; /* FIXME: get_date should set this.  */
	      valid_date = (when.tv_sec != (time_t) -1);
	    }

	  format = (n_args == 1 ? argv[optind] + 1 : NULL);
	}

      if (! valid_date)
	error (EXIT_FAILURE, 0, _("invalid date `%s'"), 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 (settime (&when) != 0)
	    {
	      error (0, errno, _("cannot set date"));
	      status = 1;
	    }
	}

      show_date (format, when);
    }

  exit (status);
}

/* 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). */

static void
show_date (const char *format, struct timespec when)
{
  struct tm *tm;
  char *out = NULL;
  size_t out_length = 0;
  /* ISO 8601 formats.  See below regarding %z */
  static char const * const iso_format_string[] =
  {
    "%Y-%m-%d",
    "%Y-%m-%dT%H%z",
    "%Y-%m-%dT%H:%M%z",
    "%Y-%m-%dT%H:%M:%S%z"
  };

  tm = localtime (&when.tv_sec);

  if (format == NULL)
    {
      if (rfc_format)
	format = "%a, %d %b %Y %H:%M:%S %z";
      else if (iso_8601_format)
	format = iso_format_string[iso_8601_format - 1];
      else
	{
	  char *date_fmt = DATE_FMT_LANGINFO ();
	  format = *date_fmt ? date_fmt : dcgettext(NULL, N_("%a %b %e %H:%M:%S %Z %Y"), LC_TIME);
	}
    }
  else if (*format == '\0')
    {
      printf ("\n");
      return;
    }

  while (1)
    {
      int done;
      out_length += 200;
      out = (char *) xrealloc (out, out_length);

      /* Mark the first byte of the buffer so we can detect the case
	 of nstrftime 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';

      if (rfc_format)
	setlocale (LC_ALL, "C");

      done = (nstrftime (out, out_length, format, tm, 0, when.tv_nsec)
	      || out[0] == '\0');

      if (rfc_format)
	setlocale (LC_ALL, "");

      if (done)
	break;
    }

  printf ("%s\n", out);
  free (out);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -