[GNU Manual] [POSIX requirement] [Linux man] [FreeBSD man]

Summary
date - print or set system date and time
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 fileshow_date()- Displays the current time in the desired format
die()- Exit with mandatory non-zero error and message to stderrerror()- Outputs error message to standard error with possible process terminationlocaltime_rz()- Stores current time with timezone in a provided buffersetlocale()- 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 formatok- The final return status.optc- The character for the next option to processoption_specified_date- Counts the number of date sources used*reference- The name of a reference file used for a date sourcerefstats- Thestat()of the reference fileset_date- Flag to set the system date*set_datestr- The user-provided date string for setting the systemwhen- 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 byget_stat_mtime()from the returned stat structure - Directly from user input by parsing with gnulib (parse_datetime2()
- A reference file using
- 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