Method
A fixture workbook holds the same date serial, 45662, in three cells with three different format codes, plus two numeric cells carrying the Saudi locale tag. The serial corresponds to 5 January 2025 in the 1900 epoch, and the correct Umm al-Qura answer is 05/07/1446.
Three engines read the same file:
ssf0.11.2, the format engine most JavaScript spreadsheet tooling uses, called directly with the code and the value.- LibreOffice 26.2.1.2, converted headless to both HTML and PDF. Its HTML export records the number format it resolved for each cell, so its failures are visible rather than inferred.
- The Sifrsys viewer, rendered in headless Chromium, with the display strings read back from the live DOM.
The reference for the date is not any of the three. It is Intl.DateTimeFormat with the islamic-umalqura calendar, which is the ICU implementation of the calendar in civil use in Saudi Arabia. That choice matters, because ICU also ships islamic-tbla, the arithmetic tabular calendar, and the two disagree.
Reproducing it
Two lines are enough to see the calendars diverge, in any recent Node or browser console:
const d = new Date(Date.UTC(2025, 0, 5))
const f = (cal) => new Intl.DateTimeFormat(`en-u-ca-${cal}-nu-latn`,
{ day: 'numeric', month: 'numeric', year: 'numeric', timeZone: 'UTC' }).format(d)
f('islamic-umalqura') // 7/5/1446 -> 05/07/1446
f('islamic-tbla') // 7/6/1446 -> 06/07/1446For the full three-engine comparison, node tests/fidelity/run.mjs renders both sides and scores the Saudi cells against the specification rather than against LibreOffice. Its LibreOffice output is cached under tests/fidelity/.cache/, so the resolved format codes can be read directly out of the exported HTML.
Results
| Criterion | ssf 0.11.2 | LibreOffice 26.2 | Sifrsys |
|---|---|---|---|
| B2dd/mm/yyyyHijri via the B2 calendar modifier | 05/01/1444 | B205/01/2025 | 05/07/1446 |
| [$-060401]dd/mm/yyyyHijri via the ar-SA locale tag | 05/01/2025 | 06/07/1446 | 05/07/1446 |
| [$-2060401]dd/mm/yyyyHijri plus Arabic-Indic digits | 05/01/2025 | not applied | ٠٥/٠٧/١٤٤٦ |
| [$-2060401]#,##0.00Saudi locale, native digits, no symbol | $45,231,000.00 | 45231000 | ٤٥٬٢٣١٬٠٠٠٫٠٠ |
| [$-2060401]#,##0Same, integer | $14,131,000 | 14131000 | ١٤٬١٣١٬٠٠٠ |
| [$ر.س-401]#,##0.00Control: a real currency symbol | ر.س45,231,000.00 | correct | ر.س45,231,000.00 |
| 0.0%Control: a code every engine gets right | 62.3% | correct | 62.3% |
Four failures are worth naming individually, because each has a different cause.
The dollar sign. [$-2060401] carries no currency symbol at all. The $ is the delimiter that opens the locale token, and ssf reads a bare tag as a currency, so a Saudi figure comes back with a US dollar sign in front of it. We shipped that defect ourselves before we found it. The fix rewrites the format string before the engine sees it: a locale token that carries no symbol is removed, and a real one such as [$ر.س-401] is preserved as a literal.
The literal B2. LibreOffice does not honour the B2 modifier and prints the two characters as text in front of a Gregorian date, producing B205/01/2025in a cell whose column header reads "Hijri date".
The one-day error. Where LibreOffice does recognise the Hijri request, it rewrites the code into its own [$-401][~hijri] dialect and renders 06/07/1446. Its Islamic calendar is the tabular algorithm, not Umm al-Qura, so it is a day out. Locale environment, profile locale and alternate format spellings were all tried and none moved it.
The silent drop. For the two Arabic-Indic numeric cells, LibreOffice records the format as 1033;, which is the en-US locale and no format code, and prints the raw underlying number. The most dangerous of the four, because nothing on screen suggests a format was ever requested.


Right-to-left is not a font choice
Direction is a sheet property in the file, sheetView rightToLeft, and it changes four separate things. Column order reverses, so column A sits at the right edge. Frozen panes pin to the right rather than the left. Horizontal scroll offsets run negative in the browser, which means every scroll calculation needs its sign flipped. Data bar gradients fill in the other direction. The direction attribute goes on the table and deliberately not on the scrolling container, because normalising the scroll arithmetic in code and flipping the container as well would cancel out. The formula inspector is forced back to left-to-right, since a cell reference is not an Arabic phrase.
Everything above came out of the same run described in the fidelity test, where the Saudi format cells are scored against the specification precisely because the obvious reference gets them wrong.
Related: The spreadsheet fidelity test · What a citation has to point at · How we test our own data room · Pricing
Arabic, Hijri and RTL rendering are part of the viewer on every tier, with no per-page fees. See pricing.