Live app: https://hopezh.github.io/datetime-barcode/
A minimalistic web app that converts a date and time into a fixed-width digit string in base 2–10, then renders that string as a "barcode" made of Unicode symbols you pick to represent each digit. Step 00 picks the number system from nine tabs — Binary, Ternary, Quaternary, Quinary, Senary, Septenary, Octal, Nonary, and Decimal, each marked with a dice icon showing its base — and steps 01–05 below it are the same flow, one per base.
Each datetime component is encoded with a fixed digit width, with - between fields and _ between the date and time halves:
- binary (bits): year 12, month 4, day 5, hour 5, minute 6, second 6
- ternary (trits): year 8, month 3, day 4, hour 3, minute 4, second 4
- quaternary: year 6, month 2, day 3, hour 3, minute 3, second 3
- quinary: year 6, month 2, day 3, hour 2, minute 3, second 3
- senary: year 5, month 2, day 2, hour 2, minute 3, second 3
- septenary: year 5, month 2, day 2, hour 2, minute 3, second 3
- octal: year 5, month 2, day 2, hour 2, minute 2, second 2
- nonary: year 5, month 2, day 2, hour 2, minute 2, second 2
- decimal: year 4, month 2, day 2, hour 2, minute 2, second 2
Example:
-> 2026-07-15_18:35:49
binary -> 011111101010-0111-01111_10010-100011-110001
-> ▒▚▚▚▚▚▚▒▚▒▚▒ ▒▚▚▚ ▒▚▚▚▚ ▚▒▒▚▒ ▚▒▒▒▚▚ ▚▚▒▒▒▚
ternary -> 02210001-021-0120_200-1022-1211
-> ▖██▀▖▖▖▀ ▖█▀ ▖▀█▖ █▖▖ ▀▖██ ▀█▀▀
quaternary -> 133222-13-033_102-203-301
-> ▄▟▟▐▐▐ ▄▟ ▁▟▟ ▄▁▐ ▐▁▟ ▟▁▄
quinary -> 031101-12-030_33-120-144
-> ▘▓▌▌▘▌ ▌░ ▘▓▘ ▓▓ ▌░▘ ▌▇▇
senary -> 13214-11-23_30-055-121
-> ▝▛▐▝▙ ▝▝ ▐▛ ▛▂ ▂██ ▝▐▝
septenary -> 05623-10-21_24-050-100
-> ▁▆▇▃▄ ▂▁ ▃▂ ▃▅ ▁▆▁ ▂▁▁
octal -> 03752-07-17_22-43-61
-> ▏▌█▊▍ ▏█ ▎█ ▍▍ ▋▌ ▉▎
nonary -> 02701-07-16_20-38-54
-> ▘▖▟▘▝ ▘▟ ▝▛ ▖▘ ▗█ ▞▚
decimal -> 2026-07-15_18-35-49
-> ▁▔▁▅ ▔▆ ▏▄ ▏▇ ▂▄ ▃█
Built with React + Vite (plain JSX, no TypeScript), run with Bun. No other runtime dependencies.
Requires Bun.
bun install
bun run dev
Then open http://localhost:5173.
Other commands:
bun test— run the unit testsbun run build— production build intodist/bun run preview— serve the builtdist/locallybun run lint— lint with oxlint
Pushes to main deploy the app to GitHub Pages via .github/workflows/deploy.yml.
00. Select number system — pick the tab for the base you want. Each tab keeps its own state, so you can set up several bases and switch between them freely.
Then walk through the five labeled steps:
- Specify date and time — a date picker plus three 24-hour dropdowns for hour, minute, and second, defaulting to the moment the app loaded. Click -> Step 2 to send it down. Alternatively, use the field below it to paste any number (digits with
-and_separators, of any length) and send that instead — each field is converted independently, so the datetime widths don't apply. - Convert date and time — the string arrives in an editable String to be converted field, so you can adjust it by hand. Click Convert to encode it as the fixed-width digit string.
- Pick symbols and colors — click a slot button (one per digit:
0 =and1 =for binary, up to9 =for decimal) to arm it, then click a glyph in the grid in step 4. After each pick the next slot arms automatically, so one grid click per digit completes the setup, and assigned glyphs are badged with their digit in the grid. The color picker under each slot tints that digit's symbol. The shortcuts are Assign random symbols across all sets (distinct random symbols from the three non-experimental sets), Assign random symbols in the selected set only (from the set chosen in step 4), Assign unique random colors (a distinct color per digit from a palette that stays readable in both themes), and Assign one random color (the same random color for every digit). Export number-symbol-color config downloads the current assignment as JSON and Import number-symbol-color config loads one back — entries are matched by digit, so a config saved under another base still loads, dropping extra digits and leaving missing ones empty. - Select symbol set — choose which Unicode block the grid shows (Block Elements, Box Drawing, Geometric Shapes, or the experimental Legacy Computing sextants, which may not render with default fonts). Assignments survive switching sets, so the digit symbols can come from different sets.
- Convert the string to barcode — click Translate to render the barcode, with each symbol shown in its digit's color. Separators become spaces so the fields read as groups.
The barcode has a copy button that puts both plain text and colored HTML on the clipboard — when pasting into PowerPoint or Word, choose "keep source formatting" to keep the colors. The toggle in the header switches between dark and light mode; the initial theme follows your system preference.
datetime-barcode/
├── index.html
├── package.json
├── vite.config.js
├── public/
│ ├── qr-code.svg # theme-aware favicon
│ └── dice-2.svg … dice-10.svg # per-base tab icons
└── src/
├── main.jsx # bootstrap
├── App.jsx # theme + tab switching; renders one BarcodeBuilder per tab
├── index.css # theme tokens + all styles
├── logic/ # pure functions, zero React imports
│ ├── datetimeCode.js # parse + fixed-width encoding in a given base
│ ├── datetimeCode.test.js
│ ├── barcode.js # digit string → symbol + color substitution
│ ├── barcode.test.js
│ ├── configFile.js # symbol/color assignment ↔ JSON file
│ ├── clipboard.js # plain-text + rich-HTML clipboard write
│ └── random.js # sampling without replacement
├── data/
│ ├── symbolSets.js # curated Unicode symbol sets
│ └── colorPool.js # mid-tone colors readable in both themes
└── components/
├── BarcodeBuilder.jsx # steps 01–05, parameterized by base
├── Step.jsx # numbered section shell
├── ExampleSubtitle.jsx # the hero example, recolored each load
├── PageFooter.jsx # reference links
├── ThemeToggle.jsx
├── GithubLink.jsx
├── CopyButton.jsx
├── SymbolSetPicker.jsx
├── SymbolGrid.jsx
├── DigitAssigner.jsx
├── DatetimeInput.jsx
├── NumberPaste.jsx
└── CodeDisplay.jsx
Per-tab state lives in each BarcodeBuilder instance (props down, callbacks up); all tabs stay mounted so switching preserves their state. The logic/ modules return result objects ({ ok, ... }) instead of throwing, since malformed input is an expected state while typing.
- Numeral systems: binary · ternary · quaternary · quinary · senary · septenary · octal · nonary · decimal
- Block Elements — U+2580–259F
- Box Drawing — U+2500–257F
- Geometric Shapes — U+25A0–25FF
- Symbols for Legacy Computing — U+1FB00–1FB3B (sextants)
- Vite · React · Bun
- Page design study: aihero.dev/ai-coding-dictionary