2020-10-22

datetime

Use UNIX milliseconds

I'm making an app with chat, so time actually matters. Most advice online boils down to "pick a format." Cool, thanks. I wrote this so I can link it instead of re-explaining it in a PR.

This is not ISO-8601 fanfic. It is me being annoyed in a structured way.

Store a UTC instant. UNIX milliseconds, or a DateTimeOffset with an explicit offset. Render local, with an explicit timezone. Never pretend a culture-specific string round-trips.

The links, for when a comment wants one. RFC 3339 is the internet profile, 2012-10-03T12:13:00Z. ISO 8601 is the broader standard, and a lot of APIs say ISO when they mean the RFC. POSIX time counts seconds from 1970-01-01T00:00:00Z, and the usual encoding ignores leap seconds. In .NET, DateTimeOffset is an instant plus an offset. A plain DateTime can be UTC, local, or unspecified, and mixing those is the historical footgun. Microsoft wrote it down. Ticks are 100 ns since year 1. Finer than a chat message needs. Patrick McKenzie's Falsehoods programmers believe about time is the list of edges that kill "just parse the string." The civil rules live in the IANA time zone database. .NET's timezone overview is the API side.

A totally ordered id can sort a chat without anyone agreeing on a clock. You still want an order a person can read, and you still want a way to reconcile two copies. A timestamp, with a plan for collisions, is the hammer.

Same instant, different strings. Seconds and milliseconds mostly left off. The opinions are mine.

DateTime codeDescriptionMy opinion
2012-10-03T12:13:00ZUTC time friendly
10-03-12 12:13PMUS/UK short AM/PMStupid, because counting 12 + 12 only makes sense when using
10-03-12 12:13US/UK short 24HInternaly sencible, internationally stupid
10-03-2012 12:13PMUS/UK long AM/PMsee above
03-10-12 12:13Short internationalWhat I grew up using, but it's confusing
03-10-2012 12:13Long internationalThe most sencible day-to-day format
2012-10-03 12:13Sortable long internationalVery useful for sorting
2012-40-3 12:13year-week-weekday internationalVery useful for class schedules
2012-40-4 12:13year-week-weekday USWho thought it was a good idea to start the week on Sunday?
201210031213sortable character safeGreat for document naming or a timestamp on a database-row
100320121213non-sortable character safe USNEVER use this
1349266380UNIX time secondsSomewhat useful
1349259180000UNIX time millisecondsTHE best way to use date and time, (see bellow)
You might be confused by the "snowflaking" of the US in all of this, but it has it's reasons, mostly the unwillingness to risk confusion among it's citizens. However the US Military does use the the UTC time,

Other calendars are in use. This list is not complete, and it is eurocentric on purpose.

DateDecription
5773-Tishri-18Hebrew
1433-Dhu I-Qa'da-18Islamic
1391-Mehr-13Persian
1934-Asvina-12Indian Civil
Dragon-Dog-18Chinese variant 1 (not actually used)
4710-8-18Chinese variant 2 (China actually use Gregorian)
there are scores upon scores of others, some only used by tribes in micronesia or in the himalayas, (that there's probably a conversion for anyway, because developers love a challange, or some social anthropologist needs it in their research

I will not denegrade the non-gregorian calanders, and they are useful for those who share them, but I don't think I'll be using Dragon-dog-18, (though if I were, I would have to have some logic to assume it's the closest Dragon in the last 12 years)

Timezones, for storage: ignore them. Store a universal instant and convert on the way out. The video I send people is Tom Scott, The Problem with Time & Timezones.

The computer counts in milliseconds. .NET also has ticks, which are much smaller, and I do not need them here.

  1. Persist an unambiguous instant.
  2. Convert for display with an explicit timezone. TimeZoneInfo, Noda Time, whatever you will actually maintain.
  3. A locale string is a projection. It is not the key.

All posts