VALUE() parses product text like "5V 2.1A - EU Wall Adaptor" as a date

Author: gechuanpanCreated Sep 18, 2026Updated Sep 18, 2026

Which version of PhpSpreadsheet are you using?

Reproduced on 1.21 and against current master (DateValue::fromString() / Format::VALUE()).

What is the expected vs actual behaviour?

Excel:

excel
=VALUE("5V 2.1A - EU Wall Adaptor")  →  #VALUE!
=IFERROR(VALUE("5V 2.1A - EU Wall Adaptor"), 1)  →  1

PhpSpreadsheet:

php
Format::VALUE('5V 2.1A - EU Wall Adaptor');
// actual: 37381.0  (Excel serial for 2002-05-05)
// expected: #VALUE!

This shows up in real workbooks that do VALUE(LEFT(spec, FIND(" pcs", spec & " pcs")-1)) on a product specification. When the spec is not "N pcs ...", Excel falls back through IFERROR(..., 1). PhpSpreadsheet instead treats the spec as a date, so unit price becomes amount / 37381 and quantity becomes qty * 37381.

A nearby description without a decimal point is already rejected:

"5V 1A - EU Wall Adaptor for VC4/..."  →  #VALUE!   (correct)
"5V 2.1A - EU Wall Adaptor"            →  37381     (wrong)

What are the steps to reproduce?

php
use PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\DateValue;
use PhpOffice\PhpSpreadsheet\Calculation\TextData\Format;

var_dump(Format::VALUE('5V 2.1A - EU Wall Adaptor'));
var_dump(DateValue::fromString('5V 2.1A - EU Wall Adaptor'));

DateValue replaces . and - with spaces, then date_parse('5V-2-1A') returns error_count === 0 (year 2002, month 5, day 5). Excel VALUE() does not accept that string.

Suggested fix

Reject strings that still contain leftover letters after stripping English month/weekday names, am/pm, digits, ordinals, and date/time separators, before calling DateValue::fromString() from VALUE(). Real dates such as 2026-09-18, 18 Sep 2026, Sep 18, 2026, and 6:45 PM still parse.

Source: PHPOffice/PhpSpreadsheet