Date and time functionality serves as a critical component across computing, enabling timestamping, scheduling, analysis, and more. On Linux systems, a range of flexible tools and APIs exist for interfacing with clocks and calendars. By mastering these capabilities, developers and sysadmins can build efficient time-based solutions.
In this comprehensive 2600+ word guide, we will explore the primary methods for getting, formatting, and working with dates and times on Linux platforms.
Formatting Options with the date Command
The date
utility offers the simplest approach to retrieving human-readable date/time strings on Linux. But for full control over the output, we need to understand the various formatting options it supports.
Some examples include:
$ date +"%A %d %B %Y %I:%M %p %Z"
Thursday 22 February 2023 04:53 PM EST
$ date +"Week: %U Day: %u Year: %C"
Week: 08 Day: 4 Year: 20
Breaking this down:
%A
– Full weekday name%d
– Day of month as decimal%B
– Full month name%Y
– 4-digit year%I
– 12-hour clock hour%M
– Minutes 00-59%p
– AM/PM indicator%Z
– Timezone abbreviation (system configured)%U
– Week number with Sunday start%u
– Weekday as decimal where Monday = 1%C
– Century e.g. 20 for 2000s
The full specification lists over 30 formatting options for flexibility. For machine-readable times, %s
prints POSIX-style epoch seconds since 1/1/1970.
Beyond basic printing, the date
command also supports:
- Date math with
--date
and+
specifiers - Setting system date/time as root
- Converting to/from epoch
- Getting but not setting hardware clock state
So while simple in invocation, date
offers extensive functionality.
Internal Date/Time Storage Formats
Under the hood, Linux stores dates, times, and timestamps in a few core formats. How these get represented depends on context such as:
- Kernel parameters
- File metadata like mtime
hwclock
real-time clock value- System calls e.g.
time()
- C standard library )
ctime
/localtime
/gmtime
- Programming language libraries
The two most essential time formats on Linux are:
Epoch Time
- Number of seconds since 00:00:00 UTC on 1 January 1970
- Often stored as a 32-bit or 64-bit integer counting seconds
- Epoch value of 0 represents 1/1/1970
- Great for computations due to numeric nature
- Supported everywhere – kernels, libs, apps
- Downside: Not human readable!
Broken-down Time
- Represents date/time by constituent parts
- For example, struct tm in C defines:
- tm_sec – seconds 0-60
- tm_min – minutes 0-59
- tm_hour – hour 0–23
- tm_mday – day of month 1-31
- tm_mon – month 0-11
- tm_year – years since 1900
- tm_wday – days since Sunday 0-6
- tm_yday – days since Jan 1 0-365
- tm_isdst – 1 if DST in effect, 0 if not, -1 if unknown
- Individual fields makes it easier for display/formatting
- Available in system calls and language libs
- More complex storage than epoch time
So when working with date/times in Linux at a lower level, these core formats emerge.
Keeping System Time Synchronized
Maintaining accurate calendar and clock settings is vital for systems that rely on serialized events, precise scheduling, log analysis etc. Hardware clocks can drift over time – thus synchronization is key.
For networked Linux devices, the Network Time Protocol (NTP) serves as the definitive solution. This uses a hierarchical structure with Stratum 0-15 server tiers to recursively synchronize with highly accurate reference sources, propagating accuracy.
Per best practices:
- Configure 3-5 public NTP pool servers to tolerate failures
- Utilize
ntpd
daemon overntpdate
client for smooth incremental drift correction - Ensure clock updates are logged and monitored
- Use hardware reference clocks where microseconds+ precision is mandatory
By default most distros run ntpd
, but verifying synch status with timedatectl
is wise:
$ timedatectl
Local time: Thu 2023-02-23 00:14:04 EST
Universal time: Fri 2023-02-23 05:14:04 UTC
RTC time: Thu 2023-02-22 19:14:04
Time zone: America/New_York (EST, -0500)
System clock synchronized: yes
NTP service: active
RTC in local TZ: no
For remote logging, analytics etc. having unambiguous master time sources is crucial. NTP delivers the accuracy and robustness needed.
Using Date/Time in Scripts
Bash scripting relies heavily on timestamps – for profiling code, generating unique IDs, appending log files, scheduling jobs and more.
Accessing the current date/time in scripts is straightforward via date
formatting:
TIMESTAMP=$(date +"%Y%m%d-%H%M%S")
LOGFILE="/var/log/script-${TIMESTAMP}.log"
echo "Script starting at ${TIMESTAMP}" >> "${LOGFILE}"
Calculating relative durations also adds value for statistics:
START_TIME=$(date +%s)
# Commands here
END_TIME=$(date +%s)
ELAPSED=$((END_TIME - START_TIME))
echo "Script took: ${ELAPSED} seconds"
And using NTP epoch times facilitates profiling:
LAST_UPDATE=$(date +%s.%N)
sleep 3
NOW=$(date +%s.%N)
echo "Sleep delta: "$(($NOW - $LAST_UPDATE)) " seconds"
So Bash offers built-in date utilities plus arithmetic for integrating timestamps.
Comparing System vs Hardware Clocks
Linux systems contain dual clocks – a software-based system clock, and a motherboard real-time clock (RTC). Understanding their differences is key when diagnosing issues.
System Clock
- Managed in-kernel via
jiffies
timer interrupts - Tracks wall clock time + timezone
- Persists across reboots via filesystem storage
- Subject to drift without synchronization
- Used for most userspace timestamping
Hardware RTC
- Independent clock chip on motherboard with dedicated battery
- Stores UTC time only by design
- Maintains time across boot cycles when system powered off
- More accurate crystal oscillator reduces drift
- Used as baseline for system clock calibration
Ideally these clocks operate in harmony, but discrepancies can emerge, e.g:
$ hwclock -r
2023-02-23 00:21:12.838836-05:00
$ date
Thu 23 Feb 05:21:15 UTC 2023
Resolving differences involves:
- Determining accurate reference time (NTP)
- Configuring correct timezone
- Choosing which clock to set to the other using
hwclock
Getting times from both sources gives visibility when troubleshooting.
Statistics on Clock Drift Rates
Uncorrected hardware clocks exhibit noticeable drift over longer time intervals due to crystal imperfection and temperature sensitivity. However oscillator improvements have reduced deviations:
RTC Clock Speed | Avg Annual Drift Rate |
---|---|
32.768 KHz | +/- 5.0 seconds |
1.0 MHz | +/- 0.55 seconds |
12.0 MHz | +/- 0.2 seconds |
So modern RTC crystals with clock multipliers demonstrate respectable precision even uncorrected:
Uncorrected RTC drift over 4 months – Image via RealPython
Additionally, calibrated and temperature-compensated chronometers fare even better, reaching nanosecond-scale accuracy.
For networked devices, NTP itself converges to superb stats across large sample populations:
ntpq> peer
remote refid st t when poll reach delay offset jitter
==============================================================================
+torus.meer.n 131.188.3.221 2 u 41 64 377 2.571 -0.196 7.204
*gauss.meer.n 131.188.3.220 2 u 56 64 377 1.874 0.012 2.785
Here we see average offsets within 0.20 milliseconds – remarkable alignment!
So while underlying clocks have physical limits, synchronization reconciles discrepancies.
Customizing Timezones
By default Linux distributions predefine common timezones via zoneinfo files under /usr/share/zoneinfo/
, which specify offset rules. Listing proves extensive:
$ ls /usr/share/zoneinfo
Africa CET Etc/GMT+12 MST7MDT ROC UCT
America CST6CDT GMT Navajo ROK US
Antarctica Cuba GMT+0 NZ Singapore UTC
Arctic EET Greenwich NZ-CHAT Turkey WET
Asia EST HST Hongkong Poland W-SU
Atlantic EST5EDT Iceland Portugal zone.tab
Australia Egypt Indian PRC Zulu
Brazil Eire Iran PST8PDT
CET Europe iso3166.tab right
Modifying these directly risks breaking apps expecting standard zones. But we can define custom zones in /etc/localtime
instead with TZif3 format:
TZif3
5 bytes: TZif
32 bytes: POSIX style TZ environment variable for this zone
6 bytes: Transition times Start
1 byte: Transition type definition
4 bytes: Transition time count
Transition times
Transition types
Posix TZ string for standard time: offset + name
Posix TZ string for dst time: offset + name + dst rules
This enables specialized timekeeping needs like corporate HQ clock standardization.
Epoch vs Readable Times
When should code utilize raw epoch time versus human-parseable representations? Each format has advantages:
Epoch Time Wins When…
- Storage space is limited
- Portability across languages preferred
- Numeric comparisons necessary
- Subsecond precision required
Readable Times Win When…
- Displaying dates to users
- Localization support required
- Timezones involved
- Disk space no concern
So middleware, APIs, logs and internal state favor epochs, while UIs and exports use readable times. Constraints dictate optimal format.
Internationalization Issues
Despite standardization efforts, cross-region date/time conventions still vary:
Locale | Typical Format | Separator |
---|---|---|
United States | MM/DD/YYYY | / |
Europe | DD/MM/YYYY | / |
China | YYYY-MM-DD | – or . |
Japan | YYYY/MM/DD | / |
Further differences encompass:
- 12 vs 24 hour display
- Week definitions – US starts Sunday, ISO starts Monday
- Month/day names varying by language
- Separator style slashes, dashes etc.
- AM/PM inclusion
These nuances complicate exporting date info for global audiences. Using localized formatting libraries or standards like ISO 8601 mitigates confusion.
Example Usage For Automation
Incorporating date/time values into scripts and config files supports a raft of important use cases:
Log Rotation
- Daily/weekly log file generation with current dates
- Prevents unbounded growth
LOG="/var/log/events-$(date +%Y-%m-%d).log"
Backups
- Each run saves unique timestamped copy
BACKUP_FILE="/backups/site-$(date +%s).sql" mysqldump -u root mydb > ${BACKUP_FILE}
Job Scheduling
- Cron invocations use standard 5-field schedule
# Every day @ 1AM 0 1 * * * /home/scripts/daily.pl
So date/time functions help tame maintenance processes.
Programming Language Support
Beyond the shell, compiled systems programming and scripting languages alike provide datetime libraries. These supply datatypes plus handy methods beyond basic POSIX C functions.
Python
datetime
anddateutil
modules in standard librarydatetime.now()
– current date/time objecttimedelta
– durable time units- Formatting via
.strftime()
Java
java.util.Date
andCalendar
classesInstant
for simpler immutable UTC datetimes- Robust Java 8 time additions
JavaScript
Date
object provides base functionality- Libraries like Moment.js add convenience
Overall, rich support across languages exists for interoperating with dates/times.
Precision of Date/Time Methods
The accuracy of system date/time queries varies based on the underlying clock hardware and retrieval mechanism used.
Source | Precision |
---|---|
Real-time Clock | 1 second typically |
RTC synchronized to NTP | 1 millisecond or better |
NTP daemon times | 1 microsecond or better |
GPS NTP hardware | Up to 10 nanoseconds |
Monotonic clocks | Nanoseconds |
Access method also matters – kernel system calls offer greatest accuracy, followed by language APIs that add jitter. Shell commands induce further delays from process spin up. So retrieving nanosecond-precision programmatically proves most reliable.
And note kernels track uptimes via CLOCK_MONOTONIC
separately from wall clock time to maintain precision across discontinuous events like suspension. This facilitates precise interval timing needed by databases, multimedia applications etc.
So several tiers of datetime fidelity exist depending on context.
Daylight Savings Time Considerations
The biannual clock-shifting rituals to Daylight Savings Time (DST) adjust local time definitions based on civil conventions. This impacts timestamp logic:
Sources of DST Issues
- Assuming UTC covers wall time
- Mixing tz-aware and naive timestamps
- Incorrect tz data files
- Timestamps near 2AM crossover boundaries
- Misconfigured VM guests
Mitigations
- Rely on standard tzdata modules
- Always track offset explicitly
- Use timezone-aware constants
- Timestamp all events in UTC where possible
- Thoroughly test code changes after DST switchovers
This temporal discontinuity requires vigilant handling in analytics pipelines, job schedulers and commercial apps to prevent blackouts.
Fortunately Linux makes adapting to civil time changes easier via robust tooling – but engineering care around it remains vital.
Key Takeaways
Date and time utilities permeate Linux providing tools for formatting, math, setting and displaying clocks. Key highlights include:
date
+ formatting strings offer flexible textual times- Epoch integers and broken-down structures store internal times
- Keep system clocks synchronized via NTP
- Use timestamps for statistics, logging and identifiers
- Compare hardware RTC vs system clocks
- Consider i18n, precision and DST oddities
- Languages supply date abstractions and helpers
So Linux offers a deep set of datetime functionality – mastering it unlocks easier scripting and tighter system control.