About Sophie

Cybersecurity, assurance, technology, identity, and life.

“I dare do all that may become a woman. Who dares do more is none.”

New Series: Sophie Baskerville’s History of Cybersecurity

sophie @ baskerville.net ©️1977-2026 Sophie Baskerville

Why we should INSIST that years are written in full


Two missing digits can change the century and corrupt the record

A brass wheel with six broad cog teeth, each displaying a man and woman in clothing representing a different century. Clockwise from the top, the pairs are labelled 1526, 1626, 1726, 1826, 1926, and 2026, progressing from Tudor dress to contemporary clothing. A large “26?” fills the central hub: all six years become indistinguishable when their first two digits are removed. Purple fabric, old books, maps, a globe, and an hourglass surround the wheel, with a historic city skyline beyond.

A document I received during the evening of 9 September 2026 has a section headed “History”. Its version table dates version 1.0 as 20.08.26. I presume that means 20 August 2026. The date itself does not establish that. Under a year–month–day convention, the same numerals could instead mean 26 August 2020. Even before choosing a century, we need to know the field order. A record intended to document history has started by requiring its reader to supply some.

I have rather a long history of thinking that years should be specified in full. I can actually evidence several decades of it.

I was already asking people to abandon two-digit years in an article published on 2 January 2020. [1] Six years later, I am still receiving documents with the same avoidable defect.

After Y2K, having to explain this again is, let us not beat around the bush, bloody infuriating. “Lessons Learned” actually requires the lessons to be drawn AND for them to be implemented. Writing a year with two digits removes information that another person or system must reconstruct. The practical consequences include incorrect ages, misplaced records, unreliable chronology, and dates that change meaning when software changes. Saving two characters is an absurdly poor bargain.

The remedy for ordinary contemporary records is straightforward: write 20 August 2026 for people, or use 2026-08-20 in an explicitly defined year–month–day data format (which, combined with consistent field widths and formatting, actually sorts properly since it is most-to-least-significant element order). Preserve that full year through storage, display, export, and reuse. A complete internal value is little comfort to someone whose only copy is a screenshot.

The information that has disappeared

In ordinary decimal year numbering, retaining only the final two digits performs this operation:

short_year = full_year mod 100

“Modulo 100” means taking the remainder after division by 100. So 1726, 1826, 1926, and 2026 all become 26. The transformation is many-to-one: several different original values produce exactly the same result. There is no unique inverse.

A reader may infer the intended century from the surrounding text, the sender, or the document’s appearance. Those are additional inputs. They can make an inference compelling without putting the missing information back into the date. A later extract, printout, or migrated record, however, may retain the date and lose every clue used to interpret it.

The loss exists from the moment the abbreviated value is written. We do not have to wait until 2100 for it to become a defect.

What actually went wrong at Y2K

If you were born around or after 2000, the millennium bug may be something you know through old headlines. Its central mechanism is still relevant whenever software guesses what an incomplete date means. You do not need to have lived through Y2K to inherit its bugs.

Many systems represented years using two digits and treated them as belonging to the 1900s. At the transition from 1999 to 2000, 99 became 00. Comparisons could place the new date before the old one. Arithmetic on those shortened values could produce nonsense. A simplified calculation of elapsed years, 00 − 99, gives −99; the corresponding full-year calculation, 2000 − 1999, gives 1. Neither calculation alone is a complete date-duration algorithm, but the century error is obvious.

The problem also arises before a clock reaches the boundary. A system processing a future expiry date, loan repayment, or appointment can encounter a new century years in advance. Retrospective records present the same difficulty in the other direction. Software has to handle the dates in its data, not merely the year on the office calendar.

In older systems, shorter fields could save valuable storage and reduce changes to established record layouts. With a one-byte character encoding, two decimal characters use two bytes and four use four: a saving of two bytes per year field. That does not mean a 50% saving in the entire record, and it says nothing about how a modern database stores its native date type. The arithmetic was legitimate; an unrecorded assumption that the data would never outlive its century was the liability.

Nor was “nothing happened” an adequate assessment of the outcome. In January 2000, the US General Accounting Office reported that most observed failures had been mitigated through corrections or contingency measures, and credited leadership and organisational cooperation. It also recorded real errors: one Medicare contractor received about 11,000 claims with erroneous dates of 1900 or 2099 in the first two weeks of January. Many were traced to providers that had not upgraded their systems. [2]

The relative calm at rollover followed substantial remediation and preparation. It cannot establish that the defects were imaginary. Equally, the existence of genuine defects does not validate every alarming prediction made beforehand.

The engineering lesson was to define the range and meaning of date values, preserve them across interfaces, and test the boundaries. It was never sensible to treat 1 January 2000 as the expiry date of that lesson.

Software is still supplying the missing century

A common compatibility technique is windowing: assign the 100 possible two-digit values to a chosen run of 100 full years. A window ending in 2029 covers 1930–2029. A window ending in 2049 covers 1950–2049. Both produce a full year for every input, but they disagree about some of those years.

Input yearWindow 1930–2029
.NET 6 & 7
Window 1950–2049
.NET 8
2620262026
2920292029
3019302030
3519352035
4919492049
5019501950

The disagreement is a documented modern behaviour. Microsoft’s .NET 8 compatibility note records a change in the default Gregorian-style calendar cutoff from 2029 to 2049. Its example parses the same date string into 1935 under .NET 6 or .NET 7, and into 2035 under the new behaviour. Explicit settings, culture, and the relevant Windows configuration matter; this is not a claim that every application behaves identically. [3]

The bytes in the input can stay unchanged while their interpreted century moves by 100 years. That is a serious property for an archive, a data migration, or a repeatable calculation. A successful parse proves that the parser found a value permitted by its rules. It does not prove that the value is the one the writer intended.

Microsoft also documents Excel’s 2029 rule, under which 00–29 become 2000–2029 and 30–99 become 1930–1999. Typed input can be affected by regional settings, and behaviour differs by entry route. Check the actual application and import path. “The computer will work it out” is an invitation to discover which convention it happened to use. [4]

A fixed window merely establishes a bounded interpretation. A moving window can make the interpretation depend on when processing takes place. Changing either one can reinterpret previously accepted data. Windowing is defensible in a controlled legacy interface only when its range is appropriate, its rules accompany the data, and its limitations are actively managed.

It is particularly unsuitable as a universal assumption for dates of birth. Records of people born more than a century apart can legitimately coexist. One 100-year window cannot represent them all uniquely.

Displaying four digits after guessing the century does not repair this. It can make the unsupported guess look authoritative.

A gravestone is a long-term storage medium

Another example comes from my photograph of memorial inscriptions in a cemetery with gravestones ranging from recent examples to others dating back about 400 years. Two of the date ranges read 23.8.50 ~ 16.10.99 and 26/3/79 To 24/8/00. The personal names have no bearing on the technical point, so I have not included the actual photograph in question.

Take the second range. Assuming day/month/year ordering, all these pairs are compatible with its abbreviated years:

Birth dateDeath dateCompleted
years of age
26 March 167924 August 170021
26 March 177924 August 180021
26 March 187924 August 190021
26 March 197924 August 200021

These alternative interpretations all give the same completed age. Even an additional inscription saying “aged 21” would fail to identify the century. The other memorial similarly admits 1650-1699 or 1750-1799 or 1850–1899 or 1950–1999, all with an age of 49.

Materials, lettering, and cemetery records may make the intended dates recoverable. They remain evidence external to the date. Weathering is not a calibrated clock, and a replacement inscription can be much younger than the death it records. Appearance is a clue, not a century field.

An expert may resolve the dates by consulting other evidence. They have nevertheless been given a research task where two more digits could have supplied the answer directly.

This is the same information problem as the document’s “History”, but expressed in stone. The medium can survive while the context required to interpret it disappears. Designing for long-term preservation requires attention to both physical survival and retained meaning.

Calendar systems, eras, and local conventions can also need explanation. Those are reasons to preserve additional information, rather than discard a century we already know.

Abbreviated years also invite alteration

My 2020 article identified a second defect: a written date ending “31 December 20” could be extended to “31 December 2000” or “31 December 2099” (or any year between the two) by appending digits. [1] The result looks more complete, but its apparent year has changed. This is a question of document integrity as well as interpretation.

Writing all four digits removes that particular opportunity within a four-digit year format. It does not make a document tamper-proof. Protecting the original and verifying integrity, for example through an appropriately validated digital signature covering the complete content, remain separate requirements. A scanned handwritten signature alone does not provide that cryptographic check.

My older article mischievously proposed Roman numerals. Its accompanying table explored append-only changes under conventional subtractive notation: XX can become XXI, XXIX, or XXX, among others. [1] The permissible changes depend on the encoding rules. But XX still leaves the century unstated; MMXX expresses 2020. Changing the alphabet cannot supply information you have chosen not to record.

Preserve the year through every representation

There are three separate things to check: what a system stores, what it displays, and what it exports. They may not be identical. A spreadsheet can hold a complete date while a cell format shows only two year digits; Microsoft explicitly distinguishes stored date interpretation from display format. [4]

Such a display has not necessarily damaged the underlying workbook. It has, however, produced an incomplete representation. A screenshot or paper copy cannot reveal the hidden value. An export or copy operation may carry either the complete value or a formatted string, depending on the software and route. Inspect the actual output rather than assuming that the original data model travelled with it.

The same applies to database reports, application screens, generated letters, and filenames. A well-designed database does not absolve a report template that discards the century. Quality assurance must follow the date to the place where somebody will actually read or reuse it.

UseA suitable representationWhat it establishes
Human-readable date20 August 2026Day and named month, with the full year.
Structured calendar date2026-08-20Year–month–day in an explicitly defined format.
Recorded instant in UTC2026-08-20T14:30:00ZDate & time in UTC, in RFC 3339 format.
Year genuinely unknownPreserve “26” with an uncertainty noteWhat the source actually says, without inventing a century.

RFC 3339, the Internet timestamp specification published in July 2002, is admirably direct: “Internet Protocols MUST generate four digit years in dates.” It defines a four-digit year and a year–month–day date component. The uppercase MUST has a standards meaning within that specification; it is not a claim that every document template is legally governed by an RFC. [5]

For people, a named month also avoids the separate day/month ordering ambiguity. Writing 04/05/2026 retains the century but still leaves readers in different locales wondering whether it means 4 May or 5 April. Writing 4 May 2026 settles both questions in ordinary English use. Although it introduces language dependencies or biases.

For software, define the accepted syntax, calendar, and range; validate the date itself. A string with four year digits can still contain an impossible day. Use maintained date types and libraries for calculation, and an agreed interchange representation at boundaries.

Make complete years the default

The practical change should be visible in the tools people use. A policy asking for complete years will achieve little if every form offers a box labelled “YY” and every report template shortens the value again. Make the correct representation the default, then check the outputs.

For new records, require the full year at entry and keep it visible in documents, labels, and exports. A form should explain the required format and reject an incomplete year, rather than silently assigning a century. A responsive screen can put a date on another line. Its layout problem is not a reason to create a data problem.

For existing records, preserve the original value. Recover the century from authoritative evidence where possible, and record the evidence or conversion rule. If it remains uncertain, represent that uncertainty explicitly. Prepending “20” to every two-digit year will manufacture confident errors, particularly in historical and birth records.

Where an old interface cannot yet change, specify its interpretation window, validate that the data fits, and arrange a dated migration. Test the years immediately on either side of its cutoff, the century boundary, and records more than 100 years apart. Verify that a round trip through export and re-import preserves the full date. Repeat those checks when parsers, settings, or runtime versions change.

There are legitimate compact representations. A database may encode dates as a count from a defined origin, and a document headed “2026” may use shorter entries within that explicit scope. In each case, the omitted information must remain available under a dependable contract. Extracting or exporting those entries requires carrying their context with them. A free-standing “26” has no such protection.

The calendar does not specify your file format

The illustration on my 2020 article blamed Pope Gregory XIII for failing to specify that years must be written in full. [1][6] I remember the joke from the mini-Annals of Improbable Research (the issuers of the Ig Nobel awards), issue 1999-01, January 1999. Its “Y2K Scapegoat” feature reports the results of a humorous vote. The Pope was Gregory XIII; the comment about requiring full years was attributed to voter Joel Brown. [7] The surviving source resolves three details of the recollection: it was published before the rollover, in January 1999; Gregory XIII was one of the candidates; and Bill Gates won, with Jesus the other leading candidate. Gregory appeared in a lower tier. Full details in the reference. [7]

The joke identifies a real distinction. Calendar rules define the organisation of dates; a representation specifies how those dates are recorded. A reform of leap-year rules does not relieve a software designer or document author of responsibility for preserving the year. Papal approval is unnecessary for adding the missing digits.

So I was talking about this in 2020. Was I talking about it earlier? Are bears Catholic? But was I REALLY talking about it? Oh yes…. 11 January 1999. CNK, if not obvious, is short for C|N>K which stands broadly for “coke (or coffee) piped through nose onto keyboard” which is what happens when you read something unexpectedly funny.


Source: oldmail.tgz, folder “cnk” • message 260

Subject: Y2K Scapegoat 
To: cnk@mcc.ac.uk
Date: Mon, 11 Jan 1999 20:40:30 +0000 (GMT)
From: Robert Baskerville <Robert@Baskerville.Net>
Return-Path: <Robert@Baskerville.Net>
Reply-To: Robert@Baskerville.Net
X-Mailer: ELM [version 2.4 PL24alpha3]
MIME-Version: 1.0
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: 7bit
Content-Length: 529       

Excerpted from the Annals of Improbable Research

> Voter Joel Brown commented of POPE GREGORY: "He could easily have
> decreed that we all use a four digit year when referring to his
> calendar. The problem would have been fixed in 1582."

...yeah, but look what we would have been storing up for Y10K..

Still, gives me to chance to gratuitously include some output from
the cal ("cal 9 1752") command in my sig :-)

Robert

   September 1752
 S  M Tu  W Th  F  S
       1  2 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30


On 12 November 1998, I wrote about Four digit years and Y10K. Text of email in the references since it is long. [8]

So 1998 then? We can find older than that.

14 December 1997: A reported failure before the rollover

“Re: premature Y2K problem”. A correspondent reports that a VM/CMS backup package assigns special meanings to years 98 and 99 and will not run from 1 January 1998. My reply:

“Hmmm. So that’s about 7 working days to sort it out. Who knows any CMS?!”

This documents my response to a reported date-related operational risk before 2000. The archive does not independently establish the package behaviour or its eventual remediation. [9]

December 1997. That’s as far back as I can find Y2K references in my personal mail archive. But that is not the start of my concerns. Excuse my lack of documentation; somewhere may exist some ancient fan-fold printouts, but I have not yet located any:

Four digits are sufficient for ordinary present-day civil years. Applications spanning other eras or years beyond 9999 need an appropriate representation and explicit conventions. Nor does a full year replace the timezone or offset needed to identify an instant. These are distinct requirements, each to be specified rather than guessed. [5]

We know the failure mechanism. We have working representations. We have spent decades dealing with the consequences of getting it wrong. Continuing to remove the century from a record that must stand on its own is an avoidable defect, and I have very little patience left for it.

References and source notes

Sources checked on 9 September 2026. The mathematical examples and recommendations are the author’s analysis; numbered references support the historical and implementation claims.

[1] Sophie Baskerville  Time to wave 2-Digit Years goodbye for good

My article, published on 2 January 2020 under the name Rob Baskerville. Supplies the earlier campaign, the example of appending digits to an abbreviated written year, and the Gregory XIII illustration.

[2] US General Accounting Office  Year 2000 Computing Challenge Leadership and Partnerships Result in Limited Rollover Disruptions

Testimony GAO/T-AIMD-00-70, 27 January 2000. Printed pages 1–2 discuss the rollover outcome and response; printed page 12 records Medicare claims carrying erroneous years. Contemporary evidence of real failures and mitigation, without relying on retrospective disaster folklore.

[3] Microsoft Learn  Breaking change TwoDigitYearMax default is 2049

Documents the .NET 8 change, the prior .NET 6 and .NET 7 behaviour, the 1935/2035 example, and configuration considerations. The article’s comparison table illustrates the two explicitly stated windows; it is not a universal claim about all installed software.

[4] Microsoft Learn  How Excel works with two digit year numbers

Documents the 2029 rule, regional-setting effects, distinctions between entry routes, and the separation of stored date interpretation from cell display. Local behaviour must be checked for the actual product, settings, and workflow.

[5] IETF RFC Editor  RFC 3339 Date and Time on the Internet Timestamps

July 2002. Section 3 addresses two-digit years; sections 1 and 5 define scope and timestamp representation. Quoted requirement is from section 3. A date without a time is not, by itself, a complete RFC 3339 timestamp.

[6] EBSCO Research Starters  Gregory XIII Reforms the Calendar

Historical background for the attribution to Gregory XIII and the 1582 calendar reform.

[7] Annals of Improbable research. Download the January 1999 edition from this page https://improbable.com/airchives/miniair/ Below you will find JUST the Y2K relevant sections.

[8] Email: 12 November 1998; Four digit years and Y10K.

Typos preserved.

“Note also that the year is 4-digit, and the software is Y2K complient. I have my doubts about Y10K though :-)”

[9] 14 Dec 1997; “Re: premature Y2K problem”


Leave a comment