Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[4.6] fix: Time::createFromTimestamp() change for PHP 8.4 #9105

Merged
merged 15 commits into from
Aug 20, 2024

Conversation

kenjis
Copy link
Member

@kenjis kenjis commented Aug 6, 2024

Needs #9107

Description
Follow-up #8544

  • Time::createFromTimestamp() (without timezone specified) should return Time with the timezone UTC, because DateTime(Immutable)::createFromTimestamp() in PHP 8.4 returns an instance with the timezone +00:00.
  • update the method signature for PHP 8.4.
  • replaceself with static.

PHP 8.4 introduces new DateTime(Immutable)::createFromTimestamp() method.
https://php.watch/versions/8.4/datetime-createFromTimestamp

bash-3.2$ php -v
PHP 8.4.0-dev (cli) (built: Aug  5 2024 00:57:29) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.4.0-dev, Copyright (c) Zend Technologies
    with Zend OPcache v8.4.0-dev, Copyright (c), by Zend Technologies
bash-3.2$ php -a
Interactive shell

php > $d = DateTimeImmutable::createFromTimeStamp(0);
php > var_dump($d);
object(DateTimeImmutable)#1 (3) {
  ["date"]=>
  string(26) "1970-01-01 00:00:00.000000"
  ["timezone_type"]=>
  int(1)
  ["timezone"]=>
  string(6) "+00:00"
}

Carbon and Chronos have changed the behaviors.

createFromTimestamp UTC by default
Timezone for createFromTimestamp was previously date_default_timezone_get() in Carbon 2.
In Carbon 3, it's now "UTC" so to be consistent with DateTime behavior when doing new DateTime('@123').
https://carbon.nesbot.com/docs/#api-carbon-3

Chronos::createFromTimestamp() handles timezones differently. If $timezone is not explicitly passed then the instance has timezone set to +00:00 unlike earlier where the currently set default timezone was used. This behavior change normalizes behavior with changes in PHP 8.4 which adds a new DateTimeInterface::createFromTimestamp() method.
https://github.com/cakephp/chronos/releases/tag/3.1.0

Checklist:

  • Securely signed commits
  • Component(s) with PHPDoc blocks, only if necessary or adds value
  • Unit testing, with >80% coverage
  • User guide updated
  • Conforms to style guide

@kenjis kenjis added breaking change Pull requests that may break existing functionalities 4.6 labels Aug 6, 2024
@kenjis kenjis force-pushed the fix-Time-createFromTimestamp branch from 4aa7a39 to 3b51c3e Compare August 6, 2024 01:36
@kenjis kenjis changed the title fix: Time::createFromTimestamp() timezone change fix: Time::createFromTimestamp() change Aug 6, 2024
@kenjis kenjis marked this pull request as draft August 6, 2024 01:45
Comment on lines 292 to 298
$timestamp = 1489762800.654321;

// The timezone will be UTC if you don't specify.
$time = Time::createFromTimestamp($timestamp);

// float cannot handle the number precisely.
$this->assertSame('2017-03-17 15:00:00.654300', $time->format('Y-m-d H:i:s.u'));
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought this was due to float, but the following test passes. Why?

        $timestamp = 1489762800.654321;

        $time = \DateTimeImmutable::createFromTimestamp($timestamp);

        $this->assertSame('2017-03-17 15:00:00.654321', $time->format('Y-m-d H:i:s.u'));

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The u format expresses the time in microseconds which is a millionth of a second. So, the expressed time is six decimal digits.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I meant the following test passes. Why 654300 and 654321?

        $timestamp = 1489762800.654321;

        $time1 = Time::createFromTimestamp($timestamp);
        $time2 = \DateTimeImmutable::createFromTimestamp($timestamp);

        $this->assertSame('2017-03-17 15:00:00.654300', $time1->format('Y-m-d H:i:s.u'));
        $this->assertSame('2017-03-17 15:00:00.654321', $time2->format('Y-m-d H:i:s.u'));

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It probably has something to do with the default precision (which is 14 by default).

In the Time::createFromTimestamp method, we use:

$time = new static('@' . $timestamp, 'UTC', $locale);

Which will "cut" the ending and make it: .6543. We can either set ini_set('precision', 16) at the framework level which is not ideal or use sprintf here:

$time = new static(sprintf('@%.6f', $timestamp), 'UTC', $locale);

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sprintf('@%.6f', $timestamp) works. Thank you!

@kenjis kenjis force-pushed the fix-Time-createFromTimestamp branch 2 times, most recently from 3ff50fb to 2b819ac Compare August 7, 2024 02:49
@kenjis kenjis force-pushed the fix-Time-createFromTimestamp branch from 2b819ac to 97148ef Compare August 11, 2024 22:49
@kenjis kenjis changed the title fix: Time::createFromTimestamp() change fix: Time::createFromTimestamp() change for PHP 8.4 Aug 11, 2024
@kenjis kenjis marked this pull request as ready for review August 11, 2024 22:55
@kenjis kenjis mentioned this pull request Aug 11, 2024
15 tasks
@kenjis kenjis merged commit 0a15e7b into codeigniter4:4.6 Aug 20, 2024
42 checks passed
@kenjis kenjis deleted the fix-Time-createFromTimestamp branch August 20, 2024 06:31
@kenjis kenjis changed the title fix: Time::createFromTimestamp() change for PHP 8.4 [4.6] fix: Time::createFromTimestamp() change for PHP 8.4 Aug 21, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
4.6 breaking change Pull requests that may break existing functionalities
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants