date, one time format per page
Twenty-eight lessons on the date command, one time concept or one command per page: the two clocks inside a machine; the epoch as the honest zero and Unix time as one count; UTC and local paint; tzdata behind the zone names; daylight saving as the trap; ISO 8601, the ctime shape and RFC 5322 read like decoder cards; strftime one token at a time and strptime as the mirror; date -d parsing human strings; yesterday, tomorrow and the month-end edge; why NTP exists and clocks are never set by hand; the 2038 cliff; the second that reaches 60; cron's five fields; filenames that sort; log lines in UTC; and teaching a friend the epoch in one sitting.
One instant, one page, one real capture. That's the rhythm.
date, one time format per page
Twenty-eight lessons on the date command, one time concept or one command per page: the two clocks inside a machine; the epoch as the honest zero and Unix time as one count; UTC and local paint; tzdata behind the zone names; daylight saving as the trap; ISO 8601, the ctime shape and RFC 5322 read like decoder cards; strftime one token at a time and strptime as the mirror; date -d parsing human strings; yesterday, tomorrow and the month-end edge; why NTP exists and clocks are never set by hand; the 2038 cliff; the second that reaches 60; cron's five fields; filenames that sort; log lines in UTC; and teaching a friend the epoch in one sitting.
Set in Space Grotesk, Inter and JetBrains Mono (SIL Open Font License).
Every fact in this book is as the official source states it, fetched and read during this build: the local manual pages date(1) (GNU coreutils 9.4), strftime(3), strptime(3), ctime(3), crontab(5), tzselect(8) and tzfile(5) (the definition of truth for this book), and the Wikipedia articles Unix time, ISO 8601, Coordinated Universal Time, Time zone, Daylight saving time, System time, Network Time Protocol, Year 2038 problem, Leap year, Gregorian calendar, Time in China, List of tz database time zones and Leap second. No facts are sourced from Reddit, Stack Overflow, vendor blogs or commercial sites. Every command and output pair was run on this machine read-only, each capture recording its TZ environment so the pair is reproducible. SAFETY LAW: no clock was ever set and no file outside this book directory was written by any demonstration; the setting forms date -s and MMDDhhmm are documented but never run here, because keeping time is NTP's job. Honest notes: this host has no hwclock(8) manual page, so hardware-clock facts cite the System time article instead; one early capture attempt with a doubled percent in the format string failed honestly and is kept in the log. An independent guide, not affiliated with or endorsed by the Free Software Foundation, the IETF, IANA, or the Wikimedia Foundation.
Your purchase is for personal use only. You do not have redistribution rights: please do not share, resell, or republish this book or its pages.
© 2026 Steve Hodgkiss. All rights reserved. Personal use only; no redistribution rights.
Edition 1.0 · stevehodgkiss.net
Contents
Per the Wikipedia Unix time article, in Unix time every day contains exactly 86400 seconds, each leap second uses the timestamp of a second that immediately precedes or follows it, negative values on systems that support them indicate times before the Unix epoch, and Unix time is typically encoded as a signed integer. Per the date(1) manual page, %s is seconds since the Epoch (1970-01-01 00:00 UTC). This machine's captures: date +%s printed 1793891898 under TZ default, under TZ=Europe/London and under TZ=America/New_York.
Unix time, one count
Unix time is one number for the whole planet: seconds since the epoch, no zone, no name, no paint. Our capture: 1793891898 in CET, in London, in New York, the same digits every time.
Per the Wikipedia Unix time article, every day contains exactly 86400 seconds, so the count never stumbles at midnight. The honest wrinkle: a leap second reuses the timestamp of its neighbor rather than breaking the count.
Before 1970 the count goes negative, on systems that support it; that is a signed integer doing its job.
Convert your birthday: date -d '1990-06-15 12:00' +%s, then read the number back with date -d @N.
Per the Wikipedia Daylight saving time article, daylight saving time is the practice of advancing clocks to make better use of the longer daylight available during summer, and Germany and its allies led the way in introducing DST during World War I on 30 April 1916. Per the date(1) manual page, -d displays time described by STRING, not 'now'. This machine's captures: under TZ=America/New_York, date -d 2026-03-08 02:30 failed with date: invalid date '2026-03-08 02:30', and date -d 2026-11-01 01:30 printed Sun Nov 1 01:30:00 EDT 2026, an hour that occurs twice that night.
Daylight saving
Daylight saving is the practice of advancing clocks in summer, first rolled out nationally by Germany and its allies on 30 April 1916, per the Wikipedia article.
Spring forward makes a wall hour that never existed. Our capture, under TZ=America/New_York: date -d 2026-03-08 02:30 was refused outright, date: invalid date.
Fall back makes a wall hour that happens twice: date -d 2026-11-01 01:30 printed Sun Nov 1 01:30:00 EDT 2026, and the same wall digits recur an hour later. Wall time is a rumor; the count is the truth.
Try both edges yourself under TZ=America/New_York: the March hour refuses, the November one repeats.
Per the date(1) manual page, %Y is the year, %m the month (01..12), %d the day of month, %H the hour (00..23), %M the minute and %S the second. Per the strftime(3) manual page, %D is equivalent to %m/%d/%y and in international context this format is ambiguous and should not be used. This machine's captures: date +%Y%m%d-%H%M%S printed 20261105-161819 and date +%Y-%m-%d.%H:%M printed 2026-11-05.16:18. Per this book's plan, a stamp is honest when lexical order is chronological order.
Formats that sort
A filename stamped big-endian sorts by when: our captures printed 20261105-161819 and 2026-11-05.16:18, and both order themselves in time as ls orders them in bytes.
The honest opposite is %D, the month/day/year habit: strftime(3) says it is ambiguous in international context and should not be used.
Biggest first, fixed width, dashes as glue: that is the whole recipe. Page 25 hangs backups on it.
Stamp one file: touch notes-$(date +%Y%m%d-%H%M%S).txt, then ls it.
Per the strftime(3) manual page, %A is the full name of the day of the week, %B the full name of the month, %j the day of the year in range 001 to 366, %V the ISO 8601 week number in range 01 to 53 where week 1 is the first week that has at least 4 days in the new year, and %G the ISO week-based year. This machine's captures: date +%A %B %j %V printed Thursday November 309 45 and date +%V printed 45.
Names and numbers
Names for humans, numbers for sorting: our capture date +%A %B %j %V printed Thursday November 309 45 in one breath.
%j counts the year's days, 001 to 366: this build day is day 309 of 2026. %V counts ISO weeks, 01 to 53, where week 1 owns at least four days of the new year, per strftime(3).
Near a year's edge %V and %Y disagree: January 1 can belong to the old year's week 53. That is why %G exists; ask for %G-%V-%u together or not at all.
Run date +%A %B %j %V, then say which three tokens are names, counts and walls.
Per the ctime(3) manual page, mktime converts a broken-down time structure to calendar time, and if structure members are outside their valid interval, they will be normalized, so that for example 40 October is changed into 9 November. Per the date(1) manual page, -d displays time described by STRING, which may contain relative items. This machine's capture: date -d 2026-01-31 +1 month printed Tue Mar 3 00:00:00 CET 2026. Per this book's plan, this is labelled the honest arithmetic surprise, not a bug.
The month-end trap
Add one month to January 31 and arithmetic must lie somewhere: February has no 31st. Our capture: date -d 2026-01-31 +1 month printed Tue Mar 3 00:00:00 CET 2026.
What happened is normalization, documented in ctime(3) for mktime: members outside their interval are adjusted, 40 October becomes 9 November. Jan 31 plus a month lands on Feb 31, which normalizes into March 3.
This book's plan calls it the honest surprise, not a bug: the machine obeyed a rule. If you need month ends, ask for them explicitly, then verify with one more date -d.
Try the other edge: date -d 2026-03-31 -1 month, and reason the landing before you press.
Per the Wikipedia Year 2038 problem article, the problem leaves some computer systems unable to represent times after 03:14:07 UTC on 19 January 2038, because Unix time is stored in a signed 32-bit integer which overflows when its maximum value is exceeded. Per the date(1) manual page, --date='@2147483647' converts seconds since the Epoch to a date. This machine's captures: under TZ=UTC, date -u -d @2147483647 printed Tue Jan 19 03:14:07 UTC 2038 and date -u -d @2147483648 printed Tue Jan 19 03:14:08 UTC 2038, one second past the cliff, because this host's time_t is wider than 32 bits.
The 2038 cliff
A signed 32-bit integer stops at 2147483647; after it, overflow, says the Wikipedia Year 2038 problem article. The wall lands at 03:14:07 UTC on 19 January 2038.
Our captures, under TZ=UTC: date -u -d @2147483647 printed Tue Jan 19 03:14:07 UTC 2038; one second more printed 03:14:08, because this host's time_t is 64 bits wide and steps over the cliff.
The manual itself keeps the address: date(1)'s own example is --date='@2147483647'. Smaller systems, older ones, must be audited; that is the 2038 industry's job, not date's.
Stand on the edge read-only: date -u -d @2147483647, then step past with @2147483648.
Per this book's plan, the closing lesson teaches one friend the epoch in one sitting: run date, run date -u, run date +%s, read the count back with date -d @0, and end with one stamped filename. Per the Wikipedia Unix time article, the Unix epoch is 00:00:00 UTC on 1 January 1970 and Unix time 0 is exactly midnight UTC on that day. This machine's captures, re-read from this book: date printing Thu Nov 5 16:18:18 CET 2026, date -u printing 15:18:18 UTC, date +%s printing 1793891898, and date -d @0 printing Thu Jan 1 01:00:00 CET 1970.
Teaching the epoch
The whole book in one sitting with a friend: date, date -u, date +%s, date -d @0, one stamped filename. Five steps, one story: the count is the truth, the paint is a choice.
Teach the readings as much as the typing: which line is the instant, which is the wall, and why 1793891898 is the same in every zone.
The lines they will meet are this book's own captures: Thu Nov 5 16:18:18 CET 2026, 15:18:18 UTC, 1793891898, Thu Jan 1 01:00:00 CET 1970. Let them type every one.
Sit with one friend and teach the epoch in one sitting; they type, you read the instants aloud.