PHPOffice/PhpSpreadsheet · error · PhpOffice\PhpSpreadsheet\Exception
The Intl extension does not support Accounting Formats witho
Error message
The Intl extension does not support Accounting Formats without ICU 53
What it means
Thrown by the Accounting number-format Wizard when a locale-aware accounting mask is requested but the installed ICU library is older than version 53. Accounting formats rely on NumberFormatter::CURRENCY_ACCOUNTING, which ICU only supports from 53 onwards, so getLocaleFormat() refuses to run rather than emit a wrong mask. It fires only when the intl extension reports an ICU version below 53.0, which is rare on current PHP builds.
Source
Thrown at src/PhpSpreadsheet/Style/NumberFormat/Wizard/Accounting.php:21
namespace PhpOffice\PhpSpreadsheet\Style\NumberFormat\Wizard;
use NumberFormatter;
use PhpOffice\PhpSpreadsheet\Exception;
class Accounting extends CurrencyBase
{
protected ?bool $overrideSpacing = true;
protected ?CurrencyNegative $overrideNegative = CurrencyNegative::parentheses;
/**
* @throws Exception if the Intl extension and ICU version don't support Accounting formats
*/
protected function getLocaleFormat(): string
{
if (self::icuVersion() < 53.0) {
// @codeCoverageIgnoreStart
throw new Exception('The Intl extension does not support Accounting Formats without ICU 53');
// @codeCoverageIgnoreEnd
}
// Scrutinizer does not recognize CURRENCY_ACCOUNTING
$formatter = new Locale($this->fullLocale, NumberFormatter::CURRENCY_ACCOUNTING);
$mask = $formatter->format($this->stripLeadingRLM);
if ($this->decimals === 0) {
$mask = (string) preg_replace('/\.0+/miu', '', $mask);
}
return str_replace('¤', $this->formatCurrencyCode(), $mask);
}
public static function icuVersion(): float
{
[$major, $minor] = explode('.', INTL_ICU_VERSION);
return (float) "{$major}.{$minor}";View on GitHub (pinned to 65b080eef4)
Solutions
- Upgrade PHP/intl so it links ICU >= 53 (verify with `echo INTL_ICU_VERSION;`), usually via current distro or sury/ondrej-php packages
- Build the accounting format without a locale so the wizard uses its built-in mask (pass '' as the locale argument)
- Catch the exception and fall back to a hand-written format code such as '_-"€"* #,##0.00_-;-"€"* #,##0.00_-;_-"€"* "-"??_-;_-@_-'
Example fix
// before
$mask = (new Accounting(2, '€', 'de-DE'))->format();
// after (guard for old ICU)
if (defined('INTL_ICU_VERSION') && version_compare(INTL_ICU_VERSION, '53.0', '>=')) {
$mask = (new Accounting(2, '€', 'de-DE'))->format();
} else {
$mask = '_-"€"* #,##0.00_-;-"€"* #,##0.00_-;_-"€"* "-"??_-;_-@_-';
} Defensive patterns
Strategy: validation
Validate before calling
$icuOk = extension_loaded('intl') && defined('INTL_ICU_VERSION') && version_compare(INTL_ICU_VERSION, '53.0', '>=');
if ($icuOk) {
$mask = (new Accounting(2, '€', 'de-DE'))->format();
} else {
$mask = '_-"€"* #,##0.00_-;-"€"* #,##0.00_-;_-"€"* "-"??_-;_-@_-';
} Type guard
function icuSupportsAccountingFormats(): bool
{
return extension_loaded('intl')
&& defined('INTL_ICU_VERSION')
&& version_compare(INTL_ICU_VERSION, '53.0', '>=');
} Try / catch
try {
$mask = $accountingWizard->format();
} catch (\PhpOffice\PhpSpreadsheet\Exception $e) {
// ICU too old: fall back to a hardcoded accounting format code
$mask = '_-"€"* #,##0.00_-;-"€"* #,##0.00_-;_-"€"* "-"??_-;_-@_-';
} Prevention
- Print INTL_ICU_VERSION in your CI to catch old ICU builds before release
- Pin base images/Docker stages that bundle a current ICU
- Avoid locale-driven wizards unless the deployment environment is known
When it happens
Trigger: Calling (new Accounting(2, '€', 'de-DE'))->format(), or any Accounting wizard with a non-empty locale, on a PHP build whose intl extension links ICU < 53 (checked via INTL_ICU_VERSION).
Common situations: Legacy hosting, old Ubuntu/Debian PHP packages, outdated XAMPP/WAMP bundles, or containers built from very old base images where PHP was upgraded but the ICU library was not.
Related errors
- Unable to read locale data for '{$locale}'
- Invalid locale code '{$locale}'
- Unsupported binary comparison operator
- Cloning the calculation engine is not allowed!
- Unsupported numeric binary operation
AI-assisted analysis of PHPOffice/PhpSpreadsheet@65b080eef4 (2026-08-17).
Data as JSON: /api/errors/6465c5fb5b28fe7a.
Report an issue: GitHub.