Decoded: date (coreutils)

[Back to Project Main Page]

Note: This page explores the design of command-line utilities. It is not a user guide.
[GNU Manual] [POSIX requirement] [Linux man] [FreeBSD man]

Logical flow of date command (coreutils)

Summary

date - print or set system date and time

[Source] [Code Walkthrough]

Lines of code: 604
Principal syscall: stime() (or some variant such as clock_settime() in POSIX or settimeofday() in BSD), clock_gettime()
Support syscalls: stat(), getenv()
Options: 22 (7 short, 15 long, does not include perm digits)

Earliest (?) date/time concept from CTSS (1966): GETIME, GETTM, GTDYTM
     - Predates UNIX-time; V1 UNIX (1971) date is a better ancestor
Added to Shellutils in November 1992 [First version]
Number of revisions: 229

The date utility requires a surprising amount of heavy lifting, even though the most challenge aspects are pushed off to gnulib (which uses a separate yacc parser). For this utility, our primary concerns are the datetime source and the timezone.

Helpers:
  • batch_convert() - Parses datetime for each line of a file
  • show_date() - Displays the current time in the desired format
External non-standard helpers:
  • die() - Exit with mandatory non-zero error and message to stderr
  • error() - Outputs error message to standard error with possible process termination
  • localtime_rz() - Stores current time with timezone in a provided buffer
  • setlocale() - Sets the systems location

Setup

date manages execution by declaring a long list of local variables in main():

  • *batch_file - The input file of datetimes (-f)
  • *datestr - The user-provided datetime source string
  • *format - The post-parsing chosen format
  • ok - The final return status.
  • optc - The character for the next option to process
  • option_specified_date - Counts the number of date sources used
  • *reference - The name of a reference file used for a date source
  • refstats - The stat() of the reference file
  • set_date - Flag to set the system date
  • *set_datestr - The user-provided date string for setting the system
  • when - Buffer to hold the system time

Parsing

Parsing answers the following questions to define the execution parameters

  • What is the date source? Current time, User provided, A reference file, A list of datetimes in a file?
  • What format should we use for output? (Several RFC/ISO options)
  • What timezone should we use?

Parsing failures

These failure cases are explicitly checked:

  • User chooses multiple conflicting sources of datetimes
  • User specifies multiple output targets or formats
  • Requesting to get and set the datetime in a single operation
  • Too many operands
  • Invalid format provided
  • Unknown option used

User specified parsing failures result in a short error message followed by the usage instructions. Access related parsing errors die with an error message.


Execution

The execution path is largely based on if we're only displaying a time, or if we're setting a new time.

Beforehand, there are two preliminary steps. If no format was provided y the user, we initialize a default. Second, we need to retrieve the local timezone setting.

Subsequent execute depends on the overall task:

Setting a new time

  • Retrieve the desired time from either:
    • A reference file using stat() followed by get_stat_mtime() from the returned stat structure
    • Directly from user input by parsing with gnulib (parse_datetime2()
  • Call settime() on the properly parsed datetime

Displaying a new time

  • Retrieve the times to display from:
    • A provided batch file of times. Multiple lines are retrieved and printed until EOF.
    • Take from the system time with the gnulib function gettime()

Failure cases:

  • No valid date is parsed or provided
  • Unable to set the date
  • Unable to read input from the source
  • Unable to stat() the reference file
  • Unable to open or close the target batch file

All failures at this stage output an error message to STDERR and return without displaying usage help


[Back to Project Main Page]