fix: parse fractional seconds in ChronosTime as a fraction of a second
ChronosTime::parseString() passed the fractional-seconds digits straight to (int), so a short fraction such as .5 was read as 5 microseconds instead of 500000 (half a second), diverging from DateTime. Right-pad the fractional digits to microseconds before converting.
This commit is contained in:
1 parent
760a3e72b1
commit
49dbcb8c91
2 files changed
+16
-1
No files matched your search
+3
-1
@@ -122,7 +122,9 @@ class ChronosTime implements Stringable
|
|||||||
$hours = (int)$matches[1];
|
$hours = (int)$matches[1];
|
||||||
$minutes = (int)$matches[2];
|
$minutes = (int)$matches[2];
|
||||||
$seconds = (int)($matches[3] ?? 0);
|
$seconds = (int)($matches[3] ?? 0);
|
||||||
$microseconds = (int)substr($matches[4] ?? '', 0, 6);
|
// The fraction is of a second, so pad on the right to microseconds:
|
||||||
|
// without it ".5" reads as 5us instead of 500000 (half a second).
|
||||||
|
$microseconds = (int)str_pad(substr($matches[4] ?? '', 0, 6), 6, '0', STR_PAD_RIGHT);
|
||||||
|
|
||||||
if ($hours > 24 || $minutes > 59 || $seconds > 59 || $microseconds > 999_999) {
|
if ($hours > 24 || $minutes > 59 || $seconds > 59 || $microseconds > 999_999) {
|
||||||
throw new InvalidArgumentException(sprintf('Time string `%s` contains invalid values.', $time));
|
throw new InvalidArgumentException(sprintf('Time string `%s` contains invalid values.', $time));
|
||||||
|
|||||||
@@ -53,6 +53,19 @@ class ChronosTimeTest extends TestCase
|
|||||||
$this->assertSame('00:59:59.999999', $t->format('H:i:s.u'));
|
$this->assertSame('00:59:59.999999', $t->format('H:i:s.u'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testConstructFromStringWithFractionalSeconds(): void
|
||||||
|
{
|
||||||
|
// The fractional part is a fraction of a second, matching DateTime.
|
||||||
|
$t = new ChronosTime('12:00:00.5');
|
||||||
|
$this->assertSame('12:00:00.500000', $t->format('H:i:s.u'));
|
||||||
|
|
||||||
|
$t = new ChronosTime('12:00:00.05');
|
||||||
|
$this->assertSame('12:00:00.050000', $t->format('H:i:s.u'));
|
||||||
|
|
||||||
|
$t = new ChronosTime('12:00:00.000005');
|
||||||
|
$this->assertSame('12:00:00.000005', $t->format('H:i:s.u'));
|
||||||
|
}
|
||||||
|
|
||||||
public function testConstructFromInstance(): void
|
public function testConstructFromInstance(): void
|
||||||
{
|
{
|
||||||
$t = new ChronosTime(new DateTimeImmutable('23:59:59.999999'));
|
$t = new ChronosTime(new DateTimeImmutable('23:59:59.999999'));
|
||||||
|
|||||||
Reference in new issue
Block a user