[Web] Some minor fixes and improvements for PHP 8
This commit is contained in:
@@ -7,30 +7,24 @@
|
||||
"time",
|
||||
"DateTime"
|
||||
],
|
||||
"homepage": "http://carbon.nesbot.com",
|
||||
"support": {
|
||||
"issues": "https://github.com/briannesbitt/Carbon/issues",
|
||||
"source": "https://github.com/briannesbitt/Carbon"
|
||||
},
|
||||
"homepage": "https://carbon.nesbot.com",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Brian Nesbitt",
|
||||
"email": "brian@nesbot.com",
|
||||
"homepage": "http://nesbot.com"
|
||||
"homepage": "https://markido.com"
|
||||
},
|
||||
{
|
||||
"name": "kylekatarnls",
|
||||
"homepage": "http://github.com/kylekatarnls"
|
||||
"homepage": "https://github.com/kylekatarnls"
|
||||
}
|
||||
],
|
||||
"prefer-stable": true,
|
||||
"minimum-stability": "dev",
|
||||
"bin": ["bin/carbon"],
|
||||
"require": {
|
||||
"php": "^7.1.8 || ^8.0",
|
||||
"ext-json": "*",
|
||||
"symfony/polyfill-mbstring": "^1.0",
|
||||
"symfony/polyfill-php80": "^1.16",
|
||||
"symfony/translation": "^3.4 || ^4.0 || ^5.0"
|
||||
},
|
||||
"require-dev": {
|
||||
@@ -43,43 +37,14 @@
|
||||
"phpunit/phpunit": "^7.5.20 || ^8.5.14",
|
||||
"squizlabs/php_codesniffer": "^3.4"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Carbon\\": "src/Carbon/"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"files": [
|
||||
"tests/Laravel/ServiceProvider.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Tests\\": "tests/"
|
||||
}
|
||||
},
|
||||
"config": {
|
||||
"process-timeout": 0,
|
||||
"sort-packages": true
|
||||
},
|
||||
"scripts": {
|
||||
"test": [
|
||||
"@phpunit",
|
||||
"@style-check"
|
||||
],
|
||||
"style-check": [
|
||||
"@phpcs",
|
||||
"@phpstan",
|
||||
"@phpmd"
|
||||
],
|
||||
"phpunit": "phpunit --verbose",
|
||||
"phpcs": "php-cs-fixer fix -v --diff --dry-run",
|
||||
"phpstan": "phpstan analyse --configuration phpstan.neon",
|
||||
"phpmd": "phpmd src text /phpmd.xml",
|
||||
"phpdoc": "php phpdoc.php"
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.x-dev",
|
||||
"dev-3.x": "3.x-dev"
|
||||
"dev-3.x": "3.x-dev",
|
||||
"dev-master": "2.x-dev"
|
||||
},
|
||||
"laravel": {
|
||||
"providers": [
|
||||
@@ -91,5 +56,43 @@
|
||||
"extension.neon"
|
||||
]
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Carbon\\": "src/Carbon/"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"Tests\\": "tests/"
|
||||
},
|
||||
"files": [
|
||||
"tests/Laravel/ServiceProvider.php"
|
||||
]
|
||||
},
|
||||
"minimum-stability": "dev",
|
||||
"prefer-stable": true,
|
||||
"bin": [
|
||||
"bin/carbon"
|
||||
],
|
||||
"scripts": {
|
||||
"phpcs": "php-cs-fixer fix -v --diff --dry-run",
|
||||
"phpdoc": "php phpdoc.php",
|
||||
"phpmd": "phpmd src text /phpmd.xml",
|
||||
"phpstan": "phpstan analyse --configuration phpstan.neon",
|
||||
"phpunit": "phpunit --verbose",
|
||||
"style-check": [
|
||||
"@phpcs",
|
||||
"@phpstan",
|
||||
"@phpmd"
|
||||
],
|
||||
"test": [
|
||||
"@phpunit",
|
||||
"@style-check"
|
||||
]
|
||||
},
|
||||
"support": {
|
||||
"issues": "https://github.com/briannesbitt/Carbon/issues",
|
||||
"source": "https://github.com/briannesbitt/Carbon"
|
||||
}
|
||||
}
|
||||
|
@@ -1,154 +0,0 @@
|
||||
# Contributing to Carbon
|
||||
|
||||
## Issue Contributions
|
||||
|
||||
Please report any security issue using [Tidelift security contact](https://tidelift.com/security).
|
||||
Tidelift will coordinate the fix and disclosure.
|
||||
Please don't disclose security bugs publicly until they have been handled by us.
|
||||
|
||||
For any other bug or issue, please click this link and follow the template:
|
||||
[Create new issue](https://github.com/briannesbitt/Carbon/issues/new)
|
||||
|
||||
You may think this template does not apply to your case but please think again. A long description will never be as
|
||||
clear as a code chunk with the output you expect from it (for either bug report or new features).
|
||||
|
||||
## Code Contributions
|
||||
|
||||
### Where to begin
|
||||
|
||||
We use the label **good first issue** to tag issues that could be a good fit for new contributors, see if there are such issues now following this link:
|
||||
|
||||
https://github.com/briannesbitt/Carbon/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22
|
||||
|
||||
Else, check the roadmap to see what we plan to do in next releases:
|
||||
|
||||
https://github.com/briannesbitt/Carbon/issues/1681
|
||||
|
||||
### Develop locally, then submit changes
|
||||
|
||||
Fork the [GitHub project](https://github.com/briannesbitt/Carbon) and download it locally:
|
||||
|
||||
```shell
|
||||
git clone https://github.com/<username>/Carbon.git
|
||||
cd Carbon
|
||||
git remote add upstream https://github.com/briannesbitt/Carbon.git
|
||||
```
|
||||
Replace `<username>` with your GitHub username.
|
||||
|
||||
Then, you can work on the master or create a specific branch for your development:
|
||||
|
||||
```shell
|
||||
git checkout -b my-feature-branch -t origin/master
|
||||
```
|
||||
|
||||
You can now edit the "Carbon" directory contents.
|
||||
|
||||
Before committing, please set your name and your e-mail (use the same e-mail address as in your GitHub account):
|
||||
|
||||
```shell
|
||||
git config --global user.name "Your Name"
|
||||
git config --global user.email "your.email.address@example.com"
|
||||
```
|
||||
|
||||
The ```--global``` argument will apply this setting for all your git repositories, remove it to set only your Carbon
|
||||
fork with those settings.
|
||||
|
||||
Now you can commit your modifications as you usually do with git:
|
||||
|
||||
```shell
|
||||
git add --all
|
||||
git commit -m "The commit message log"
|
||||
```
|
||||
|
||||
If your patch fixes an open issue, please insert ```#``` immediately followed by the issue number:
|
||||
|
||||
```shell
|
||||
git commit -m "#21 Fix this or that"
|
||||
```
|
||||
|
||||
Use git rebase (not git merge) to sync your work from time to time:
|
||||
|
||||
```shell
|
||||
git fetch origin
|
||||
git rebase origin/master
|
||||
```
|
||||
|
||||
Please add some tests for bug fixes and features (so it will ensure next developments will not break your code),
|
||||
then check all is right with phpunit:
|
||||
|
||||
Install PHP if you haven't yet, then install composer:
|
||||
https://getcomposer.org/download/
|
||||
|
||||
Update dependencies:
|
||||
```
|
||||
./composer.phar update
|
||||
```
|
||||
|
||||
Or if you installed composer globally:
|
||||
```
|
||||
composer update
|
||||
```
|
||||
|
||||
Then call phpunit:
|
||||
```
|
||||
./vendor/bin/phpunit
|
||||
```
|
||||
|
||||
Make sure all tests succeed before submitting your pull-request, else we will not be able to merge it.
|
||||
|
||||
Push your work on your remote GitHub fork with:
|
||||
```
|
||||
git push origin my-feature-branch
|
||||
```
|
||||
|
||||
Go to https://github.com/yourusername/Carbon and select your feature branch. Click the 'Pull Request' button and fill
|
||||
out the form.
|
||||
|
||||
We will review it within a few days. And we thank you in advance for your help.
|
||||
|
||||
## Versioning
|
||||
|
||||
### Note about Semantic Versioning and breaking changes
|
||||
|
||||
As a developer, you must understand every change is a breaking change. What is a bug for someone
|
||||
is expected in someone else's workflow. The consequence of a change strongly depends on the usage.
|
||||
[Semantic Versioning](https://semver.org/) relies to public API. In PHP, the public API of a class is its public
|
||||
methods. However, if you extend a class, you can access protected methods, then if you use reflexion, you can
|
||||
access private methods. So anything can become a public API if you force it to be. That doesn't mean we should handle
|
||||
any possible usage, else we would have to publish a major release for each change and it would no longer make sense.
|
||||
|
||||
So before any complain about a breaking change, be warned, we do not guarantee a strict Semantic Versioning as you
|
||||
may expect, we're following a pragmatic interpretation of Semantic Versioning that allows the software to evolve in a
|
||||
reliable way with reasonable maintenance effort.
|
||||
|
||||
Concretely, we consider a change as breaking if it makes fail one of our unit test. We will do our best to avoid
|
||||
incompatibilities with libraries that extends Carbon classes (such as Laravel that is continuously tested thanks to
|
||||
Travis CI, [see the compatibility matrix](https://github.com/kylekatarnls/carbon-laravel/tree/master#carbon-1-dev-version-1next)).
|
||||
|
||||
If you're the owner of a library that strongly depends on Carbon, we recommend you to run unit tests daily requiring
|
||||
`"nesbot/carbon": "dev-master"` (for `^2`) or `"nesbot/carbon": "dev-version-1.next"` (for `^1`), this way you can
|
||||
detect incompatibilities earlier and report it to us before we tag a release. We'll pay attention and try to fix it to
|
||||
make update to next minor releases as soft as possible.
|
||||
|
||||
We reserve the right to publish emergency patches within 24 hours after a release if a tag that does not respect
|
||||
this pattern would have been released despite our vigilance. In this very rare and particular case, we would mark the
|
||||
tag as broken on GitHub and backward compatibility would be based on previous stable tag.
|
||||
|
||||
Last, you must understand that Carbon extends PHP natives classes, that means Carbon can be impacted by any change
|
||||
that occurs in the date/time API of PHP. We watch new PHP versions and handle those changes as quickly as possible
|
||||
when detected, but as PHP does not follow the semantic versioning pattern, it basically means any releases (including
|
||||
patches) can have unexpected consequences on Carbon methods results.
|
||||
|
||||
### Long term support
|
||||
|
||||
To benefit the better support, require Carbon using major version range (`^1` or `^2`). By requiring `1.26.*`,
|
||||
`~1.26.0` or limited range such as `>=1.20 <1.33`, you fall to low priority support (only security and critical issues
|
||||
will be fixed), our prior support goes to next minor releases of each major version. It applies to bug fixes and
|
||||
low-cost features. Other new features will only be added in the last stable release. At the opposite, we recommend you
|
||||
to restrain to a major number, as there is no compatibility guarantee from a major version to the next. It means
|
||||
requiring `>=2`, as it allows any newer version, will probably leads to errors on releasing our next major version.
|
||||
|
||||
Open milestones can be patched if a minor bug is detected while if you're on a closed milestone, we'll more likely
|
||||
ask you to update first to an open one. See currently open milestones:
|
||||
|
||||
https://github.com/briannesbitt/Carbon/milestones
|
46
data/web/inc/lib/vendor/nesbot/carbon/phpmd.xml
vendored
46
data/web/inc/lib/vendor/nesbot/carbon/phpmd.xml
vendored
@@ -1,46 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<ruleset name="Mess detection rules for Carbon"
|
||||
xmlns="http://pmd.sf.net/ruleset/1.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://pmd.sf.net/ruleset/1.0.0
|
||||
http://pmd.sf.net/ruleset_xml_schema.xsd"
|
||||
xsi:noNamespaceSchemaLocation="
|
||||
http://pmd.sf.net/ruleset_xml_schema.xsd">
|
||||
<description>
|
||||
Mess detection rules for Carbon
|
||||
</description>
|
||||
<rule ref="rulesets/codesize.xml">
|
||||
<exclude name="CyclomaticComplexity" />
|
||||
<exclude name="NPathComplexity" />
|
||||
<exclude name="ExcessiveMethodLength" />
|
||||
<exclude name="ExcessiveClassLength" />
|
||||
<exclude name="ExcessivePublicCount" />
|
||||
<exclude name="TooManyMethods" />
|
||||
<exclude name="TooManyPublicMethods" />
|
||||
<exclude name="ExcessiveClassComplexity" />
|
||||
</rule>
|
||||
<rule ref="rulesets/cleancode.xml">
|
||||
<exclude name="BooleanArgumentFlag" />
|
||||
<exclude name="StaticAccess" />
|
||||
<exclude name="IfStatementAssignment" />
|
||||
<exclude name="UndefinedVariable" />
|
||||
<exclude name="ErrorControlOperator" />
|
||||
</rule>
|
||||
<rule ref="rulesets/controversial.xml" />
|
||||
<rule ref="rulesets/design.xml">
|
||||
<exclude name="EvalExpression" />
|
||||
<exclude name="CouplingBetweenObjects" />
|
||||
<exclude name="CountInLoopExpression" />
|
||||
</rule>
|
||||
<rule ref="rulesets/design.xml/CouplingBetweenObjects">
|
||||
<properties>
|
||||
<property name="maximum" value="25" />
|
||||
</properties>
|
||||
</rule>
|
||||
<rule ref="rulesets/naming.xml/ShortVariable">
|
||||
<properties>
|
||||
<property name="exceptions" value="ci,id,to,tz" />
|
||||
</properties>
|
||||
</rule>
|
||||
<rule ref="rulesets/unusedcode.xml" />
|
||||
</ruleset>
|
@@ -8,7 +8,7 @@
|
||||
[](https://github.com/phpstan/phpstan)
|
||||
[](https://tidelift.com/subscription/pkg/packagist-nesbot-carbon?utm_source=packagist-nesbot-carbon&utm_medium=referral&utm_campaign=readme)
|
||||
|
||||
An international PHP extension for DateTime. [http://carbon.nesbot.com](http://carbon.nesbot.com)
|
||||
An international PHP extension for DateTime. [https://carbon.nesbot.com](https://carbon.nesbot.com)
|
||||
|
||||
```php
|
||||
<?php
|
||||
@@ -84,7 +84,7 @@ printf("Now: %s", Carbon::now());
|
||||
|
||||
### Without Composer
|
||||
|
||||
Why are you not using [composer](http://getcomposer.org/)? Download the Carbon [latest release](https://github.com/briannesbitt/Carbon/releases) and put the contents of the ZIP archive into a directory in your project. Then require the file `autoload.php` to get all classes and dependencies loaded on need.
|
||||
Why are you not using [composer](https://getcomposer.org/)? Download the Carbon [latest release](https://github.com/briannesbitt/Carbon/releases) and put the contents of the ZIP archive into a directory in your project. Then require the file `autoload.php` to get all classes and dependencies loaded on need.
|
||||
|
||||
```php
|
||||
<?php
|
||||
@@ -97,7 +97,7 @@ printf("Now: %s", Carbon::now());
|
||||
|
||||
## Docs
|
||||
|
||||
[http://carbon.nesbot.com/docs](http://carbon.nesbot.com/docs)
|
||||
[https://carbon.nesbot.com/docs](https://carbon.nesbot.com/docs)
|
||||
|
||||
## Security contact information
|
||||
|
||||
@@ -122,7 +122,7 @@ This project exists thanks to all the people who contribute.
|
||||
Support this project by becoming a sponsor. Your logo will show up here with a link to your website.
|
||||
|
||||
<a href="https://tidelift.com/subscription/pkg/packagist-nesbot-carbon?utm_source=packagist-nesbot-carbon&utm_medium=referral&utm_campaign=readme" target="_blank"><img src="https://carbon.nesbot.com/tidelift-brand.png" width="256" height="64"></a>
|
||||
<a href="https://onlinecasinohex.ca/?utm_source=opencollective&utm_medium=github&utm_campaign=Carbon" target="_blank"><img src="https://opencollective.com/Carbon/sponsor/0/avatar.svg" width="192" height="64"></a>
|
||||
<a href="https://onlinecasinohex.ca/?utm_source=opencollective&utm_medium=github&utm_campaign=Carbon" target="_blank"><img src="https://images.opencollective.com/hexcasinoca/2da3af2/logo/256.png" width="85" height="64"></a>
|
||||
<a href="https://opencollective.com/Carbon/sponsor/0/website" target="_blank"><img src="https://opencollective.com/Carbon/sponsor/0/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/Carbon/sponsor/1/website" target="_blank"><img src="https://opencollective.com/Carbon/sponsor/1/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/Carbon/sponsor/2/website" target="_blank"><img src="https://opencollective.com/Carbon/sponsor/2/avatar.svg"></a>
|
||||
|
@@ -555,6 +555,11 @@ class CarbonImmutable extends DateTimeImmutable implements CarbonInterface
|
||||
return 145261681241552;
|
||||
}
|
||||
|
||||
// Remove if https://bugs.php.net/bug.php?id=81107 is fixed
|
||||
if (version_compare(PHP_VERSION, '8.1.0-dev', '>=')) {
|
||||
return 1118290769066902787;
|
||||
}
|
||||
|
||||
return PHP_INT_MAX;
|
||||
}
|
||||
|
||||
@@ -567,6 +572,11 @@ class CarbonImmutable extends DateTimeImmutable implements CarbonInterface
|
||||
return -135908816449551;
|
||||
}
|
||||
|
||||
// Remove if https://bugs.php.net/bug.php?id=81107 is fixed
|
||||
if (version_compare(PHP_VERSION, '8.1.0-dev', '>=')) {
|
||||
return -1118290769066898816;
|
||||
}
|
||||
|
||||
return max(PHP_INT_MIN, -9223372036854773760);
|
||||
}
|
||||
}
|
||||
|
@@ -26,6 +26,7 @@ use DateTimeInterface;
|
||||
use DateTimeZone;
|
||||
use JsonSerializable;
|
||||
use ReflectionException;
|
||||
use ReturnTypeWillChange;
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
@@ -721,6 +722,7 @@ interface CarbonInterface extends DateTimeInterface, JsonSerializable
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public static function __set_state($dump);
|
||||
|
||||
/**
|
||||
@@ -755,6 +757,7 @@ interface CarbonInterface extends DateTimeInterface, JsonSerializable
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function add($unit, $value = 1, $overflow = null);
|
||||
|
||||
/**
|
||||
@@ -830,6 +833,16 @@ interface CarbonInterface extends DateTimeInterface, JsonSerializable
|
||||
*/
|
||||
public function average($date = null);
|
||||
|
||||
/**
|
||||
* Clone the current instance if it's mutable.
|
||||
*
|
||||
* This method is convenient to ensure you don't mutate the initial object
|
||||
* but avoid to make a useless copy of it if it's already immutable.
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public function avoidMutation();
|
||||
|
||||
/**
|
||||
* Determines if the instance is between two others.
|
||||
*
|
||||
@@ -1066,6 +1079,7 @@ interface CarbonInterface extends DateTimeInterface, JsonSerializable
|
||||
*
|
||||
* @return static|false
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public static function createFromFormat($format, $time, $tz = null);
|
||||
|
||||
/**
|
||||
@@ -1946,7 +1960,7 @@ interface CarbonInterface extends DateTimeInterface, JsonSerializable
|
||||
|
||||
/**
|
||||
* Format the instance with the current locale. You can set the current
|
||||
* locale using setlocale() http://php.net/setlocale.
|
||||
* locale using setlocale() https://php.net/setlocale.
|
||||
*
|
||||
* @param string $format
|
||||
*
|
||||
@@ -2135,6 +2149,7 @@ interface CarbonInterface extends DateTimeInterface, JsonSerializable
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public static function getLastErrors();
|
||||
|
||||
/**
|
||||
@@ -3007,6 +3022,7 @@ interface CarbonInterface extends DateTimeInterface, JsonSerializable
|
||||
*
|
||||
* @return array|string
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function jsonSerialize();
|
||||
|
||||
/**
|
||||
@@ -3317,6 +3333,7 @@ interface CarbonInterface extends DateTimeInterface, JsonSerializable
|
||||
*
|
||||
* @see https://php.net/manual/en/datetime.modify.php
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function modify($modify);
|
||||
|
||||
/**
|
||||
@@ -3700,6 +3717,7 @@ interface CarbonInterface extends DateTimeInterface, JsonSerializable
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function setDate($year, $month, $day);
|
||||
|
||||
/**
|
||||
@@ -3764,6 +3782,7 @@ interface CarbonInterface extends DateTimeInterface, JsonSerializable
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function setISODate($year, $week, $day = 1);
|
||||
|
||||
/**
|
||||
@@ -3834,6 +3853,7 @@ interface CarbonInterface extends DateTimeInterface, JsonSerializable
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function setTime($hour, $minute, $second = 0, $microseconds = 0);
|
||||
|
||||
/**
|
||||
@@ -3863,6 +3883,7 @@ interface CarbonInterface extends DateTimeInterface, JsonSerializable
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function setTimestamp($unixTimestamp);
|
||||
|
||||
/**
|
||||
@@ -3872,6 +3893,7 @@ interface CarbonInterface extends DateTimeInterface, JsonSerializable
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function setTimezone($value);
|
||||
|
||||
/**
|
||||
@@ -4213,6 +4235,7 @@ interface CarbonInterface extends DateTimeInterface, JsonSerializable
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function sub($unit, $value = 1, $overflow = null);
|
||||
|
||||
public function subRealUnit($unit, $value = 1);
|
||||
@@ -4751,7 +4774,7 @@ interface CarbonInterface extends DateTimeInterface, JsonSerializable
|
||||
*
|
||||
* @param string $key
|
||||
* @param array $parameters
|
||||
* @param null $number
|
||||
* @param string|int|float|null $number
|
||||
* @param \Symfony\Component\Translation\TranslatorInterface $translator
|
||||
*
|
||||
* @return string
|
||||
@@ -4808,7 +4831,7 @@ interface CarbonInterface extends DateTimeInterface, JsonSerializable
|
||||
public static function translateWith(\Symfony\Component\Translation\TranslatorInterface $translator, string $key, array $parameters = [], $number = null): string;
|
||||
|
||||
/**
|
||||
* Format as ->format() do (using date replacements patterns from http://php.net/manual/fr/function.date.php)
|
||||
* Format as ->format() do (using date replacements patterns from https://php.net/manual/en/function.date.php)
|
||||
* but translate words whenever possible (months, day names, etc.) using the current locale.
|
||||
*
|
||||
* @param string $format
|
||||
@@ -4991,6 +5014,8 @@ interface CarbonInterface extends DateTimeInterface, JsonSerializable
|
||||
*
|
||||
* @param Closure|static|string|false|null $testNow real or mock Carbon instance
|
||||
* @param Closure|null $callback
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public static function withTestNow($testNow = null, $callback = null);
|
||||
|
||||
|
@@ -353,7 +353,7 @@ class CarbonInterval extends DateInterval implements CarbonConverterInterface
|
||||
|
||||
$spec = $years;
|
||||
|
||||
if (!\is_string($spec) || \floatval($years) || preg_match('/^[0-9.]/', $years)) {
|
||||
if (!\is_string($spec) || (float) $years || preg_match('/^[0-9.]/', $years)) {
|
||||
$spec = static::PERIOD_PREFIX;
|
||||
|
||||
$spec .= $years > 0 ? $years.static::PERIOD_YEARS : '';
|
||||
@@ -380,7 +380,7 @@ class CarbonInterval extends DateInterval implements CarbonConverterInterface
|
||||
|
||||
parent::__construct($spec);
|
||||
|
||||
if (!\is_null($microseconds)) {
|
||||
if ($microseconds !== null) {
|
||||
$this->f = $microseconds / Carbon::MICROSECONDS_PER_SECOND;
|
||||
}
|
||||
}
|
||||
@@ -536,7 +536,7 @@ class CarbonInterval extends DateInterval implements CarbonConverterInterface
|
||||
}
|
||||
|
||||
$interval = mb_substr($interval, mb_strlen($match[0]));
|
||||
$instance->$unit += \intval($match[0]);
|
||||
$instance->$unit += (int) ($match[0]);
|
||||
|
||||
continue;
|
||||
}
|
||||
@@ -546,7 +546,7 @@ class CarbonInterval extends DateInterval implements CarbonConverterInterface
|
||||
"'$expected'",
|
||||
$nextCharacter,
|
||||
'Allowed substitutes for interval formats are '.implode(', ', array_keys(static::$formats))."\n".
|
||||
'See https://www.php.net/manual/en/function.date.php for their meaning'
|
||||
'See https://php.net/manual/en/function.date.php for their meaning'
|
||||
);
|
||||
}
|
||||
|
||||
@@ -679,8 +679,8 @@ class CarbonInterval extends DateInterval implements CarbonConverterInterface
|
||||
preg_match_all($pattern, $intervalDefinition, $parts, PREG_SET_ORDER);
|
||||
|
||||
while ([$part, $value, $unit] = array_shift($parts)) {
|
||||
$intValue = \intval($value);
|
||||
$fraction = \floatval($value) - $intValue;
|
||||
$intValue = (int) $value;
|
||||
$fraction = (float) $value - $intValue;
|
||||
|
||||
// Fix calculation precision
|
||||
switch (round($fraction, 6)) {
|
||||
@@ -964,7 +964,7 @@ class CarbonInterval extends DateInterval implements CarbonConverterInterface
|
||||
*
|
||||
* @return static
|
||||
*
|
||||
* @link http://php.net/manual/en/dateinterval.createfromdatestring.php
|
||||
* @link https://php.net/manual/en/dateinterval.createfromdatestring.php
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public static function createFromDateString($time)
|
||||
@@ -996,7 +996,7 @@ class CarbonInterval extends DateInterval implements CarbonConverterInterface
|
||||
*/
|
||||
public function get($name)
|
||||
{
|
||||
if (substr($name, 0, 5) === 'total') {
|
||||
if (str_starts_with($name, 'total')) {
|
||||
return $this->total(substr($name, 5));
|
||||
}
|
||||
|
||||
@@ -1360,7 +1360,7 @@ class CarbonInterval extends DateInterval implements CarbonConverterInterface
|
||||
$minimumUnit = 's';
|
||||
extract($this->getForHumansInitialVariables($syntax, $short));
|
||||
|
||||
if (\is_null($syntax)) {
|
||||
if ($syntax === null) {
|
||||
$syntax = CarbonInterface::DIFF_ABSOLUTE;
|
||||
}
|
||||
|
||||
@@ -1368,7 +1368,7 @@ class CarbonInterval extends DateInterval implements CarbonConverterInterface
|
||||
$parts = INF;
|
||||
}
|
||||
|
||||
if (\is_null($options)) {
|
||||
if ($options === null) {
|
||||
$options = static::getHumanDiffOptions();
|
||||
}
|
||||
|
||||
@@ -1860,7 +1860,7 @@ class CarbonInterval extends DateInterval implements CarbonConverterInterface
|
||||
[$value, $unit] = [$unit, $value];
|
||||
}
|
||||
|
||||
return $this->add($unit, -\floatval($value));
|
||||
return $this->add($unit, -(float) $value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2104,7 +2104,7 @@ class CarbonInterval extends DateInterval implements CarbonConverterInterface
|
||||
public static function compareDateIntervals(DateInterval $first, DateInterval $second)
|
||||
{
|
||||
$current = Carbon::now();
|
||||
$passed = $current->copy()->add($second);
|
||||
$passed = $current->avoidMutation()->add($second);
|
||||
$current->add($first);
|
||||
|
||||
if ($current < $passed) {
|
||||
@@ -2242,12 +2242,12 @@ class CarbonInterval extends DateInterval implements CarbonConverterInterface
|
||||
'years' => $this->years,
|
||||
'months' => $this->months,
|
||||
'weeks' => (int) ($this->d / $daysPerWeek),
|
||||
'dayz' => (int) ($this->d % $daysPerWeek),
|
||||
'dayz' => $this->d % $daysPerWeek,
|
||||
'hours' => $this->hours,
|
||||
'minutes' => $this->minutes,
|
||||
'seconds' => $this->seconds,
|
||||
'milliseconds' => (int) ($this->microseconds / Carbon::MICROSECONDS_PER_MILLISECOND),
|
||||
'microseconds' => (int) ($this->microseconds % Carbon::MICROSECONDS_PER_MILLISECOND),
|
||||
'microseconds' => $this->microseconds % Carbon::MICROSECONDS_PER_MILLISECOND,
|
||||
];
|
||||
|
||||
if (isset($factors['dayz']) && $factors['dayz'][0] !== 'weeks') {
|
||||
|
@@ -32,6 +32,7 @@ use InvalidArgumentException;
|
||||
use Iterator;
|
||||
use JsonSerializable;
|
||||
use ReflectionException;
|
||||
use ReturnTypeWillChange;
|
||||
use RuntimeException;
|
||||
|
||||
/**
|
||||
@@ -875,7 +876,7 @@ class CarbonPeriod implements Iterator, Countable, JsonSerializable
|
||||
*/
|
||||
public function setOptions($options)
|
||||
{
|
||||
if (!\is_int($options) && !\is_null($options)) {
|
||||
if (!\is_int($options) && $options !== null) {
|
||||
throw new InvalidPeriodParameterException('Invalid options.');
|
||||
}
|
||||
|
||||
@@ -962,7 +963,7 @@ class CarbonPeriod implements Iterator, Countable, JsonSerializable
|
||||
*/
|
||||
public function getStartDate(string $rounding = null)
|
||||
{
|
||||
$date = $this->startDate->copy();
|
||||
$date = $this->startDate->avoidMutation();
|
||||
|
||||
return $rounding ? $date->round($this->getDateInterval(), $rounding) : $date;
|
||||
}
|
||||
@@ -980,7 +981,7 @@ class CarbonPeriod implements Iterator, Countable, JsonSerializable
|
||||
return null;
|
||||
}
|
||||
|
||||
$date = $this->endDate->copy();
|
||||
$date = $this->endDate->avoidMutation();
|
||||
|
||||
return $rounding ? $date->round($this->getDateInterval(), $rounding) : $date;
|
||||
}
|
||||
@@ -1220,7 +1221,7 @@ class CarbonPeriod implements Iterator, Countable, JsonSerializable
|
||||
*/
|
||||
public function setRecurrences($recurrences)
|
||||
{
|
||||
if (!is_numeric($recurrences) && !\is_null($recurrences) || $recurrences < 0) {
|
||||
if (!is_numeric($recurrences) && $recurrences !== null || $recurrences < 0) {
|
||||
throw new InvalidPeriodParameterException('Invalid number of recurrences.');
|
||||
}
|
||||
|
||||
@@ -1276,7 +1277,7 @@ class CarbonPeriod implements Iterator, Countable, JsonSerializable
|
||||
*/
|
||||
public function setEndDate($date, $inclusive = null)
|
||||
{
|
||||
if (!\is_null($date) && !$date = ([$this->dateClass, 'make'])($date)) {
|
||||
if ($date !== null && !$date = ([$this->dateClass, 'make'])($date)) {
|
||||
throw new InvalidPeriodDateException('Invalid end date.');
|
||||
}
|
||||
|
||||
@@ -1523,7 +1524,7 @@ class CarbonPeriod implements Iterator, Countable, JsonSerializable
|
||||
{
|
||||
$state = [
|
||||
$this->key,
|
||||
$this->current ? $this->current->copy() : null,
|
||||
$this->current ? $this->current->avoidMutation() : null,
|
||||
$this->validationResult,
|
||||
];
|
||||
|
||||
@@ -1722,7 +1723,7 @@ class CarbonPeriod implements Iterator, Countable, JsonSerializable
|
||||
$date = $this->getEndFromRecurrences() ?? $this->iterateUntilEnd();
|
||||
|
||||
if ($date && $rounding) {
|
||||
$date = $date->copy()->round($this->getDateInterval(), $rounding);
|
||||
$date = $date->avoidMutation()->round($this->getDateInterval(), $rounding);
|
||||
}
|
||||
|
||||
return $date;
|
||||
@@ -1743,13 +1744,13 @@ class CarbonPeriod implements Iterator, Countable, JsonSerializable
|
||||
if ($this->recurrences === INF) {
|
||||
$start = $this->getStartDate();
|
||||
|
||||
return $start < $start->copy()->add($this->getDateInterval())
|
||||
return $start < $start->avoidMutation()->add($this->getDateInterval())
|
||||
? CarbonImmutable::endOfTime()
|
||||
: CarbonImmutable::startOfTime();
|
||||
}
|
||||
|
||||
if ($this->filters === [[static::RECURRENCES_FILTER, null]]) {
|
||||
return $this->getStartDate()->copy()->add(
|
||||
return $this->getStartDate()->avoidMutation()->add(
|
||||
$this->getDateInterval()->times(
|
||||
$this->recurrences - ($this->isStartExcluded() ? 0 : 1)
|
||||
)
|
||||
@@ -1795,13 +1796,8 @@ class CarbonPeriod implements Iterator, Countable, JsonSerializable
|
||||
$range = static::create($range);
|
||||
}
|
||||
|
||||
$thisDates = [$this->getStartDate(), $this->calculateEnd()];
|
||||
sort($thisDates);
|
||||
[$start, $end] = $thisDates;
|
||||
|
||||
$rangeDates = [$range->getStartDate(), $range->calculateEnd()];
|
||||
sort($rangeDates);
|
||||
[$rangeStart, $rangeEnd] = $rangeDates;
|
||||
[$start, $end] = $this->orderCouple($this->getStartDate(), $this->calculateEnd());
|
||||
[$rangeStart, $rangeEnd] = $this->orderCouple($range->getStartDate(), $range->calculateEnd());
|
||||
|
||||
return $end > $rangeStart && $rangeEnd > $start;
|
||||
}
|
||||
@@ -2168,6 +2164,7 @@ class CarbonPeriod implements Iterator, Countable, JsonSerializable
|
||||
*
|
||||
* @return CarbonInterface[]
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function jsonSerialize()
|
||||
{
|
||||
return $this->toArray();
|
||||
@@ -2283,7 +2280,7 @@ class CarbonPeriod implements Iterator, Countable, JsonSerializable
|
||||
*/
|
||||
protected function isCarbonPredicateMethod($callable)
|
||||
{
|
||||
return \is_string($callable) && substr($callable, 0, 2) === 'is' &&
|
||||
return \is_string($callable) && str_starts_with($callable, 'is') &&
|
||||
(method_exists($this->dateClass, $callable) || ([$this->dateClass, 'hasMacro'])($callable));
|
||||
}
|
||||
|
||||
@@ -2384,7 +2381,7 @@ class CarbonPeriod implements Iterator, Countable, JsonSerializable
|
||||
foreach ($this->filters as $tuple) {
|
||||
$result = \call_user_func(
|
||||
$tuple[0],
|
||||
$current->copy(),
|
||||
$current->avoidMutation(),
|
||||
$this->key,
|
||||
$this
|
||||
);
|
||||
@@ -2493,4 +2490,9 @@ class CarbonPeriod implements Iterator, Countable, JsonSerializable
|
||||
? static::instance($period)
|
||||
: static::create($period, ...$arguments);
|
||||
}
|
||||
|
||||
private function orderCouple($first, $second): array
|
||||
{
|
||||
return $first > $second ? [$second, $first] : [$first, $second];
|
||||
}
|
||||
}
|
||||
|
@@ -33,7 +33,7 @@ class CarbonTimeZone extends DateTimeZone
|
||||
|
||||
protected static function getDateTimeZoneNameFromMixed($timezone)
|
||||
{
|
||||
if (\is_null($timezone)) {
|
||||
if ($timezone === null) {
|
||||
return date_default_timezone_get();
|
||||
}
|
||||
|
||||
|
@@ -37,7 +37,7 @@ trait CarbonTypeConverter
|
||||
return $type;
|
||||
}
|
||||
|
||||
if (strpos($type, '(') !== false) {
|
||||
if (str_contains($type, '(')) {
|
||||
return preg_replace('/\(\d+\)/', "($precision)", $type);
|
||||
}
|
||||
|
||||
@@ -95,7 +95,7 @@ trait CarbonTypeConverter
|
||||
return $value;
|
||||
}
|
||||
|
||||
if ($value instanceof DateTimeInterface || $value instanceof CarbonInterface) {
|
||||
if ($value instanceof DateTimeInterface) {
|
||||
return $value->format('Y-m-d H:i:s.u');
|
||||
}
|
||||
|
||||
|
@@ -215,7 +215,7 @@ use ReflectionMethod;
|
||||
* You should rather use the ->settings() method.
|
||||
* Or you can use method variants: addYearsWithOverflow/addYearsNoOverflow, same variants
|
||||
* are available for quarters, years, decade, centuries, millennia (singular and plural forms).
|
||||
* @method Carbon withTestNow($testNow = null, $callback = null) Temporarily sets a static date to be used within the callback.
|
||||
* @method mixed withTestNow($testNow = null, $callback = null) Temporarily sets a static date to be used within the callback.
|
||||
* Using setTestNow to set the date, executing the callback, then
|
||||
* clearing the test instance.
|
||||
* /!\ Use this method for unit tests only.
|
||||
@@ -229,7 +229,7 @@ class Factory
|
||||
|
||||
protected $settings = [];
|
||||
|
||||
public function __construct(array $settings = [], string $className = null)
|
||||
public function __construct(array $settings = [], ?string $className = null)
|
||||
{
|
||||
if ($className) {
|
||||
$this->className = $className;
|
||||
|
@@ -214,7 +214,7 @@ use Closure;
|
||||
* You should rather use the ->settings() method.
|
||||
* Or you can use method variants: addYearsWithOverflow/addYearsNoOverflow, same variants
|
||||
* are available for quarters, years, decade, centuries, millennia (singular and plural forms).
|
||||
* @method CarbonImmutable withTestNow($testNow = null, $callback = null) Temporarily sets a static date to be used within the callback.
|
||||
* @method mixed withTestNow($testNow = null, $callback = null) Temporarily sets a static date to be used within the callback.
|
||||
* Using setTestNow to set the date, executing the callback, then
|
||||
* clearing the test instance.
|
||||
* /!\ Use this method for unit tests only.
|
||||
|
@@ -11,7 +11,7 @@
|
||||
// @codeCoverageIgnoreStart
|
||||
if (class_exists('Symfony\\Component\\Translation\\PluralizationRules')) {
|
||||
\Symfony\Component\Translation\PluralizationRules::set(function ($number) {
|
||||
return ((1 == $number % 10) && (11 != $number % 100)) ? 0 : ((($number % 10 >= 2) && ($number % 10 <= 4) && (($number % 100 < 10) || ($number % 100 >= 20))) ? 1 : 2);
|
||||
return (($number % 10 == 1) && ($number % 100 != 11)) ? 0 : ((($number % 10 >= 2) && ($number % 10 <= 4) && (($number % 100 < 10) || ($number % 100 >= 20))) ? 1 : 2);
|
||||
}, 'be');
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
@@ -11,7 +11,7 @@
|
||||
|
||||
/*
|
||||
* Authors:
|
||||
* - Ankur Group, http://www.ankurbangla.org, http://www.bengalinux.org Taneem Ahmed, Jamil Ahmed taneem@bengalinux.org, jamil@bengalinux.org
|
||||
* - Ankur Group, Taneem Ahmed, Jamil Ahmed
|
||||
*/
|
||||
return array_replace_recursive(require __DIR__.'/bn.php', [
|
||||
'formats' => [
|
||||
|
@@ -41,7 +41,7 @@ return [
|
||||
's' => ':count seg.',
|
||||
'ago' => 'hai :time',
|
||||
'from_now' => function ($time) {
|
||||
if (substr($time, 0, 2) === 'un') {
|
||||
if (str_starts_with($time, 'un')) {
|
||||
return "n$time";
|
||||
}
|
||||
|
||||
|
@@ -169,8 +169,8 @@ return [
|
||||
|
||||
return $number.'-ე';
|
||||
},
|
||||
'months' => ['იანვარს', 'თებერვალს', 'მარტს', 'აპრილის', 'მაისს', 'ივნისს', 'ივლისს', 'აგვისტს', 'სექტემბერს', 'ოქტომბერს', 'ნოემბერს', 'დეკემბერს'],
|
||||
'months_standalone' => ['იანვარი', 'თებერვალი', 'მარტი', 'აპრილი', 'მაისი', 'ივნისი', 'ივლისი', 'აგვისტო', 'სექტემბერი', 'ოქტომბერი', 'ნოემბერი', 'დეკემბერი'],
|
||||
'months' => ['იანვარი', 'თებერვალი', 'მარტი', 'აპრილი', 'მაისი', 'ივნისი', 'ივლისი', 'აგვისტო', 'სექტემბერი', 'ოქტომბერი', 'ნოემბერი', 'დეკემბერი'],
|
||||
'months_standalone' => ['იანვარს', 'თებერვალს', 'მარტს', 'აპრილს', 'მაისს', 'ივნისს', 'ივლისს', 'აგვისტოს', 'სექტემბერს', 'ოქტომბერს', 'ნოემბერს', 'დეკემბერს'],
|
||||
'months_short' => ['იან', 'თებ', 'მარ', 'აპრ', 'მაი', 'ივნ', 'ივლ', 'აგვ', 'სექ', 'ოქტ', 'ნოე', 'დეკ'],
|
||||
'months_regexp' => '/(D[oD]?(\[[^\[\]]*\]|\s)+MMMM?|L{2,4}|l{2,4})/',
|
||||
'weekdays' => ['კვირას', 'ორშაბათს', 'სამშაბათს', 'ოთხშაბათს', 'ხუთშაბათს', 'პარასკევს', 'შაბათს'],
|
||||
|
@@ -69,7 +69,7 @@ return [
|
||||
'diff_after_tomorrow' => 'overmorgen',
|
||||
'diff_before_yesterday' => 'eergisteren',
|
||||
'period_recurrences' => ':count keer',
|
||||
'period_interval' => function ($interval) {
|
||||
'period_interval' => function (string $interval = '') {
|
||||
/** @var string $output */
|
||||
$output = preg_replace('/^(een|één|1)\s+/', '', $interval);
|
||||
|
||||
|
@@ -82,7 +82,7 @@ return [
|
||||
'weekdays' => ['dimenge', 'diluns', 'dimars', 'dimècres', 'dijòus', 'divendres', 'dissabte'],
|
||||
'weekdays_short' => ['dg', 'dl', 'dm', 'dc', 'dj', 'dv', 'ds'],
|
||||
'weekdays_min' => ['dg', 'dl', 'dm', 'dc', 'dj', 'dv', 'ds'],
|
||||
'ordinal' => function ($number, $period) {
|
||||
'ordinal' => function ($number, string $period = '') {
|
||||
$ordinal = [1 => 'èr', 2 => 'nd'][(int) $number] ?? 'en';
|
||||
|
||||
// feminine for year, week, hour, minute, second
|
||||
|
@@ -29,7 +29,7 @@
|
||||
return [
|
||||
'year' => ':count rok|:count lata|:count lat',
|
||||
'a_year' => 'rok|:count lata|:count lat',
|
||||
'y' => ':count r|:count l',
|
||||
'y' => ':count r|:count l|:count l',
|
||||
'month' => ':count miesiąc|:count miesiące|:count miesięcy',
|
||||
'a_month' => 'miesiąc|:count miesiące|:count miesięcy',
|
||||
'm' => ':count mies.',
|
||||
|
@@ -11,7 +11,7 @@
|
||||
// @codeCoverageIgnoreStart
|
||||
if (class_exists('Symfony\\Component\\Translation\\PluralizationRules')) {
|
||||
\Symfony\Component\Translation\PluralizationRules::set(function ($number) {
|
||||
return ((1 == $number % 10) && (11 != $number % 100)) ? 0 : ((($number % 10 >= 2) && ($number % 10 <= 4) && (($number % 100 < 10) || ($number % 100 >= 20))) ? 1 : 2);
|
||||
return (($number % 10 == 1) && ($number % 100 != 11)) ? 0 : ((($number % 10 >= 2) && ($number % 10 <= 4) && (($number % 100 < 10) || ($number % 100 >= 20))) ? 1 : 2);
|
||||
}, 'sh');
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
@@ -11,7 +11,7 @@
|
||||
|
||||
/*
|
||||
* Authors:
|
||||
* - ubuntu Myanmar LoCo Team http://www.ubuntu-mm.net Bone Pyae Sone bone.burma@mail.com
|
||||
* - ubuntu Myanmar LoCo Team https://ubuntu-mm.net Bone Pyae Sone bone.burma@mail.com
|
||||
*/
|
||||
return array_replace_recursive(require __DIR__.'/en.php', [
|
||||
'formats' => [
|
||||
|
@@ -11,6 +11,7 @@
|
||||
namespace Carbon;
|
||||
|
||||
use JsonSerializable;
|
||||
use ReturnTypeWillChange;
|
||||
|
||||
class Language implements JsonSerializable
|
||||
{
|
||||
@@ -332,6 +333,7 @@ class Language implements JsonSerializable
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function jsonSerialize()
|
||||
{
|
||||
return $this->getIsoDescription();
|
||||
|
@@ -622,7 +622,7 @@ trait Comparison
|
||||
|
||||
if (!isset($units[$unit])) {
|
||||
if (isset($this->$unit)) {
|
||||
return $this->$unit === $this->resolveCarbon($date)->$unit;
|
||||
return $this->resolveCarbon($date)->$unit === $this->$unit;
|
||||
}
|
||||
|
||||
if ($this->localStrictModeEnabled ?? static::isStrictModeEnabled()) {
|
||||
@@ -949,7 +949,7 @@ trait Comparison
|
||||
$tester = trim($tester);
|
||||
|
||||
if (preg_match('/^\d+$/', $tester)) {
|
||||
return $this->year === \intval($tester);
|
||||
return $this->year === (int) $tester;
|
||||
}
|
||||
|
||||
if (preg_match('/^\d{3,}-\d{1,2}$/', $tester)) {
|
||||
@@ -964,9 +964,9 @@ trait Comparison
|
||||
|
||||
/* @var CarbonInterface $max */
|
||||
$median = static::parse('5555-06-15 12:30:30.555555')->modify($modifier);
|
||||
$current = $this->copy();
|
||||
$current = $this->avoidMutation();
|
||||
/* @var CarbonInterface $other */
|
||||
$other = $this->copy()->modify($modifier);
|
||||
$other = $this->avoidMutation()->modify($modifier);
|
||||
|
||||
if ($current->eq($other)) {
|
||||
return true;
|
||||
@@ -1001,7 +1001,7 @@ trait Comparison
|
||||
];
|
||||
|
||||
foreach ($units as $unit => [$minimum, $startUnit]) {
|
||||
if ($median->$unit === $minimum) {
|
||||
if ($minimum === $median->$unit) {
|
||||
$current = $current->startOf($startUnit);
|
||||
|
||||
break;
|
||||
|
@@ -38,7 +38,7 @@ trait Converter
|
||||
*
|
||||
* @var string|Closure|null
|
||||
*/
|
||||
protected static $toStringFormat = null;
|
||||
protected static $toStringFormat;
|
||||
|
||||
/**
|
||||
* Reset the format used to the default when type juggling a Carbon instance to a string
|
||||
@@ -324,7 +324,9 @@ trait Converter
|
||||
*/
|
||||
public function toIso8601ZuluString($unitPrecision = 'second')
|
||||
{
|
||||
return $this->copy()->utc()->rawFormat('Y-m-d\T'.static::getTimeFormatByPrecision($unitPrecision).'\Z');
|
||||
return $this->avoidMutation()
|
||||
->utc()
|
||||
->rawFormat('Y-m-d\T'.static::getTimeFormatByPrecision($unitPrecision).'\Z');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -452,7 +454,7 @@ trait Converter
|
||||
*/
|
||||
public function toRfc7231String()
|
||||
{
|
||||
return $this->copy()
|
||||
return $this->avoidMutation()
|
||||
->setTimezone('GMT')
|
||||
->rawFormat(\defined('static::RFC7231_FORMAT') ? static::RFC7231_FORMAT : CarbonInterface::RFC7231_FORMAT);
|
||||
}
|
||||
@@ -512,7 +514,7 @@ trait Converter
|
||||
*/
|
||||
public function toString()
|
||||
{
|
||||
return $this->copy()->locale('en')->isoFormat('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ');
|
||||
return $this->avoidMutation()->locale('en')->isoFormat('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -537,7 +539,7 @@ trait Converter
|
||||
|
||||
$yearFormat = $this->year < 0 || $this->year > 9999 ? 'YYYYYY' : 'YYYY';
|
||||
$tzFormat = $keepOffset ? 'Z' : '[Z]';
|
||||
$date = $keepOffset ? $this : $this->copy()->utc();
|
||||
$date = $keepOffset ? $this : $this->avoidMutation()->utc();
|
||||
|
||||
return $date->isoFormat("$yearFormat-MM-DD[T]HH:mm:ss.SSSSSS$tzFormat");
|
||||
}
|
||||
|
@@ -77,7 +77,7 @@ trait Creator
|
||||
}
|
||||
|
||||
// Work-around for PHP bug https://bugs.php.net/bug.php?id=67127
|
||||
if (strpos((string) .1, '.') === false) {
|
||||
if (!str_contains((string) .1, '.')) {
|
||||
$locale = setlocale(LC_NUMERIC, '0');
|
||||
setlocale(LC_NUMERIC, 'C');
|
||||
}
|
||||
@@ -592,7 +592,7 @@ trait Creator
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
||||
if ($originalTz === null) {
|
||||
return parent::createFromFormat($format, "$time");
|
||||
return parent::createFromFormat($format, (string) $time);
|
||||
}
|
||||
|
||||
$tz = \is_int($originalTz)
|
||||
@@ -605,7 +605,7 @@ trait Creator
|
||||
return false;
|
||||
}
|
||||
|
||||
return parent::createFromFormat($format, "$time", $tz);
|
||||
return parent::createFromFormat($format, (string) $time, $tz);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -27,6 +27,7 @@ use Closure;
|
||||
use DateInterval;
|
||||
use DatePeriod;
|
||||
use DateTime;
|
||||
use DateTimeImmutable;
|
||||
use DateTimeInterface;
|
||||
use DateTimeZone;
|
||||
use InvalidArgumentException;
|
||||
@@ -630,7 +631,7 @@ trait Date
|
||||
*
|
||||
* @return CarbonTimeZone
|
||||
*
|
||||
* @link http://php.net/manual/en/datetime.gettimezone.php
|
||||
* @link https://php.net/manual/en/datetime.gettimezone.php
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function getTimezone()
|
||||
@@ -683,6 +684,23 @@ trait Date
|
||||
return clone $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clone the current instance if it's mutable.
|
||||
*
|
||||
* This method is convenient to ensure you don't mutate the initial object
|
||||
* but avoid to make a useless copy of it if it's already immutable.
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public function avoidMutation(): self
|
||||
{
|
||||
if ($this instanceof DateTimeImmutable) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
return clone $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a present instance in the same timezone.
|
||||
*
|
||||
@@ -774,7 +792,7 @@ trait Date
|
||||
public function carbonize($date = null)
|
||||
{
|
||||
if ($date instanceof DateInterval) {
|
||||
return $this->copy()->add($date);
|
||||
return $this->avoidMutation()->add($date);
|
||||
}
|
||||
|
||||
if ($date instanceof DatePeriod || $date instanceof CarbonPeriod) {
|
||||
@@ -872,7 +890,7 @@ trait Date
|
||||
switch (true) {
|
||||
case isset($formats[$name]):
|
||||
$format = $formats[$name];
|
||||
$method = substr($format, 0, 1) === '%' ? 'formatLocalized' : 'rawFormat';
|
||||
$method = str_starts_with($format, '%') ? 'formatLocalized' : 'rawFormat';
|
||||
$value = $this->$method($format);
|
||||
|
||||
return is_numeric($value) ? (int) $value : $value;
|
||||
@@ -927,11 +945,11 @@ trait Date
|
||||
|
||||
// @property-read int 51 through 53
|
||||
case $name === 'weeksInYear':
|
||||
return (int) $this->weeksInYear();
|
||||
return $this->weeksInYear();
|
||||
|
||||
// @property-read int 51 through 53
|
||||
case $name === 'isoWeeksInYear':
|
||||
return (int) $this->isoWeeksInYear();
|
||||
return $this->isoWeeksInYear();
|
||||
|
||||
// @property-read int 1 through 5
|
||||
case $name === 'weekOfMonth':
|
||||
@@ -939,7 +957,7 @@ trait Date
|
||||
|
||||
// @property-read int 1 through 5
|
||||
case $name === 'weekNumberInMonth':
|
||||
return (int) ceil(($this->day + $this->copy()->startOfMonth()->dayOfWeekIso - 1) / static::DAYS_PER_WEEK);
|
||||
return (int) ceil(($this->day + $this->avoidMutation()->startOfMonth()->dayOfWeekIso - 1) / static::DAYS_PER_WEEK);
|
||||
|
||||
// @property-read int 0 through 6
|
||||
case $name === 'firstWeekDay':
|
||||
@@ -951,7 +969,7 @@ trait Date
|
||||
|
||||
// @property int 1 through 366
|
||||
case $name === 'dayOfYear':
|
||||
return 1 + \intval($this->rawFormat('z'));
|
||||
return 1 + (int) ($this->rawFormat('z'));
|
||||
|
||||
// @property-read int 365 or 366
|
||||
case $name === 'daysInYear':
|
||||
@@ -1013,7 +1031,7 @@ trait Date
|
||||
|
||||
// @property-read bool checks if the timezone is local, true if local, false otherwise
|
||||
case $name === 'local':
|
||||
return $this->getOffset() === $this->copy()->setTimezone(date_default_timezone_get())->getOffset();
|
||||
return $this->getOffset() === $this->avoidMutation()->setTimezone(date_default_timezone_get())->getOffset();
|
||||
|
||||
// @property-read bool checks if the timezone is UTC, true if UTC, false otherwise
|
||||
case $name === 'utc':
|
||||
@@ -1114,7 +1132,7 @@ trait Date
|
||||
case 'microseconds':
|
||||
case 'microsecond':
|
||||
case 'micro':
|
||||
if (substr($name, 0, 5) === 'milli') {
|
||||
if (str_starts_with($name, 'milli')) {
|
||||
$value *= 1000;
|
||||
}
|
||||
|
||||
@@ -1309,7 +1327,7 @@ trait Date
|
||||
{
|
||||
$dayOfYear = $this->dayOfYear;
|
||||
|
||||
return \is_null($value) ? $dayOfYear : $this->addDays($value - $dayOfYear);
|
||||
return $value === null ? $dayOfYear : $this->addDays($value - $dayOfYear);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1321,9 +1339,9 @@ trait Date
|
||||
*/
|
||||
public function weekday($value = null)
|
||||
{
|
||||
$dayOfWeek = ($this->dayOfWeek + 7 - \intval($this->getTranslationMessage('first_day_of_week') ?? 0)) % 7;
|
||||
$dayOfWeek = ($this->dayOfWeek + 7 - (int) ($this->getTranslationMessage('first_day_of_week') ?? 0)) % 7;
|
||||
|
||||
return \is_null($value) ? $dayOfWeek : $this->addDays($value - $dayOfWeek);
|
||||
return $value === null ? $dayOfWeek : $this->addDays($value - $dayOfWeek);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1337,7 +1355,7 @@ trait Date
|
||||
{
|
||||
$dayOfWeekIso = $this->dayOfWeekIso;
|
||||
|
||||
return \is_null($value) ? $dayOfWeekIso : $this->addDays($value - $dayOfWeekIso);
|
||||
return $value === null ? $dayOfWeekIso : $this->addDays($value - $dayOfWeekIso);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1352,11 +1370,11 @@ trait Date
|
||||
public function setUnitNoOverflow($valueUnit, $value, $overflowUnit)
|
||||
{
|
||||
try {
|
||||
$original = $this->copy();
|
||||
$original = $this->avoidMutation();
|
||||
/** @var static $date */
|
||||
$date = $this->$valueUnit($value);
|
||||
$end = $original->copy()->endOf($overflowUnit);
|
||||
$start = $original->copy()->startOf($overflowUnit);
|
||||
$end = $original->avoidMutation()->endOf($overflowUnit);
|
||||
$start = $original->avoidMutation()->startOf($overflowUnit);
|
||||
if ($date < $start) {
|
||||
$date = $date->setDateTimeFrom($start);
|
||||
} elseif ($date > $end) {
|
||||
@@ -1509,7 +1527,7 @@ trait Date
|
||||
*/
|
||||
public function setTimeFromTimeString($time)
|
||||
{
|
||||
if (strpos($time, ':') === false) {
|
||||
if (!str_contains($time, ':')) {
|
||||
$time .= ':0';
|
||||
}
|
||||
|
||||
@@ -1791,7 +1809,7 @@ trait Date
|
||||
|
||||
/**
|
||||
* Format the instance with the current locale. You can set the current
|
||||
* locale using setlocale() http://php.net/setlocale.
|
||||
* locale using setlocale() https://php.net/setlocale.
|
||||
*
|
||||
* @param string $format
|
||||
*
|
||||
@@ -1900,7 +1918,7 @@ trait Date
|
||||
's' => 'second',
|
||||
'ss' => ['getPaddedUnit', ['second']],
|
||||
'S' => function (CarbonInterface $date) {
|
||||
return \strval((string) floor($date->micro / 100000));
|
||||
return (string) floor($date->micro / 100000);
|
||||
},
|
||||
'SS' => function (CarbonInterface $date) {
|
||||
return str_pad((string) floor($date->micro / 10000), 2, '0', STR_PAD_LEFT);
|
||||
@@ -1999,15 +2017,15 @@ trait Date
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function ordinal(string $key, string $period = null): string
|
||||
public function ordinal(string $key, ?string $period = null): string
|
||||
{
|
||||
$number = $this->$key;
|
||||
$result = $this->translate('ordinal', [
|
||||
':number' => $number,
|
||||
':period' => $period,
|
||||
':period' => (string) $period,
|
||||
]);
|
||||
|
||||
return \strval($result === 'ordinal' ? $number : $result);
|
||||
return (string) ($result === 'ordinal' ? $number : $result);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2070,7 +2088,7 @@ trait Date
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function isoFormat(string $format, string $originalFormat = null): string
|
||||
public function isoFormat(string $format, ?string $originalFormat = null): string
|
||||
{
|
||||
$result = '';
|
||||
$length = mb_strlen($format);
|
||||
@@ -2149,7 +2167,7 @@ trait Date
|
||||
}
|
||||
|
||||
$format = mb_substr($format, 0, $i).$sequence.mb_substr($format, $i + mb_strlen($code));
|
||||
$i += mb_strlen("$sequence") - 1;
|
||||
$i += mb_strlen((string) $sequence) - 1;
|
||||
$length = mb_strlen($format);
|
||||
$char = $sequence;
|
||||
}
|
||||
@@ -2179,7 +2197,7 @@ trait Date
|
||||
'S' => function ($date) {
|
||||
$day = $date->rawFormat('j');
|
||||
|
||||
return str_replace("$day", '', $date->isoFormat('Do'));
|
||||
return str_replace((string) $day, '', $date->isoFormat('Do'));
|
||||
},
|
||||
'w' => true,
|
||||
'z' => true,
|
||||
@@ -2219,7 +2237,7 @@ trait Date
|
||||
}
|
||||
|
||||
/**
|
||||
* Format as ->format() do (using date replacements patterns from http://php.net/manual/fr/function.date.php)
|
||||
* Format as ->format() do (using date replacements patterns from https://php.net/manual/en/function.date.php)
|
||||
* but translate words whenever possible (months, day names, etc.) using the current locale.
|
||||
*
|
||||
* @param string $format
|
||||
@@ -2519,7 +2537,7 @@ trait Date
|
||||
|
||||
$unit = rtrim($method, 's');
|
||||
|
||||
if (substr($unit, 0, 2) === 'is') {
|
||||
if (str_starts_with($unit, 'is')) {
|
||||
$word = substr($unit, 2);
|
||||
|
||||
if (\in_array($word, static::$days)) {
|
||||
@@ -2557,7 +2575,7 @@ trait Date
|
||||
if ($action === 'add' || $action === 'sub') {
|
||||
$unit = substr($unit, 3);
|
||||
|
||||
if (substr($unit, 0, 4) === 'Real') {
|
||||
if (str_starts_with($unit, 'Real')) {
|
||||
$unit = static::singularUnit(substr($unit, 4));
|
||||
|
||||
return $this->{"${action}RealUnit"}($unit, ...$parameters);
|
||||
@@ -2599,7 +2617,7 @@ trait Date
|
||||
}
|
||||
}
|
||||
|
||||
if (substr($unit, 0, 9) === 'isCurrent') {
|
||||
if (str_starts_with($unit, 'isCurrent')) {
|
||||
try {
|
||||
return $this->isCurrentUnit(strtolower(substr($unit, 9)));
|
||||
} catch (BadComparisonUnitException | BadMethodCallException $exception) {
|
||||
@@ -2607,7 +2625,7 @@ trait Date
|
||||
}
|
||||
}
|
||||
|
||||
if (substr($method, -5) === 'Until') {
|
||||
if (str_ends_with($method, 'Until')) {
|
||||
try {
|
||||
$unit = static::singularUnit(substr($method, 0, -5));
|
||||
|
||||
|
@@ -121,7 +121,17 @@ trait Difference
|
||||
#[ReturnTypeWillChange]
|
||||
public function diff($date = null, $absolute = false)
|
||||
{
|
||||
return parent::diff($this->resolveCarbon($date), (bool) $absolute);
|
||||
$other = $this->resolveCarbon($date);
|
||||
|
||||
// Can be removed if https://github.com/derickr/timelib/pull/110
|
||||
// is merged
|
||||
// @codeCoverageIgnoreStart
|
||||
if (version_compare(PHP_VERSION, '8.1.0-dev', '>=') && $other->tz !== $this->tz) {
|
||||
$other = $other->avoidMutation()->tz($this->tz);
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
||||
return parent::diff($other, (bool) $absolute);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -540,14 +550,14 @@ trait Difference
|
||||
}
|
||||
$monthsDiff = $start->diffInMonths($end);
|
||||
/** @var Carbon|CarbonImmutable $floorEnd */
|
||||
$floorEnd = $start->copy()->addMonths($monthsDiff);
|
||||
$floorEnd = $start->avoidMutation()->addMonths($monthsDiff);
|
||||
|
||||
if ($floorEnd >= $end) {
|
||||
return $sign * $monthsDiff;
|
||||
}
|
||||
|
||||
/** @var Carbon|CarbonImmutable $startOfMonthAfterFloorEnd */
|
||||
$startOfMonthAfterFloorEnd = $floorEnd->copy()->addMonth()->startOfMonth();
|
||||
$startOfMonthAfterFloorEnd = $floorEnd->avoidMutation()->addMonth()->startOfMonth();
|
||||
|
||||
if ($startOfMonthAfterFloorEnd > $end) {
|
||||
return $sign * ($monthsDiff + $floorEnd->floatDiffInDays($end) / $floorEnd->daysInMonth);
|
||||
@@ -575,14 +585,14 @@ trait Difference
|
||||
}
|
||||
$yearsDiff = $start->diffInYears($end);
|
||||
/** @var Carbon|CarbonImmutable $floorEnd */
|
||||
$floorEnd = $start->copy()->addYears($yearsDiff);
|
||||
$floorEnd = $start->avoidMutation()->addYears($yearsDiff);
|
||||
|
||||
if ($floorEnd >= $end) {
|
||||
return $sign * $yearsDiff;
|
||||
}
|
||||
|
||||
/** @var Carbon|CarbonImmutable $startOfYearAfterFloorEnd */
|
||||
$startOfYearAfterFloorEnd = $floorEnd->copy()->addYear()->startOfYear();
|
||||
$startOfYearAfterFloorEnd = $floorEnd->avoidMutation()->addYear()->startOfYear();
|
||||
|
||||
if ($startOfYearAfterFloorEnd > $end) {
|
||||
return $sign * ($yearsDiff + $floorEnd->floatDiffInDays($end) / $floorEnd->daysInYear);
|
||||
@@ -641,7 +651,7 @@ trait Difference
|
||||
public function floatDiffInRealDays($date = null, $absolute = true)
|
||||
{
|
||||
$date = $this->resolveUTC($date);
|
||||
$utc = $this->copy()->utc();
|
||||
$utc = $this->avoidMutation()->utc();
|
||||
$hoursDiff = $utc->floatDiffInRealHours($date, $absolute);
|
||||
|
||||
return ($hoursDiff < 0 ? -1 : 1) * $utc->diffInDays($date) + fmod($hoursDiff, static::HOURS_PER_DAY) / static::HOURS_PER_DAY;
|
||||
@@ -679,14 +689,14 @@ trait Difference
|
||||
}
|
||||
$monthsDiff = $start->diffInMonths($end);
|
||||
/** @var Carbon|CarbonImmutable $floorEnd */
|
||||
$floorEnd = $start->copy()->addMonths($monthsDiff);
|
||||
$floorEnd = $start->avoidMutation()->addMonths($monthsDiff);
|
||||
|
||||
if ($floorEnd >= $end) {
|
||||
return $sign * $monthsDiff;
|
||||
}
|
||||
|
||||
/** @var Carbon|CarbonImmutable $startOfMonthAfterFloorEnd */
|
||||
$startOfMonthAfterFloorEnd = $floorEnd->copy()->addMonth()->startOfMonth();
|
||||
$startOfMonthAfterFloorEnd = $floorEnd->avoidMutation()->addMonth()->startOfMonth();
|
||||
|
||||
if ($startOfMonthAfterFloorEnd > $end) {
|
||||
return $sign * ($monthsDiff + $floorEnd->floatDiffInRealDays($end) / $floorEnd->daysInMonth);
|
||||
@@ -714,14 +724,14 @@ trait Difference
|
||||
}
|
||||
$yearsDiff = $start->diffInYears($end);
|
||||
/** @var Carbon|CarbonImmutable $floorEnd */
|
||||
$floorEnd = $start->copy()->addYears($yearsDiff);
|
||||
$floorEnd = $start->avoidMutation()->addYears($yearsDiff);
|
||||
|
||||
if ($floorEnd >= $end) {
|
||||
return $sign * $yearsDiff;
|
||||
}
|
||||
|
||||
/** @var Carbon|CarbonImmutable $startOfYearAfterFloorEnd */
|
||||
$startOfYearAfterFloorEnd = $floorEnd->copy()->addYear()->startOfYear();
|
||||
$startOfYearAfterFloorEnd = $floorEnd->avoidMutation()->addYear()->startOfYear();
|
||||
|
||||
if ($startOfYearAfterFloorEnd > $end) {
|
||||
return $sign * ($yearsDiff + $floorEnd->floatDiffInRealDays($end) / $floorEnd->daysInYear);
|
||||
@@ -737,7 +747,7 @@ trait Difference
|
||||
*/
|
||||
public function secondsSinceMidnight()
|
||||
{
|
||||
return $this->diffInSeconds($this->copy()->startOfDay());
|
||||
return $this->diffInSeconds($this->avoidMutation()->startOfDay());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -747,7 +757,7 @@ trait Difference
|
||||
*/
|
||||
public function secondsUntilEndOfDay()
|
||||
{
|
||||
return $this->diffInSeconds($this->copy()->endOfDay());
|
||||
return $this->diffInSeconds($this->avoidMutation()->endOfDay());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1106,9 +1116,9 @@ trait Difference
|
||||
public function calendar($referenceTime = null, array $formats = [])
|
||||
{
|
||||
/** @var CarbonInterface $current */
|
||||
$current = $this->copy()->startOfDay();
|
||||
$current = $this->avoidMutation()->startOfDay();
|
||||
/** @var CarbonInterface $other */
|
||||
$other = $this->resolveCarbon($referenceTime)->copy()->setTimezone($this->getTimezone())->startOfDay();
|
||||
$other = $this->resolveCarbon($referenceTime)->avoidMutation()->setTimezone($this->getTimezone())->startOfDay();
|
||||
$diff = $other->diffInDays($current, false);
|
||||
$format = $diff < -6 ? 'sameElse' : (
|
||||
$diff < -1 ? 'lastWeek' : (
|
||||
@@ -1126,6 +1136,6 @@ trait Difference
|
||||
$format = $format($current, $other) ?? '';
|
||||
}
|
||||
|
||||
return $this->isoFormat(\strval($format));
|
||||
return $this->isoFormat((string) $format);
|
||||
}
|
||||
}
|
||||
|
@@ -64,7 +64,7 @@ trait IntervalStep
|
||||
$carbonDate = $dateTime instanceof CarbonInterface ? $dateTime : $this->resolveCarbon($dateTime);
|
||||
|
||||
if ($this->step) {
|
||||
return $carbonDate->setDateTimeFrom(($this->step)($carbonDate->copy(), $negated));
|
||||
return $carbonDate->setDateTimeFrom(($this->step)($carbonDate->avoidMutation(), $negated));
|
||||
}
|
||||
|
||||
if ($negated) {
|
||||
|
@@ -168,7 +168,7 @@ trait Localization
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getTranslationMessageWith($translator, string $key, string $locale = null, string $default = null)
|
||||
public static function getTranslationMessageWith($translator, string $key, ?string $locale = null, ?string $default = null)
|
||||
{
|
||||
if (!($translator instanceof TranslatorBagInterface && $translator instanceof TranslatorInterface)) {
|
||||
throw new InvalidTypeException(
|
||||
@@ -196,7 +196,7 @@ trait Localization
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getTranslationMessage(string $key, string $locale = null, string $default = null, $translator = null)
|
||||
public function getTranslationMessage(string $key, ?string $locale = null, ?string $default = null, $translator = null)
|
||||
{
|
||||
return static::getTranslationMessageWith($translator ?: $this->getLocalTranslator(), $key, $locale, $default);
|
||||
}
|
||||
@@ -239,12 +239,12 @@ trait Localization
|
||||
*
|
||||
* @param string $key
|
||||
* @param array $parameters
|
||||
* @param null $number
|
||||
* @param string|int|float|null $number
|
||||
* @param \Symfony\Component\Translation\TranslatorInterface $translator
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function translate(string $key, array $parameters = [], $number = null, TranslatorInterface $translator = null, bool $altNumbers = false): string
|
||||
public function translate(string $key, array $parameters = [], $number = null, ?TranslatorInterface $translator = null, bool $altNumbers = false): string
|
||||
{
|
||||
$translation = static::translateWith($translator ?: $this->getLocalTranslator(), $key, $parameters, $number);
|
||||
|
||||
@@ -302,7 +302,7 @@ trait Localization
|
||||
return $result;
|
||||
}
|
||||
|
||||
return "$number";
|
||||
return (string) $number;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -224,11 +224,11 @@ trait Modifiers
|
||||
*/
|
||||
public function nthOfMonth($nth, $dayOfWeek)
|
||||
{
|
||||
$date = $this->copy()->firstOfMonth();
|
||||
$date = $this->avoidMutation()->firstOfMonth();
|
||||
$check = $date->rawFormat('Y-m');
|
||||
$date = $date->modify('+'.$nth.' '.static::$days[$dayOfWeek]);
|
||||
|
||||
return $date->rawFormat('Y-m') === $check ? $this->modify("$date") : false;
|
||||
return $date->rawFormat('Y-m') === $check ? $this->modify((string) $date) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -274,12 +274,12 @@ trait Modifiers
|
||||
*/
|
||||
public function nthOfQuarter($nth, $dayOfWeek)
|
||||
{
|
||||
$date = $this->copy()->day(1)->month($this->quarter * static::MONTHS_PER_QUARTER);
|
||||
$date = $this->avoidMutation()->day(1)->month($this->quarter * static::MONTHS_PER_QUARTER);
|
||||
$lastMonth = $date->month;
|
||||
$year = $date->year;
|
||||
$date = $date->firstOfQuarter()->modify('+'.$nth.' '.static::$days[$dayOfWeek]);
|
||||
|
||||
return ($lastMonth < $date->month || $year !== $date->year) ? false : $this->modify("$date");
|
||||
return ($lastMonth < $date->month || $year !== $date->year) ? false : $this->modify((string) $date);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -325,9 +325,9 @@ trait Modifiers
|
||||
*/
|
||||
public function nthOfYear($nth, $dayOfWeek)
|
||||
{
|
||||
$date = $this->copy()->firstOfYear()->modify('+'.$nth.' '.static::$days[$dayOfWeek]);
|
||||
$date = $this->avoidMutation()->firstOfYear()->modify('+'.$nth.' '.static::$days[$dayOfWeek]);
|
||||
|
||||
return $this->year === $date->year ? $this->modify("$date") : false;
|
||||
return $this->year === $date->year ? $this->modify((string) $date) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -454,7 +454,7 @@ trait Modifiers
|
||||
{
|
||||
return $this->modify(preg_replace_callback('/^(next|previous|last)\s+(\d{1,2}(h|am|pm|:\d{1,2}(:\d{1,2})?))$/i', function ($match) {
|
||||
$match[2] = str_replace('h', ':00', $match[2]);
|
||||
$test = $this->copy()->modify($match[2]);
|
||||
$test = $this->avoidMutation()->modify($match[2]);
|
||||
$method = $match[1] === 'next' ? 'lt' : 'gt';
|
||||
$match[1] = $test->$method($this) ? $match[1].' day' : 'today';
|
||||
|
||||
|
@@ -17,5 +17,5 @@ trait ObjectInitialisation
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $constructedObjectId = null;
|
||||
protected $constructedObjectId;
|
||||
}
|
||||
|
@@ -151,21 +151,21 @@ trait Options
|
||||
*
|
||||
* @var string|callable|null
|
||||
*/
|
||||
protected static $formatFunction = null;
|
||||
protected static $formatFunction;
|
||||
|
||||
/**
|
||||
* Function to call instead of createFromFormat.
|
||||
*
|
||||
* @var string|callable|null
|
||||
*/
|
||||
protected static $createFromFormatFunction = null;
|
||||
protected static $createFromFormatFunction;
|
||||
|
||||
/**
|
||||
* Function to call instead of parse.
|
||||
*
|
||||
* @var string|callable|null
|
||||
*/
|
||||
protected static $parseFunction = null;
|
||||
protected static $parseFunction;
|
||||
|
||||
/**
|
||||
* Indicates if months should be calculated with overflow.
|
||||
@@ -173,7 +173,7 @@ trait Options
|
||||
*
|
||||
* @var bool|null
|
||||
*/
|
||||
protected $localMonthsOverflow = null;
|
||||
protected $localMonthsOverflow;
|
||||
|
||||
/**
|
||||
* Indicates if years should be calculated with overflow.
|
||||
@@ -181,7 +181,7 @@ trait Options
|
||||
*
|
||||
* @var bool|null
|
||||
*/
|
||||
protected $localYearsOverflow = null;
|
||||
protected $localYearsOverflow;
|
||||
|
||||
/**
|
||||
* Indicates if the strict mode is in use.
|
||||
@@ -189,49 +189,49 @@ trait Options
|
||||
*
|
||||
* @var bool|null
|
||||
*/
|
||||
protected $localStrictModeEnabled = null;
|
||||
protected $localStrictModeEnabled;
|
||||
|
||||
/**
|
||||
* Options for diffForHumans and forHumans methods.
|
||||
*
|
||||
* @var bool|null
|
||||
*/
|
||||
protected $localHumanDiffOptions = null;
|
||||
protected $localHumanDiffOptions;
|
||||
|
||||
/**
|
||||
* Format to use on string cast.
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
protected $localToStringFormat = null;
|
||||
protected $localToStringFormat;
|
||||
|
||||
/**
|
||||
* Format to use on JSON serialization.
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
protected $localSerializer = null;
|
||||
protected $localSerializer;
|
||||
|
||||
/**
|
||||
* Instance-specific macros.
|
||||
*
|
||||
* @var array|null
|
||||
*/
|
||||
protected $localMacros = null;
|
||||
protected $localMacros;
|
||||
|
||||
/**
|
||||
* Instance-specific generic macros.
|
||||
*
|
||||
* @var array|null
|
||||
*/
|
||||
protected $localGenericMacros = null;
|
||||
protected $localGenericMacros;
|
||||
|
||||
/**
|
||||
* Function to call instead of format.
|
||||
*
|
||||
* @var string|callable|null
|
||||
*/
|
||||
protected $localFormatFunction = null;
|
||||
protected $localFormatFunction;
|
||||
|
||||
/**
|
||||
* @deprecated To avoid conflict between different third-party libraries, static setters should not be used.
|
||||
@@ -449,7 +449,7 @@ trait Options
|
||||
|
||||
protected function addExtraDebugInfos(&$infos): void
|
||||
{
|
||||
if ($this instanceof CarbonInterface || $this instanceof DateTimeInterface) {
|
||||
if ($this instanceof DateTimeInterface) {
|
||||
try {
|
||||
if (!isset($infos['date'])) {
|
||||
$infos['date'] = $this->format(CarbonInterface::MOCK_DATETIME_FORMAT);
|
||||
|
@@ -194,7 +194,10 @@ trait Rounding
|
||||
*/
|
||||
public function roundWeek($weekStartsAt = null)
|
||||
{
|
||||
return $this->closest($this->copy()->floorWeek($weekStartsAt), $this->copy()->ceilWeek($weekStartsAt));
|
||||
return $this->closest(
|
||||
$this->avoidMutation()->floorWeek($weekStartsAt),
|
||||
$this->avoidMutation()->ceilWeek($weekStartsAt)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -219,7 +222,7 @@ trait Rounding
|
||||
public function ceilWeek($weekStartsAt = null)
|
||||
{
|
||||
if ($this->isMutable()) {
|
||||
$startOfWeek = $this->copy()->startOfWeek($weekStartsAt);
|
||||
$startOfWeek = $this->avoidMutation()->startOfWeek($weekStartsAt);
|
||||
|
||||
return $startOfWeek != $this ?
|
||||
$this->startOfWeek($weekStartsAt)->addWeek() :
|
||||
@@ -230,6 +233,6 @@ trait Rounding
|
||||
|
||||
return $startOfWeek != $this ?
|
||||
$startOfWeek->addWeek() :
|
||||
$this->copy();
|
||||
$this->avoidMutation();
|
||||
}
|
||||
}
|
||||
|
@@ -12,6 +12,7 @@ namespace Carbon\Traits;
|
||||
|
||||
use Carbon\Exceptions\InvalidFormatException;
|
||||
use ReturnTypeWillChange;
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* Trait Serialization.
|
||||
@@ -53,7 +54,15 @@ trait Serialization
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
protected $dumpLocale = null;
|
||||
protected $dumpLocale;
|
||||
|
||||
/**
|
||||
* Embed date properties to dump in a dedicated variables so it won't overlap native
|
||||
* DateTime ones.
|
||||
*
|
||||
* @var array|null
|
||||
*/
|
||||
protected $dumpDateProperties;
|
||||
|
||||
/**
|
||||
* Return a serialized string of the instance.
|
||||
@@ -76,7 +85,7 @@ trait Serialization
|
||||
*/
|
||||
public static function fromSerialized($value)
|
||||
{
|
||||
$instance = @unserialize("$value");
|
||||
$instance = @unserialize((string) $value);
|
||||
|
||||
if (!$instance instanceof static) {
|
||||
throw new InvalidFormatException("Invalid serialized value: $value");
|
||||
@@ -114,7 +123,7 @@ trait Serialization
|
||||
*/
|
||||
public function __sleep()
|
||||
{
|
||||
$properties = $this->dumpProperties;
|
||||
$properties = $this->getSleepProperties();
|
||||
|
||||
if ($this->localTranslator ?? null) {
|
||||
$properties[] = 'dumpLocale';
|
||||
@@ -131,7 +140,15 @@ trait Serialization
|
||||
public function __wakeup()
|
||||
{
|
||||
if (get_parent_class() && method_exists(parent::class, '__wakeup')) {
|
||||
parent::__wakeup();
|
||||
// @codeCoverageIgnoreStart
|
||||
try {
|
||||
parent::__wakeup();
|
||||
} catch (Throwable $exception) {
|
||||
// FatalError occurs when calling msgpack_unpack() in PHP 7.4 or later.
|
||||
['date' => $date, 'timezone' => $timezone] = $this->dumpDateProperties;
|
||||
parent::__construct($date, unserialize($timezone));
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
|
||||
$this->constructedObjectId = spl_object_hash($this);
|
||||
@@ -149,6 +166,7 @@ trait Serialization
|
||||
*
|
||||
* @return array|string
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function jsonSerialize()
|
||||
{
|
||||
$serializer = $this->localSerializer ?? static::$serializer;
|
||||
@@ -194,4 +212,26 @@ trait Serialization
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
private function getSleepProperties(): array
|
||||
{
|
||||
$properties = $this->dumpProperties;
|
||||
|
||||
// @codeCoverageIgnoreStart
|
||||
if (!\extension_loaded('msgpack')) {
|
||||
return $properties;
|
||||
}
|
||||
|
||||
if (isset($this->constructedObjectId)) {
|
||||
$this->dumpDateProperties = [
|
||||
'date' => $this->format('Y-m-d H:i:s.u'),
|
||||
'timezone' => serialize($this->timezone ?? null),
|
||||
];
|
||||
|
||||
$properties[] = 'dumpDateProperties';
|
||||
}
|
||||
|
||||
return $properties;
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
}
|
||||
|
@@ -63,12 +63,16 @@ trait Test
|
||||
*
|
||||
* @param Closure|static|string|false|null $testNow real or mock Carbon instance
|
||||
* @param Closure|null $callback
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public static function withTestNow($testNow = null, $callback = null)
|
||||
{
|
||||
static::setTestNow($testNow);
|
||||
$callback();
|
||||
$result = $callback();
|
||||
static::setTestNow();
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -45,6 +45,7 @@ trait Timestamp
|
||||
$delta = floor($decimal / static::MICROSECONDS_PER_SECOND);
|
||||
$integer += $delta;
|
||||
$decimal -= $delta * static::MICROSECONDS_PER_SECOND;
|
||||
$decimal = str_pad((string) $decimal, 6, '0', STR_PAD_LEFT);
|
||||
|
||||
return static::rawCreateFromFormat('U u', "$integer $decimal");
|
||||
}
|
||||
@@ -136,6 +137,16 @@ trait Timestamp
|
||||
return $this->getPreciseTimestamp(3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the timestamp with millisecond precision.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getTimestampMs()
|
||||
{
|
||||
return (int) $this->getPreciseTimestamp(3);
|
||||
}
|
||||
|
||||
/**
|
||||
* @alias getTimestamp
|
||||
*
|
||||
@@ -166,15 +177,15 @@ trait Timestamp
|
||||
$numbers = number_format($numbers, $decimals, '.', '');
|
||||
}
|
||||
|
||||
$sign = substr($numbers, 0, 1) === '-' ? -1 : 1;
|
||||
$sign = str_starts_with($numbers, '-') ? -1 : 1;
|
||||
$integer = 0;
|
||||
$decimal = 0;
|
||||
|
||||
foreach (preg_split('`[^0-9.]+`', $numbers) as $chunk) {
|
||||
[$integerPart, $decimalPart] = explode('.', "$chunk.");
|
||||
|
||||
$integer += \intval($integerPart);
|
||||
$decimal += \floatval("0.$decimalPart");
|
||||
$integer += (int) $integerPart;
|
||||
$decimal += (float) ("0.$decimalPart");
|
||||
}
|
||||
|
||||
$overflow = floor($decimal);
|
||||
|
@@ -48,7 +48,7 @@ trait Units
|
||||
$seconds = (int) floor($diff / static::MICROSECONDS_PER_SECOND);
|
||||
$time += $seconds;
|
||||
$diff -= $seconds * static::MICROSECONDS_PER_SECOND;
|
||||
$microtime = str_pad("$diff", 6, '0', STR_PAD_LEFT);
|
||||
$microtime = str_pad((string) $diff, 6, '0', STR_PAD_LEFT);
|
||||
$tz = $this->tz;
|
||||
|
||||
return $this->tz('UTC')->modify("@$time.$microtime")->tz($tz);
|
||||
@@ -201,6 +201,21 @@ trait Units
|
||||
$unit = CarbonInterval::make($unit);
|
||||
}
|
||||
|
||||
// Can be removed if https://bugs.php.net/bug.php?id=81106
|
||||
// is fixed
|
||||
// @codeCoverageIgnoreStart
|
||||
if (
|
||||
$unit instanceof DateInterval &&
|
||||
version_compare(PHP_VERSION, '8.1.0-dev', '>=') &&
|
||||
($unit->f < 0 || $unit->f >= 1)
|
||||
) {
|
||||
$unit = clone $unit;
|
||||
$seconds = floor($unit->f);
|
||||
$unit->f -= $seconds;
|
||||
$unit->s += (int) $seconds;
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
||||
if ($unit instanceof CarbonConverterInterface) {
|
||||
return $this->resolveCarbon($unit->convertDate($this, false));
|
||||
}
|
||||
@@ -233,8 +248,8 @@ trait Units
|
||||
{
|
||||
$date = $this;
|
||||
|
||||
if (!is_numeric($value) || !\floatval($value)) {
|
||||
return $date->isMutable() ? $date : $date->copy();
|
||||
if (!is_numeric($value) || !(float) $value) {
|
||||
return $date->isMutable() ? $date : $date->avoidMutation();
|
||||
}
|
||||
|
||||
$metaUnits = [
|
||||
@@ -377,7 +392,7 @@ trait Units
|
||||
[$value, $unit] = [$unit, $value];
|
||||
}
|
||||
|
||||
return $this->addUnit($unit, -\floatval($value), $overflow);
|
||||
return $this->addUnit($unit, -(float) $value, $overflow);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -27,7 +27,7 @@ namespace Carbon\Traits;
|
||||
* @method static addWeeks(int $weeks = 1)
|
||||
* @method static copy()
|
||||
* @method static dayOfYear(int $dayOfYear)
|
||||
* @method string getTranslationMessage(string $key, string $locale = null, string $default = null, $translator = null)
|
||||
* @method string getTranslationMessage(string $key, ?string $locale = null, ?string $default = null, $translator = null)
|
||||
* @method static next(int|string $day = null)
|
||||
* @method static startOfWeek(int $day = 1)
|
||||
* @method static subWeeks(int $weeks = 1)
|
||||
@@ -75,7 +75,7 @@ trait Week
|
||||
$year = (int) round($year);
|
||||
|
||||
if ($this->weekYear(null, $dayOfWeek, $dayOfYear) === $year) {
|
||||
return $this->copy();
|
||||
return $this->avoidMutation();
|
||||
}
|
||||
|
||||
$week = $this->week(null, $dayOfWeek, $dayOfYear);
|
||||
@@ -103,13 +103,13 @@ trait Week
|
||||
|
||||
$year = $this->year;
|
||||
$day = $this->dayOfYear;
|
||||
$date = $this->copy()->dayOfYear($dayOfYear)->startOfWeek($dayOfWeek);
|
||||
$date = $this->avoidMutation()->dayOfYear($dayOfYear)->startOfWeek($dayOfWeek);
|
||||
|
||||
if ($date->year === $year && $day < $date->dayOfYear) {
|
||||
return $year - 1;
|
||||
}
|
||||
|
||||
$date = $this->copy()->addYear()->dayOfYear($dayOfYear)->startOfWeek($dayOfWeek);
|
||||
$date = $this->avoidMutation()->addYear()->dayOfYear($dayOfYear)->startOfWeek($dayOfWeek);
|
||||
|
||||
if ($date->year === $year && $day >= $date->dayOfYear) {
|
||||
return $year + 1;
|
||||
@@ -151,12 +151,12 @@ trait Week
|
||||
$dayOfWeek = $dayOfWeek ?? $this->getTranslationMessage('first_day_of_week') ?? 0;
|
||||
$dayOfYear = $dayOfYear ?? $this->getTranslationMessage('day_of_first_week_of_year') ?? 1;
|
||||
$year = $this->year;
|
||||
$start = $this->copy()->dayOfYear($dayOfYear)->startOfWeek($dayOfWeek);
|
||||
$start = $this->avoidMutation()->dayOfYear($dayOfYear)->startOfWeek($dayOfWeek);
|
||||
$startDay = $start->dayOfYear;
|
||||
if ($start->year !== $year) {
|
||||
$startDay -= $start->daysInYear;
|
||||
}
|
||||
$end = $this->copy()->addYear()->dayOfYear($dayOfYear)->startOfWeek($dayOfWeek);
|
||||
$end = $this->avoidMutation()->addYear()->dayOfYear($dayOfYear)->startOfWeek($dayOfWeek);
|
||||
$endDay = $end->dayOfYear;
|
||||
if ($end->year !== $year) {
|
||||
$endDay += $this->daysInYear;
|
||||
@@ -186,8 +186,8 @@ trait Week
|
||||
return $date->addWeeks(round($week) - $this->week(null, $dayOfWeek, $dayOfYear));
|
||||
}
|
||||
|
||||
$start = $date->copy()->dayOfYear($dayOfYear)->startOfWeek($dayOfWeek);
|
||||
$end = $date->copy()->startOfWeek($dayOfWeek);
|
||||
$start = $date->avoidMutation()->dayOfYear($dayOfYear)->startOfWeek($dayOfWeek);
|
||||
$end = $date->avoidMutation()->startOfWeek($dayOfWeek);
|
||||
if ($start > $end) {
|
||||
$start = $start->subWeeks(26)->dayOfYear($dayOfYear)->startOfWeek($dayOfWeek);
|
||||
}
|
||||
|
@@ -148,7 +148,7 @@ class Translator extends Translation\Translator
|
||||
*/
|
||||
public function trans($id, array $parameters = [], $domain = null, $locale = null)
|
||||
{
|
||||
if (null === $domain) {
|
||||
if ($domain === null) {
|
||||
$domain = 'messages';
|
||||
}
|
||||
|
||||
@@ -326,7 +326,7 @@ class Translator extends Translation\Translator
|
||||
|
||||
$previousLocale = $this->getLocale();
|
||||
|
||||
if ($previousLocale === $locale) {
|
||||
if ($previousLocale === $locale && isset($this->messages[$locale])) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -355,7 +355,7 @@ class Translator extends Translation\Translator
|
||||
}
|
||||
|
||||
// If subtag (ex: en_CA) first load the macro (ex: en) to have a fallback
|
||||
if (strpos($locale, '_') !== false &&
|
||||
if (str_contains($locale, '_') &&
|
||||
$this->loadMessagesFromFile($macroLocale = preg_replace('/^([^_]+).*$/', '$1', $locale))
|
||||
) {
|
||||
parent::setLocale($macroLocale);
|
||||
|
Reference in New Issue
Block a user