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
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.mdThat 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.
-
Parse the RFC 3339 §5.8 example
1996-12-19T16:39:57-08:00. What is the equivalent time in UTC? -
Take
2026-11-15T06:00:00Z,2026-11-15T06:00:00+00:00, and2026-11-15T06:00:00-00:00. Do they name the same instant? Do they mean the same thing? -
Is
2026-11-15T06:00:00a validdate-timeunder the §5.6 grammar? Is2026-11-15T24:00:00Z? -
Is
1990-12-31T23:59:60Zvalid under RFC 3339? Is2026-11-15T06:00:00z(lowercasez) allowed by the §5.6 syntax?
Our answers:
-
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. -
They name the same instant, 06:00:00 UTC. They do not mean the same thing. Section 4.3 says
-00:00means the time in UTC is known but the offset to local time is unknown, and that this differs semantically fromZor+00:00, which imply that UTC is the preferred reference point for the specified time. -
No, and no.
2026-11-15T06:00:00has notime-offset, so it is not afull-timeand not adate-timeunder §5.6; §4.4 also rejects unqualified local time for Internet interchange.2026-11-15T24:00:00Zis invalid in this profile: §5.7 says that although ISO 8601 permits hour24, this profile only allows00through23. -
Yes, and yes with a caveat.
1990-12-31T23:59:60Zis the leap second inserted at the end of 1990; §5.8 gives this exact example, and §5.7 allowstime-secondto be60at an inserted leap second. The first note in §5.6 saysTandZmay alternatively be lower casetorz, so2026-11-15T06:00:00zmatches 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.

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.

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.