BaseHalf
All posts

Learn RFC 3339 timestamps with BaseHalf and AI

We opened the real rfc3339-timestamps folder in BaseHalf, laid format, offset, and restriction notes out as cards beside a local copy of RFC 3339, listed those notes as upstream on the practice card, and had Claude Code in the Agent Area grade four timestamp cases as correct.

A timestamp is easier to check when the format, the offsets, and the restrictions each have their own card, the RFC sits in the same folder, and an agent can see both the notes and the practice answers. We made an ordinary Desktop folder, put six short Markdown notes and a local copy of RFC 3339 into it, and opened that folder in BaseHalf. The window title became rfc3339-timestamps. The sidebar listed every file. Each file became a card. We started Claude Code in the Agent Area on the right, with the practice card selected.

The folder on disk was Desktop/basehalf-learn-sessions/rfc3339-timestamps/. These were the files on the canvas:

rfc3339-timestamps/
  00-goal.md
  01-format.md
  02-offsets.md
  03-restrictions.md
  04-practice.md
  rfc3339.txt
  sources.md

BaseHalf window titled rfc3339-timestamps: the sidebar lists 00-goal through sources, including rfc3339.txt; the canvas shows the goal, three concept cards, the RFC text, sources, and 04-practice, with connection lines from the concept cards and sources into the practice note.

What each card held

00-goal.md set the boundary: parse an Internet timestamp into a full date, a time, and an offset; tell Z, +00:00, and -00:00 apart; reject a timestamp that is missing an offset or uses hour 24; and check four practice cases against RFC 3339. The folder studies RFC 3339, a profile of ISO 8601, not the ISO standard itself.

01-format.md kept the §5.6 grammar: date-time is a full-date, then T, then a full-time. The year is four digits. Seconds are required; a fractional second is optional. full-time always includes a time-offset. A note in that section says T and Z may alternatively be lower case, and that applications may, for readability, put a space between the date and the time instead of T. That space is an application choice; it is not in the ABNF itself.

02-offsets.md wrote Z as UTC, and a numeric offset as "local time minus UTC", so 18:50:00-04:00 is the same time as 22:50:00Z. It also kept the §4.3 distinction: -00:00 means the time in UTC is known but the local offset is unknown, and that this differs semantically from Z or +00:00, which imply that UTC is the preferred reference point. An unqualified local time, with no offset, is not acceptable for Internet interchange. Alphabetic zone labels are not part of this format.

03-restrictions.md kept the four-digit year rule from §3, the hour range 00 through 23 from §5.7 (ISO 8601 permits hour 24; this profile does not), and the leap-second rule: time-second may be 60 only at an inserted leap second. It pointed at 1990-12-31T23:59:60Z and 1990-12-31T15:59:60-08:00, and said applications should not generate an inserted leap-second timestamp until the leap second is announced.

sources.md linked RFC 3339 (Klyne and Newman, July 2002), with the local copy rfc3339.txt. It also said we did not open ISO 8601, which is not a free download in the same way.

Upstream on the practice note

The practice note listed the three concept cards and sources.md in its upstream list. On the canvas, lines from 01-format, 02-offsets, 03-restrictions, and sources ran into 04-practice. The file began with:

upstream:
  - 01-format.md
  - 02-offsets.md
  - 03-restrictions.md
  - sources.md

That list sticks in the file. Selection does not: it lives in .bh/cache/selection.yaml only while BaseHalf is open. We selected the practice card, and the status bar showed 04-practice, before asking Claude Code to grade it.

The four practice cases

The practice card asked for a short answer and a one-line reason in each case, preferring the cards and RFC 3339 over a remembered rule.

  1. Parse the RFC 3339 §5.8 example 1996-12-19T16:39:57-08:00. What is the equivalent time in UTC?

  2. Take 2026-11-15T06:00:00Z, 2026-11-15T06:00:00+00:00, and 2026-11-15T06:00:00-00:00. Do they name the same instant? Do they mean the same thing?

  3. Is 2026-11-15T06:00:00 a valid date-time under the §5.6 grammar? Is 2026-11-15T24:00:00Z?

  4. Is 1990-12-31T23:59:60Z valid under RFC 3339? Is 2026-11-15T06:00:00z (lowercase z) allowed by the §5.6 syntax?

Our answers:

  1. 1996-12-20T00:39:57Z. Section 5.8 gives this conversion: 16:39:57 with an offset of -08:00 is the next calendar day at 00:39:57 UTC. That also follows §4.2: subtract the offset (add eight hours) to get UTC.

  2. They name the same instant, 06:00:00 UTC. They do not mean the same thing. Section 4.3 says -00:00 means the time in UTC is known but the offset to local time is unknown, and that this differs semantically from Z or +00:00, which imply that UTC is the preferred reference point for the specified time.

  3. No, and no. 2026-11-15T06:00:00 has no time-offset, so it is not a full-time and not a date-time under §5.6; §4.4 also rejects unqualified local time for Internet interchange. 2026-11-15T24:00:00Z is invalid in this profile: §5.7 says that although ISO 8601 permits hour 24, this profile only allows 00 through 23.

  4. Yes, and yes with a caveat. 1990-12-31T23:59:60Z is the leap second inserted at the end of 1990; §5.8 gives this exact example, and §5.7 allows time-second to be 60 at an inserted leap second. The first note in §5.6 says T and Z may alternatively be lower case t or z, so 2026-11-15T06:00:00z matches the syntax. The same section also says applications that generate this format SHOULD use upper case, and a using specification (for example in an XML context) MAY require upper case.

rfc3339-timestamps canvas plus Agent Area: Claude Code v2.1.325 (Opus 5.5, xhigh, Claude Ultra) loads the BaseHalf skill, reads rfc3339.txt, and says all four answers in 04-practice.md are correct, quoting §5.8 for the first UTC conversion.

What Claude Code actually said

Treat the reply as a draft. In this session Claude Code (v2.1.325, shown in the window as Opus 5.5 with xhigh effort, Claude Ultra) said all four answers were correct, that each one fit the upstream notes and the local rfc3339.txt, and that it had not edited any files. The run lasted 1 minute 24 seconds. The practice files on disk kept the same timestamps they had before the session.

For the first case it quoted §5.8: the example is equivalent to 1996-12-20T00:39:57Z in UTC. It also quoted §4.2: numeric offsets are "local time minus UTC", and a negative offset is handled by adding the absolute value. 16:39:57 plus eight hours is 24:39:57, which rolls over to 00:39:57 on December 20. We checked those two passages in the local RFC; the quotes hold. Some of the line numbers it printed next to the quotes were a few lines off, so we used the section text, not those numbers.

For the second case it agreed they name the same instant, 06:00:00 UTC, and that they do not mean the same thing. It quoted §4.3 in full on -00:00 versus Z or +00:00, and noted that our answer followed that wording, including the word "imply". It also pointed at the §2 definition of Z as a suffix that "denotes a UTC offset of 00:00". We checked both; they are in the local copy.

For the third case it agreed both strings are invalid, with two tighter readings. The missing-offset string fails the §5.6 grammar, where full-time is partial-time plus a time-offset. Using §4.4 as support is fine, it said, but that section is a rationale: it calls the interoperability problems of unqualified local time "unacceptable for the Internet", and then puts a MUST on systems to stay in sync with UTC. "§4.4 also rejects" slightly overstates what that section does; the grammar alone is enough to make the string invalid. We checked §4.4; that distinction is right.

On hour 24, it agreed §5.7 is the right place to look, and quoted the sentence that this profile only allows 00 through 23. It then pointed out a wording problem in our question. The §5.6 ABNF writes time-hour = 2DIGIT and puts 00-23 only in the comment. 2DIGIT by itself matches 24. A validator built from the ABNF tokens alone would accept the hour; the range in the comment plus the prose in §5.7 is what rejects it. The question had asked "under the §5.6 grammar". We checked that production; the comment is where the range is written, and §5.7 is the actual restriction.

The same Claude Code session, scrolled to the end: it marks the lowercase-z caveat accurate, flags a loose leap-second citation in the restrictions note, and shows the run lasted 1 minute 24 seconds.

For the fourth case it agreed 1990-12-31T23:59:60Z is valid, quoting the §5.8 example ("the leap second inserted at the end of 1990") and the §5.7 rule that time-second may be 60 at an inserted leap second. Appendix D's table also lists 1990-12-31. It agreed that lowercase z is allowed, and quoted the first note in §5.6 on t and z. It said the caveat about a using specification MAY requiring upper case is accurate, and that the paragraph with the MAY and the SHOULD has no NOTE: label of its own: it sits between the two notes at the same indent, so calling it "the same note" is a fair reading. The MAY-restrict sentence is not in our format note; the answer took it from the RFC. We checked those passages; the quotes and the layout of the notes hold.

It then listed citation issues in the notes, not in the practice answers. The restrictions note is loose where it says §5.7 and the examples in §5.8 give the two 1990 strings: only §5.8 gives 1990-12-31T23:59:60Z and 1990-12-31T15:59:60-08:00. Section 5.7 gives the general patterns XXXX-06-30T23:59:60Z and XXXX-12-31T23:59:60Z. The 1990 examples should be cited to §5.8, or to §5.8 plus Appendix D. We checked; that is right. It also said the offsets note paraphrases "imply" as "name" for Z and +00:00, while the practice answer used the RFC's word, and that "unacceptable for Internet interchange" is close to "unacceptable for the Internet". Those wording points do not change the grades.

What this session can and cannot show

Four worked cases are a start, not a complete reading of RFC 3339. We did not walk leap-year code, the historical 19-minute Dutch offset in the last example, or the security note in §7. The model can misquote a section or a line number; the local RFC is the check, and in this run the section quotes we verified held, while several line numbers did not. A later session can take the same folder, tighten the leap-second citation, and keep going from there.