Dates, numbers and encoding pitfalls across formats

Why dates should be strings or epochs but never both, how big integers and floats lose precision in JSON, and the null, bytes and Unicode differences between formats.

Dates: pick one representation

RepresentationExampleProblem
ISO 8601 string2026-09-18T10:00:00ZNone for interchange; sorting is lexicographic and correct
Epoch seconds1789123456Ambiguous unit; range limited on 32-bit systems
Epoch millis1789123456789Needs 53 bits for precision in JavaScript
Local string18/09/2026 10:00Ambiguous order and no zone — never interchange this
Date only2026-09-18Is not an instant; do not convert it to a timestamp
{
  "createdAt": "2026-09-18T10:00:00Z",
  "createdAtEpoch": 1789123200,
  "birthday": "1990-04-01"
}

Use the string form for anything crossing a boundary, and store a timestamp in the database. Keeping both an ISO string and an epoch in the same document is a guaranteed source of disagreement.

Numbers that do not survive the trip

JSON.parse('{"id": 9223372036854775807}')
// -> { id: 9223372036854775808 }   wrong, precision lost

JSON.stringify({ x: 0.1 + 0.2 })
// -> '{"x":0.3}', but the value is 0.30000000000000004

// money as a float accumulates error
0.1 + 0.2 === 0.3            // false
  • JSON numbers are IEEE 754 doubles in most parsers, so integers above 2^53 lose precision.
  • Send 64-bit IDs as strings; the receiver can parse them with a big-integer library.
  • Represent money as a minor-unit integer (1999) or a string decimal ("19.99"), never a float.
  • YAML and TOML preserve integer types when the reader supports them; CSV does not.

Null, bytes and text across formats

ConceptJSONMessagePack/CBORCSV
Missing valueOmitted keyOmitted keyShort row or empty field
Explicit nullnullnil / nullEmpty field — indistinguishable from empty string
Binary dataBase64 string (convention)Native byte stringBase64, and usually broken by line endings
Non-finite numbersInvalid JSON (Infinity, NaN)May be supportedPlain text token
UnicodeUTF-8, \uXXXX escapesUTF-8, possibly invalidDepends on the file encoding

The CSV row is the dangerous one: an empty field, an empty string and a null are all the same bytes. If nullability matters, encode it explicitly — for example an empty field means null and "" means the empty string.

⚠️
Do not put non-finite numbers in JSON. Infinity, -Infinity and NaN are not valid JSON tokens, and a strict parser will reject the document while a lenient one quietly accepts it — which means the bug appears only in production.

FAQ

Should I send dates as epoch integers?
Only for internal, high-volume payloads where both ends agree on units and range. For anything long-lived or cross-team, ISO 8601 strings in UTC are self-describing and sort correctly as text.
How do I send a 64-bit ID through JSON?
As a string. Parsers in JavaScript and many dynamic languages lose precision above 2^53, and the corruption is silent because no exception is raised.

Converting between formats with jq, yq and csvkit Choosing a format: size, speed, readability and tooling

Last refreshed 2026-09-18.