Skip to content

Date: the B format character is one beat low at some times and is not zero padded #85124

Open

Description

@sebxt

What happens

format(), date(), gmdate(), dateI18n() and gmdateI18n() in @wordpress/date return a different value from PHP's date() for the B (Swatch Internet Time) format character.

  1. At times that fall exactly on a beat boundary, the result is one beat too low. gmdate( 'B', '2019-06-18T11:00:00Z' ) returns 499. PHP returns 500.
  2. Values below 100 are not padded. gmdate( 'B', '2024-01-01T23:05:00Z' ) returns 3. PHP returns 003. At BMT midnight the result is 0 where PHP returns 000.

The existing unit tests assert 499 for 11:00 UTC, so the wrong value is locked in by the tests.

What should happen

The output should match PHP: a three digit, zero padded number of whole beats since midnight BMT (UTC+1).

Minimal repro

import { gmdate } from '@wordpress/date';

gmdate( 'B', '2019-06-18T11:00:00Z' ); // '499', PHP gives '500'
gmdate( 'B', '2024-01-01T23:05:00Z' ); // '3', PHP gives '003'
gmdate( 'B', '1970-01-01T00:00:00Z' ); // '41', PHP gives '041'

PHP reference:

php -r 'echo gmdate( "B", strtotime( "2019-06-18T11:00:00Z" ) );'   # 500
php -r 'echo gmdate( "B", strtotime( "2024-01-01T23:05:00Z" ) );'   # 003

Comparing gmdate() with PHP 8.3 gmdate() for every supported format character over 307 timestamps, B differed for 41 of them (the only other difference was W, which #81299 already covers).

Root cause

The B formatter in packages/date/src/index.ts divides the seconds since BMT midnight by 86.4. Because 86.4 has no exact binary representation, 43200 / 86.4 is 499.99999999999994, and parseInt truncates it to 499. The number is also returned without padding. PHP divides whole numbers (seconds * 10 / 864) and formats the result with %03d.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions