RFC 3339 vs. ISO 8601
152 comments
·September 7, 2025mg
progval
It is not computer-friendly because the timezone is unspecified. And in some timezones, it is ambiguous during changes from DST to winter time.
aaronbrethorst
Slap a Zulu on there for a little more safety and consistency. https://www.noaa.gov/jetstream/time
fauigerzigerk
Why is it not computer friendly? It's just a local time. This is something we need to be able to express in computers and in brains.
Things like opening hours or appointment times are always local time, and even if Apple disagrees I very strongly believe that alarm clocks should use local time as well.
danlitt
If local time is qualified with where "local" is then it is identical to using a time with a locale, like Europe/London or whatever. Unqualified local time is wrong/confusing the moment you have any requirement which crosses a time zone (which happens when you wouldn't expect it, that's the whole reason people care about this problem).
Even your example of alarms is not obvious. If you set a timer, or a daily alarm to wake up by, then yes. But if you set an alarm for some event, like sunrise for example, then you would need a zone.
pasc1878
Well is it a local time or not. If it is a local time where is it a local time?
You need a timezone as well.
Ekaros
Local time to where?
There is even more fun corner cases. Say you live at border of timezone. First have a meeting at 12:00 for 45 minutes in one zone, then move westward and now have an other meeting at 12:00. How do you mark these in calendar? Communicate them? Make historical log?
rini17
But if there's local DST change between today and tomorrow? Then naive calculation of "Add 1 day and 3 hours to a date." is wrong.
twelvedogs
If you put times in a database without timezone you will regret it
hdgvhicv
2025-11-02 01:30:00 in New York.
When does that happen.
SideburnsOfDoom
> It's just a local time.
It's potentially a local time, potentially not. It's unspecified and that will cause trouble.
If you want to model "stores open at 8:30am, worldwide" then there are data types for that "time only". They are not "date and time".
nine_k
Fair. But the point is that it follows the only reasonable order, consistently from larger units to smaller.
A datetime can be seen as a number written in a positional notation, just with varying base: divmod by 60, 60, 24, 12. When you pick a normal decimal / hex / binary number, you expect that the digits in it come in the order of magnitude changing: thousands, hundreds, tens, ones. Mixing them would feel crazy. By the same token, formats like dd-mm-yyyy HH:MM or mm-dd-yyyy are crazy; sadly they are traditional.
rocqua
Looking through the original article, this date format is only available in the RFC, and then only with the Z (which makes it UTC).
Is there a timezoned version of this that is standardized?
dijit
the number after the Z is the offset to UTC.
2025-09-07 10:57:00Z+2 would be CEST for example. (+2 hours ahead).
2025-09-07 04:57:00Z-4 would be EDT (4 hours behind UTC)
lmm
Specifying an offset, as certain datetime formats do, is worse than not specifying any timezone information at all. I'm not aware of a standardised computer date format that includes the symbolic timezone, sadly.
zarzavat
Agreed, offsets are an anti-pattern. Any time you have a nonzero offset you almost certainly want either a tz name (e.g. Europe/Paris), a local datetime, an instant, or a formatted string.
Datetime + tz name: a point in time and space that is responsive to time zone changes. E.g. Our zoom meeting is on 3 Feb 2026 17:40 in Moscow time.
Local date time: a calendar date that is independent of time zones.
Instant: an exact point in time. e.g. the rocket will launch at 123456789 seconds from the Unix Epoch TAI.
Formatted string: an exact point in time rendered for the human user in their local timezone and calendar, taking into account leap seconds. E.g. The rocket will launch on 7 Ramadan 1447 AH, Saudi time.
mg
Do you really need the timezone for each entry in the storage layer?
The application knows how it stores data, so it can just use UTC or whatever it likes. One timezone for all entries.
The interface then can display it in a way the user likes.
procaryote
Depends on what you need.
If you specifically only care about moments in time, throwing away the input time zone might be fine.
If the application is more human centric, timezones are often very useful as humans move around but often think about time as timezone-relative. A log of your daily activities would be confusing if a past event logged as 09:16:01 suddenly showed up as 07:16:01 because you're travelling when viewing it.
NAR8789
This sounds like a footgun.
At some point some application developer will introduce a bug where they're not sending utc.
Without the time zone, the wrong times will end up in the database, bad data mixed in with good. This will be a nightmare to fix.
With the time zone, I don't think this class of bugs is possible. Most application developers will wrap the time in an object that allows them to do time operations without needing to directly handle time zone in most cases.
creatonez
For timestamps/instants, sure you can just use UTC. But you cannot do human calendar math on instants, else you will ruin someone's entire day once you inevitably hit relatively common edge cases where civil time matters.
nine_k
From bitter experience: yes, having TZ-aware dates and times everywhere is helpful, and saves you more in (lack of) trouble than it costs in storage and "hassle".
isbvhodnvemrwvn
And then your country ditches/adopts the DST and you have angry customers because your app has messed up their future appointments.
GoblinSlayer
You need time zone to parse time.
zarzavat
Not all datetimes need a timezone. My next birthday is on November 17 2025 at 00:00 (it's not really). It's on that date regardless of where I am in the world, it follows me!
So yes, I agree a local datetime format is necessary but not sufficient.
xeonmc
It's also the Swedish time format I believe[0]
LukeShu
Except for not including a timezone offset, that's one of the RFC 3339 formats.
jolmg
> "YYYY-MM-DD hh:mm:ss"
> It is human-friendly and computer-friendly at the same time.
It's not shell-friendly, because of the space. The shell being an interface between humans and the computer, this takes a chunk out of it being human-friendly and computer-friendly. You'll have to worry about quoting the thing, involve messing with IFS when making arrays of the things, extract both pieces out of text columns aligned with spaces, awk's NF wouldn't correspond with number of fields anymore, etc. Would make timestamps unnecessarily annoying to interact with. Better to at least make it an underscore. Still quite readable.
magnio
Not exactly computer friendly, since filenames cannot contain ":" on Windows.
integralid
And cannot be longer than 8 characters on DOS.
afiori
Then replace it with _ or anything else it is going to be equally understandable
eadmund
Not all computers are Windows!
And not all computer-users worry even a little bit about compatibility with Windows.
theandrewbailey
Considering that most normie non-tech people use Windows, compatibility with Windows is important.
karambahh
Others point out missing tz.
It's also not that "user friendly": depending on their locale, users will usually expect for instance DD/MM/YYYY. Sorting by YYYY-MM-DD won't feel natural to them.
reacweb
I am french. Everydays, we use DD/MM/YYYY or DD/MM/YY. Sometimes, I encounter YYYY-MM-DD, for example at the beginning of a document reference or in a file name. For me, it feels natural and I have no issue to make this switch mentally. The only problem I encounter is in english: MM/DD/YYYY. Hopefully less and less people are using this insane order.
jolmg
> Sorting by YYYY-MM-DD won't feel natural to them.
It's dictionary sorting.
anfogoat
> It is so elegant and common that even though it is not part of a standard ...
YYYY-MM-DD hh:mm:ss seems valid ISO 8601 to me, isn't it? Neither the "T" nor the timezone are required as far as I recall.
EDIT: The site says ISO 8601-1:2019 requires a T for datetimes, and that even though previous editions allowed for no T, a space was never allowed. This is shocking news to me.
burntsushi
It's not elegant at all. This is a horrible idea because it doesn't account for time zone transitions. You could even end up with a time that will never appear on your clock.
For example, what is the answer to in New York?
SELECT DATETIME('2025-03-07 23:30:00', '+1 day', '+3 hours');
If you said `2025-03-09 02:30:00`, then that would just be wrong. Because that time never appeared on clocks in New York.mrinterweb
I don't think I realized how many alternative formats there are for both 3339 and 8601. Most of those alternative formats are redundant. I like that this chart shows the venn diagram of where these standards intersect.
drob518
Every programmer starts off thinking that dates and times are easy. “Just do …,” they’ll say. And then you realize that ISO 8601 has more than a few ways just to write down the time, let alone manipulate it. Dates and times are a very, very deep rabbit hole. Fortunately most of the time you can get by with just local dates and times or zoned dates and times.
mesrik
Anyone else find it odd that C99 strftime() %F and %T equivalents did not make it later revisions ISO 8601 and RFC 3339 ?
https://en.cppreference.com/w/c/chrono/strftime
Man page strftime shows,
%F Equivalent to %Y-%m-%d (the ISO 8601 date format). (C99) %T The time in 24-hour notation (%H:%M:%S). (SU)
The Op linked page did not recognise these. I tried with the "%FT%T%z" which works fine with date and strftime().
I've probably used %F and %T about 20 years with no issues linux, bsd and mac that I wrote code over the years.
BTW, It would be nice to see some reference or comparison how systems stdlib implementations match with these standards if there is one.
One gripe I've got with RFC3999 and it's not nice to have the semicolon in filename if you intend to use it file or directory name. As it conflicts and easily becoome issue when not quoted while using rsync or any command that thinks colon (:) separates and indicates host name. I'm not sure if colon would cause issues with windows but there is chance it could as it's used indicating device name.
ps. I had to implement many stdlib time.h defined functions my own between -89 - 92 for my then work as Turbo C 2.0 and 3.0/3.1 did not implement these. I recall that last time I touched these and fixed issues was when I got P.J. Plaugers The Standard C Library book when it was brand new -92. When earlier proprietary C-compliers libraries sources had not been available, that Plaugers book was was great help for many :)
tliltocatl
Everything that isn't MDY is ok. MDY - burn in hell.
mceachen
You need to scroll that table: 8601 has so so many formats that are just as worthless without context as MDY. %C or %h%m are egregious.
tliltocatl
What makes MDY special is that it is worthless even with its normal context yet still widely used.
Those you mention make perfect sense in context: %C is usefull for historians (would you rather be parsing roman numbers?) and %h%m is good for voice radio transmission. Ideally you want to tag a format so that you have context, but I guess that's a bit difficult to do without introducing localization. It's somewhat akin to the issues with less common script in Unicode - yes, those are somewhat weird, but they do have a purpose. The standard tries to encompass every usecase rather than take a YAGNI approach, which is a sensible (if opinionated) thing to do.
On the contrary, MDY would appear in the same context you would expect DMY or YMD. It's only supposed advantage is that it maps English word order. But it is unsortable without parsing.
thayne
My main complaint about RFC 3339 is it doesn't have anything for specifying a duration/period or ranges.
bpavuk
fun fact - ATProto requires you to store all the datetime strings in a format that's compliant with both RFC 3339 and ISO 8601 plus you cannot specify time without date.
when I worked on datetime portion of Katproto, I had this link pinned for quite some time as a reference! ah, nostalgia...
also, post factum, I find this technical decision actually good - instead of supporting all possible variations of ISO 8601 or all the variations of RFC 3339, why not just support the intersection? that way, the format will be parseable by anything compliant with any standard of these two, and you only need to handle a very small set of branches.
TheChaplain
From last month; https://news.ycombinator.com/item?id=28976526
evrennetwork
[dead]
01HNNWZ0MV43FF
The difference is that `date`, the command, and `chrono` the Rust crate implement RFC 3339, so we don't need to worry about ISO :)
My favorite datetime format is "YYYY-MM-DD hh:mm:ss".
I consider it the "Markdown for time". It is human-friendly and computer-friendly at the same time. It is supported by many languages and databases. It is so elegant and common that even though it is not part of a standard, LLMs started to use it when writing answers:
Me: SQLite: Add 1 day and 3 hours to a date.
Perplexity: SELECT DATETIME('2025-09-07 07:51:00', '+1 day', '+3 hours');