timestamp-six ts6

ts6 · a timestamp, six characters wide

Fourteen
characters in.
Six out.

A tiny, dependency-free timestamp codec. yyyymmddHHMMSS collapses to six URL-safe characters that still sort in time order — one algorithm, four byte-identical languages.

  • 6 chars · 2025–2086
  • sorts chronologically
  • URL & filename safe
  • PHP · Python · JS · bash
  • MIT
ts6 encoder live · local time

yyyymmddHHMMSS — editing pauses the clock

encode
copied

decode — paste a ts6 code

Interactive demo needs JavaScript — the worked example below shows it statically.

why six characters

Compact first — then three nice bonuses.

The short form exists mainly to save screen space, where a full timestamp won't fit (mobile, especially). Everything else is designed in for free, in priority order.

01

Compact

Six characters cover every timestamp from 2025 through 2086. Then it grows one character at a time.

02

Sortable

The alphabet is in ASCII order, so a plain string sort puts codes in chronological order.

03

Safe

Output is [A-Za-z0-9] only — drops straight into URLs and filenames. A - appears solely on error.

04

Readable

Month is always uppercase A–L, hour always lowercase a–x — your eye finds them at a glance.

the encoding

A per-component base62 codec.

Each of the six timestamp fields becomes exactly one base62 digit via a fixed offset. The alphabet is 62 symbols in ASCII order — which is why a naive sort equals a chronological one.

0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
index 0…9  ·  10…35 (A–Z)  ·  36…61 (a–z)
FieldSourceOffsetRenders asNotes
yearyyyyyear − 20250-9A-Za-zepoch 2025, so 2026 → 1
month01–12+9A–Lalways uppercase
day01–31none1-9A-Vraw base62
hour00–23+36a–xalways lowercase
minute00–59none0-9A-Za-xraw base62
second00–59none0-9A-Za-xraw base62
2026·06·03  10:42:00
↓ encode
1F3kg0

Reading 1F3kg0: 1 = 2026, F = June, 3 = the 3rd, k = 10h, g = 42m, 0 = 00s.

Sort check: 10:43:001F3kh0, which sorts after 1F3kg0. Correct.

range & the future

ts6 → ts7 → … → tsN.

One year character covers 2025–2086. When year − 2025 tops 61, the year field grows by one base62 digit — the trailing five characters never change — so the format quietly becomes ts7, ts8, and on. Decoding infers the year width as length − 5, no flag needed.

FormYear digitsTotal lengthMax year offsetUpper year
ts616612086
ts7273,8435868
ts838238,327240,352
ts94914,776,33514,778,360
ts10510916,132,831916,134,856

ts7 alone reaches the year 5868, so the format sails past the year 3026 without ever leaving ts7. By ts10 we are at roughly 916 million AD — at which point the heat death of the sun is the more pressing item in the backlog. This format will not be what fails you.

Known limitation — cross-width sort. Sorting is perfect within one width. Because the year field is variable-width, a ts6 code and a ts7 code don't sort against each other (z… sorts after 10…). Since ts7 only appears after 2086 — by definition someone else's problem — it's documented rather than papered over with zero-padding.

error handling

Fails loud. Never lies.

A bad input doesn't throw and doesn't silently pass. It produces a deliberately broken output that fails downstream, with a - marking each offending position. One bad decode character means the length goes wrong — on purpose, so it can't masquerade as a clean 14-char string.

Valid — round-trips

encode("20260603104200") "1F3kg0"
decode("1F3kg0") "20260603104200"
encode("20251231235959") "0LVxxx"

Bad — marked, not thrown

encode("20261303104200") "1-3kg0" // month 13
encode("20240101000000") "-A1a00" // before epoch 2025
decode("1F3kg") - // too short

four languages, one algorithm

Two functions. Same verbs everywhere.

Procedural, no classes or namespaces: encode (14 → ts6) and decode (ts6 → 14). Pick whatever fits your stack — the codes are interchangeable.

ts6.sh · sourcestrict-mode safe
# functions echo the result; capture with $( )
source ts6.sh

code=$(ts6_encode 20260603104200)   # 1F3kg0
ts=$(ts6_decode 1F3kg0)            # 20260603104200
echo "$code -> $ts"
ts6.php · requireprocedural
require 'ts6.php';

echo ts6_encode('20260603104200');  // 1F3kg0
echo ts6_decode('1F3kg0');          // 20260603104200
ts6.py · importno deps
import ts6

ts6.encode('20260603104200')  # '1F3kg0'
ts6.decode('1F3kg0')          # '20260603104200'
ts6.js · ESM / browserdefault export
import ts6 from './ts6.js';
// or: import { encode, decode } from './ts6.js';

ts6.encode('20260603104200');  // '1F3kg0'
ts6.decode('1F3kg0');          // '20260603104200'

This very page runs on the real ts6.js above — the live converter at the top imports the same file you'd download.

download

One drop-in file. No dependencies.

Take only the language you need, or grab the whole set. Nothing to install, nothing to configure.

git clone https://github.com/grimblefritz/timestamp-six.git

The four implementations are byte-identical in both directions for every input, errors included — kept honest by one shared vector table. Source and issues live on GitHub.