TOML Cheatsheet

Numbers Booleans and Dates

Use this TOML reference while you build software engineering projects, review code, or refresh the syntax you reach for most.

Integers

64-bit signed. Underscores separate digits and must sit between digits, never leading, trailing, or doubled.

plain = 99
positive = +99
negative = -17
zero = 0
grouped = 1_000
big = 5_349_221
hex_upper = 0xDEADBEEF
hex_lower = 0xdead_beef
octal = 0o755
binary = 0b1101_0110

parses to:

{"plain": 99, "positive": 99, "negative": -17, "zero": 0,
 "grouped": 1000, "big": 5349221,
 "hex_upper": 3735928559, "hex_lower": 3735928559,
 "octal": 493, "binary": 214}
PrefixBaseSign allowed
none10yes
0x16no
0o8no
0b2no

Leading zeros are forbidden. a = 01 is a syntax error, which neatly removes YAML's octal ambiguity. +0 and -0 are both plain zero. 0x prefixes take lowercase or uppercase hex digits.

Floats

An IEEE 754 binary64. A float is either an integer part plus a fractional part, or an integer part plus an exponent, or both.

frac1 = 1.0
frac2 = 3.1415
frac3 = -0.01
exp1 = 5e+22
exp2 = 1e06
exp3 = -2E-2
both = 6.626e-34
grouped = 224_617.445_991_228

parses to {"frac1": 1.0, "frac2": 3.1415, "frac3": -0.01, "exp1": 5e+22, "exp2": 1000000.0, "exp3": -0.02, "both": 6.626e-34, "grouped": 224617.445991228}.

Unlike YAML, an unsigned exponent is fine: 1e06 is the float 1000000.0. What is not allowed:

InvalidWhy
1.needs a digit after the dot
.7needs a digit before the dot
1.e6needs a digit after the dot
0x1.8p3no hex floats
01.5leading zero

Infinity and NaN

Lowercase words, optionally signed. There is no Infinity spelling.

inf1 = inf
inf2 = +inf
inf3 = -inf
nan1 = nan
nan2 = +nan
nan3 = -nan

+nan and -nan both load as NaN. The sign on NaN is intentionally implementation-defined, so never round-trip it through a comparison.

Booleans

Lowercase only, always. true and false are the only two spellings.

enabled = true
verbose = false

True, TRUE, False, yes, no, on, and off are all syntax errors, not alternative spellings and not strings. a = True fails with Invalid value (at line 1, column 5). This is deliberate, and it is why TOML has no Norway problem.

The four date and time types

RFC 3339 forms. This is the one thing TOML has that JSON does not.

TypeExamplePython (tomllib)
offset date-time1979-05-27T07:32:00Zaware datetime
offset date-time1979-05-27T00:32:00-07:00aware datetime
local date-time1979-05-27T07:32:00naive datetime
local date1979-05-27date
local time07:32:00time
odt1 = 1979-05-27T07:32:00Z
odt2 = 1979-05-27T00:32:00-07:00
odt3 = 1979-05-27T00:32:00.999999-07:00
odt4 = 1979-05-27 07:32:00Z
ldt1 = 1979-05-27T07:32:00
ldt2 = 1979-05-27T00:32:00.999999
ld1 = 1979-05-27
lt1 = 07:32:00
lt2 = 00:32:00.999999

Rules that matter:

- Offset vs local is decided by the presence of an offset. Z or ±HH:MM makes it an offset date-time, an unambiguous instant. Omit it and you get a local date-time, a wall-clock reading with no time zone at all. - A space may replace the T separator, so odt4 above is the same instant as odt1. The T and Z may be lowercase. - Fractional seconds are allowed on any time. Precision beyond what the implementation supports is truncated, not an error, and Python truncates to microseconds. - A local time has no date, so it cannot be converted to an instant. Use it for schedules, not timestamps. - Seconds are required. 07:32 is invalid in TOML 1.0.0. (1.1 relaxes this, and 1.1 is unreleased.)

Choosing a type

You meanWrite
a specific instant2024-01-15T09:00:00Z
a wall-clock appointment2024-01-15T09:00:00
a birthday or release date2024-01-15
a daily cron time09:00:00
a durationthere is no duration type, use seconds = 300
a versionversion = "1.10", a string
a file modemode = 0o644

There is no duration and no null. Durations go in as an integer with the unit in the key name, and absence is expressed by leaving the key out.