This commit is contained in:
Sebastian Molenda
2026-05-12 21:10:38 +02:00
commit ab96d82fcf
2544 changed files with 721700 additions and 0 deletions
+4
View File
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<phive xmlns="https://phar.io/phive">
<phar name="phpstan" version="2.1.17" installed="2.1.17" location="./tools/phpstan" copy="false"/>
</phive>
+10
View File
@@ -0,0 +1,10 @@
# Basic docker based environment
# Necessary to trick dokku into building the documentation
# using dockerfile instead of herokuish
FROM php:8.1
WORKDIR /code
VOLUME ["/code"]
CMD [ '/bin/bash' ]
+20
View File
@@ -0,0 +1,20 @@
Copyright (C) Brian Nesbitt
Copyright (C) Cake Software Foundation, Inc. (https://cakefoundation.org)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
+86
View File
@@ -0,0 +1,86 @@
# CakePHP Chronos
![Build Status](https://github.com/cakephp/chronos/actions/workflows/ci.yml/badge.svg?branch=master)
[![Latest Stable Version](https://img.shields.io/github/v/release/cakephp/chronos?sort=semver&style=flat-square)](https://packagist.org/packages/cakephp/chronos)
[![Total Downloads](https://img.shields.io/packagist/dt/cakephp/chronos?style=flat-square)](https://packagist.org/packages/cakephp/chronos/stats)
[![Code Coverage](https://img.shields.io/coveralls/cakephp/chronos/master.svg?style=flat-square)](https://coveralls.io/r/cakephp/chronos?branch=master)
[![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](LICENSE)
Chronos focuses on providing immutable date/datetime objects.
Immutable objects help ensure that datetime objects aren't accidentally
modified, keeping data more predictable.
# Installation
Installing with composer:
```
$ composer require cakephp/chronos
```
For details on the (minimum/maximum) PHP version see [version map](https://github.com/cakephp/chronos/wiki#version-map).
# Usage
```php
<?php
require 'vendor/autoload.php';
use Cake\Chronos\Chronos;
printf("Now: %s", Chronos::now());
```
# Differences with nesbot/carbon
Chronos was originally compatible with Carbon but has diverged and no longer
extends the PHP DateTime and DateTimeImmutable classes.
# Immutable Object Changes
Immutable objects have a number of advantages:
1. Using immutable objects is always free of side-effects.
2. Dates and times don't accidentally change underneath other parts of your code.
With those benefits in mind, there are a few things you need to keep in mind
when modifying immutable objects:
```php
// This will lose modifications
$date = new Chronos('2015-10-21 16:29:00');
$date->modify('+2 hours');
// This will keep modifications
$date = new Chronos('2015-10-21 16:29:00');
$date = $date->modify('+2 hours');
```
# Calendar Dates
PHP only offers datetime objects as part of the native extensions. Chronos adds
a number of conveniences to the traditional DateTime object and introduces
a `ChronosDate` object. `ChronosDate` instances their time frozen to `00:00:00` and the timezone
set to the server default timezone. This makes them ideal when working with
calendar dates as the time components will always match.
```php
use Cake\Chronos\ChronosDate;
$today = new ChronosDate();
echo $today;
// Outputs '2015-10-21'
echo $today->modify('+3 hours');
// Outputs '2015-10-21'
```
Like instances of `Chronos`, `ChronosDate` objects are also *immutable*.
# Documentation
A more descriptive documentation can be found at [book.cakephp.org/chronos/3/en/](https://book.cakephp.org/chronos/3/en/).
# API Documentation
API documentation can be found on [api.cakephp.org/chronos](https://api.cakephp.org/chronos).
+67
View File
@@ -0,0 +1,67 @@
{
"name": "cakephp/chronos",
"description": "A simple API extension for DateTime.",
"license": "MIT",
"type": "library",
"keywords": [
"date",
"time",
"DateTime"
],
"authors": [
{
"name": "Brian Nesbitt",
"email": "brian@nesbot.com",
"homepage": "http://nesbot.com"
},
{
"name": "The CakePHP Team",
"homepage": "https://cakephp.org"
}
],
"homepage": "https://cakephp.org",
"support": {
"issues": "https://github.com/cakephp/chronos/issues",
"source": "https://github.com/cakephp/chronos"
},
"require": {
"php": ">=8.1",
"psr/clock": "^1.0"
},
"require-dev": {
"cakephp/cakephp-codesniffer": "^5.0",
"phpunit/phpunit": "^10.5.58 || ^11.1.3"
},
"provide": {
"psr/clock-implementation": "1.0"
},
"autoload": {
"psr-4": {
"Cake\\Chronos\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"Cake\\Chronos\\Test\\": "tests/"
}
},
"config": {
"allow-plugins": {
"dealerdirect/phpcodesniffer-composer-installer": true
}
},
"scripts": {
"check": [
"@test",
"@cs-check",
"@stan"
],
"cs-check": "phpcs --colors --parallel=16 -p",
"cs-fix": "phpcbf --colors --parallel=16 -p",
"phpstan": "tools/phpstan analyse",
"stan": "@phpstan",
"stan-baseline": "tools/phpstan --generate-baseline",
"stan-setup": "phive install",
"test": "phpunit"
}
}
+26
View File
@@ -0,0 +1,26 @@
# Generate the HTML output.
FROM ghcr.io/cakephp/docs-builder as builder
RUN pip install git+https://github.com/sphinx-contrib/video.git@master
COPY docs /data/docs
ENV LANGS="en fr ja pt"
# build docs with sphinx
RUN cd /data/docs-builder && \
make website LANGS="$LANGS" SOURCE=/data/docs DEST=/data/website
# Build a small nginx container with just the static site in it.
FROM ghcr.io/cakephp/docs-builder:runtime as runtime
ENV LANGS="en fr ja pt"
ENV SEARCH_SOURCE="/usr/share/nginx/html"
ENV SEARCH_URL_PREFIX="/chronos/3"
COPY --from=builder /data/docs /data/docs
COPY --from=builder /data/website /data/website
COPY --from=builder /data/docs-builder/nginx.conf /etc/nginx/conf.d/default.conf
# Move docs into place.
RUN cp -R /data/website/html/* /usr/share/nginx/html \
&& rm -rf /data/website
+50
View File
@@ -0,0 +1,50 @@
# Global configuration information used across all the
# translations of documentation.
#
# Import the base theme configuration
from cakephpsphinx.config.all import *
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The full version, including alpha/beta/rc tags.
release = '3.x'
# The search index version.
search_version = 'chronos-3'
# The marketing display name for the book.
version_name = ''
# Project name shown in the black header bar
project = 'Chronos'
# Other versions that display in the version picker menu.
version_list = [
{'name': '1.x', 'number': '/chronos/1', 'title': '1.x'},
{'name': '2.x', 'number': '/chronos/2', 'title': '2.x'},
{'name': '3.x', 'number': '/chronos/3', 'title': '3.x', 'current': True},
]
# Languages available.
languages = ['en', 'fr', 'ja', 'pt']
# The GitHub branch name for this version of the docs
# for edit links to point at.
branch = '3.x'
# Current version being built
version = '3.x'
# Language in use for this directory.
language = 'en'
show_root_link = True
repository = 'cakephp/chronos'
source_path = 'docs/'
hide_page_contents = ('search', '404', 'contents')
@@ -0,0 +1,21 @@
3.x Migration Guide
###################
Chronos 3.x contains breaking changes that could impact your application. This
guide provides an overview of the breaking changes made in 3.x
Minimum of PHP 8.1
==================
Chronos 3.x requires at least PHP 8.1. This allows chronos to provide more
comprehensive typehinting and better performance by leveraging features found in
newer PHP versions.
MutableDateTime and MutableDate removed
=======================================
The ``MutableDateTime`` and ``MutableDate`` classes have been removed. Long term
PHP will be deprecating and removing mutable datetime classes in favour of
immutable ones. Chronos has long favoured immutable objects and removing the
mutable variants helps simplify the internals of Chronos and encourages safer
development practices.
+9
View File
@@ -0,0 +1,9 @@
import sys, os
# Append the top level directory of the docs, so we can import from the config dir.
sys.path.insert(0, os.path.abspath('..'))
# Pull in all the configuration options defined in the global config file..
from config.all import *
language = 'en'
+7
View File
@@ -0,0 +1,7 @@
.. toctree::
:maxdepth: 2
:caption: CakePHP Chronos
/index
API <https://api.cakephp.org/chronos>
+308
View File
@@ -0,0 +1,308 @@
Chronos
#######
Chronos provides a zero-dependency ``DateTimeImmutable`` extension, Date-only and Time-only classes:
* ``Cake\Chronos\Chronos`` extends ``DateTimeImmutable`` and provides many helpers.
* ``Cake\Chronos\ChronosDate`` represents calendar dates unaffected by time or time zones.
* ``Cake\Chronos\ChronosTime`` represents clock times independent of date or time zones.
* Only safe, immutable objects.
* A pluggable translation system. Only English translations are included in the
library. However, ``cakephp/i18n`` can be used for full language support.
The ``Chronos`` class extends ``DateTimeImmutable`` and implements ``DateTimeInterface``
which allows users to use type declarations that support either.
``ChronosDate`` and ``ChronosTime`` do not extend ``DateTimeImmutable`` and do not
share an interface. However, they can be converted to a ``DateTimeImmutable`` instance
using ``toDateTimeImmutable()``.
Installation
------------
To install Chronos, you should use ``composer``. From your
application's ROOT directory (where composer.json file is located) run the
following::
php composer.phar require "cakephp/chronos:^3.0"
Creating Instances
------------------
There are many ways to get an instance of Chronos or Date. There are a number of
factory methods that work with different argument sets::
use Cake\Chronos\Chronos;
$now = Chronos::now();
$today = Chronos::today();
$yesterday = Chronos::yesterday();
$tomorrow = Chronos::tomorrow();
// Parse relative expressions
$date = Chronos::parse('+2 days, +3 hours');
// Date and time integer values.
$date = Chronos::create(2015, 12, 25, 4, 32, 58);
// Date or time integer values.
$date = Chronos::createFromDate(2015, 12, 25);
$date = Chronos::createFromTime(11, 45, 10);
// Parse formatted values.
$date = Chronos::createFromFormat('m/d/Y', '06/15/2015');
Working with Immutable Objects
------------------------------
Chronos provides only *immutable* objects.
If you've used PHP ``DateTimeImmutable`` and ``DateTime`` classes, then you understand
the difference between *mutable* and *immutable* objects.
Immutable objects create copies of an object each time a change is made. Because modifier methods
around datetimes are not always easy to identify, data can be modified accidentally
or without the developer knowing. Immutable objects prevent accidental changes
to data, and make code free of order-based dependency issues. Immutability does
mean that you will need to remember to replace variables when using modifiers::
// This code doesn't work with immutable objects
$chronos->addDay(1);
doSomething($chronos);
return $chronos;
// This works like you'd expect
$chronos = $chronos->addDay(1);
$chronos = doSomething($chronos);
return $chronos;
By capturing the return value of each modification your code will work as
expected.
Date Objects
------------
PHP provides only date-time classes that combines both dates and time parts.
Representing calendar dates can be a bit awkward with ``DateTimeImmutable`` as it includes
time and timezones, which aren't part of a 'date'. Chronos provides
``ChronosDate`` that allows you to represent dates. The time these objects
these objects is always fixed to ``00:00:00`` and not affeced by the server time zone
or modify helpers::
use Cake\Chronos\ChronosDate;
$today = ChronosDate::today();
// Changes to the time/timezone are ignored.
$today->modify('+1 hours');
// Outputs '2015-12-20'
echo $today;
Although ``ChronosDate`` uses a fixed time zone internally, you can specify which
time zone to use for current time such as ``now()`` or ``today()``::
use Cake\Chronos\ChronosDate:
// Takes the current date from Asia/Tokyo time zone
$today = ChronosDate::today('Asia/Tokyo');
Modifier Methods
----------------
Chronos objects provide modifier methods that let you modify the value in
a granular way::
// Set components of the datetime value.
$halloween = Chronos::create()
->year(2015)
->month(10)
->day(31)
->hour(20)
->minute(30);
You can also modify parts of the datetime relatively::
$future = Chronos::create()
->addYears(1)
->subMonths(2)
->addDays(15)
->addHours(20)
->subMinutes(2);
It is also possible to make big jumps to defined points in time::
$time = Chronos::create();
$time->startOfDay();
$time->endOfDay();
$time->startOfMonth();
$time->endOfMonth();
$time->startOfYear();
$time->endOfYear();
$time->startOfWeek();
$time->endOfWeek();
Or jump to specific days of the week::
$time->next(Chronos::TUESDAY);
$time->previous(Chronos::MONDAY);
When modifying dates/times across :abbr:`DST (Daylight Savings Time)` transitions
your operations may gain/lose an additional hours resulting in hour values that
don't add up. You can avoid these issues by first changing your timezone to
``UTC``, modifying the time::
// Additional hour gained.
$time = new Chronos('2014-03-30 00:00:00', 'Europe/London');
debug($time->modify('+24 hours')); // 2014-03-31 01:00:00
// First switch to UTC, and modify
$time = $time->setTimezone('UTC')
->modify('+24 hours');
Once you are done modifying the time you can add the original timezone to get
the localized time.
Comparison Methods
------------------
Once you have 2 instances of Chronos date/time objects you can compare them in
a variety of ways::
// Full suite of comparators exist
// equals, notEquals, greaterThan, greaterThanOrEquals, lessThan, lessThanOrEquals
$first->equals($second);
$first->greaterThanOrEquals($second);
// See if the current object is between two others.
$now->between($start, $end);
// Find which argument is closest or farthest.
$now->closest($june, $november);
$now->farthest($june, $november);
You can also inquire about where a given value falls on the calendar::
$now->isToday();
$now->isYesterday();
$now->isFuture();
$now->isPast();
// Check the day of the week
$now->isWeekend();
// All other weekday methods exist too.
$now->isMonday();
You can also find out if a value was within a relative time period::
$time->wasWithinLast('3 days');
$time->isWithinNext('3 hours');
Generating Differences
----------------------
In addition to comparing datetimes, calculating differences or deltas between
two values is a common task::
// Get a DateInterval representing the difference
$first->diff($second);
// Get difference as a count of specific units.
$first->diffInHours($second);
$first->diffInDays($second);
$first->diffInWeeks($second);
$first->diffInYears($second);
You can generate human readable differences suitable for use in a feed or
timeline::
// Difference from now.
echo $date->diffForHumans();
// Difference from another point in time.
echo $date->diffForHumans($other); // 1 hour ago;
Formatting Strings
------------------
Chronos provides a number of methods for displaying our outputting datetime
objects::
// Uses the format controlled by setToStringFormat()
echo $date;
// Different standard formats
echo $time->toAtomString(); // 1975-12-25T14:15:16-05:00
echo $time->toCookieString(); // Thursday, 25-Dec-1975 14:15:16 EST
echo $time->toIso8601String(); // 1975-12-25T14:15:16-05:00
echo $time->toRfc822String(); // Thu, 25 Dec 75 14:15:16 -0500
echo $time->toRfc850String(); // Thursday, 25-Dec-75 14:15:16 EST
echo $time->toRfc1036String(); // Thu, 25 Dec 75 14:15:16 -0500
echo $time->toRfc1123String(); // Thu, 25 Dec 1975 14:15:16 -0500
echo $time->toRfc2822String(); // Thu, 25 Dec 1975 14:15:16 -0500
echo $time->toRfc3339String(); // 1975-12-25T14:15:16-05:00
echo $time->toRssString(); // Thu, 25 Dec 1975 14:15:16 -0500
echo $time->toW3cString(); // 1975-12-25T14:15:16-05:00
// Get the quarter/week
echo $time->toQuarter(); // 4
echo $time->toWeek(); // 52
// Generic formatting
echo $time->toTimeString(); // 14:15:16
echo $time->toDateString(); // 1975-12-25
echo $time->toDateTimeString(); // 1975-12-25 14:15:16
echo $time->toFormattedDateString(); // Dec 25, 1975
echo $time->toDayDateTimeString(); // Thu, Dec 25, 1975 2:15 PM
Extracting Date Components
--------------------------
Getting parts of a date object can be done by directly accessing properties::
$time = new Chronos('2015-12-31 23:59:58.123');
$time->year; // 2015
$time->month; // 12
$time->day; // 31
$time->hour // 23
$time->minute // 59
$time->second // 58
$time->micro // 123
Other properties that can be accessed are:
- timezone
- timezoneName
- dayOfWeek
- dayOfMonth
- dayOfYear
- daysInMonth
- timestamp
- quarter
- half
Testing Aids
------------
When writing unit tests, it is helpful to fixate the current time. Chronos lets
you fix the current time for each class. As part of your test suite's bootstrap
process you can include the following::
Chronos::setTestNow(Chronos::now());
ChronosDate::setTestNow(ChronosDate::parse(Chronos::now()));
This will fix the current time of all objects to be the point at which the test
suite started.
For example, if you fixate the ``Chronos`` to some moment in the past, any new
instance of ``Chronos`` created with ``now`` or a relative time string, will be
returned relative to the fixated time::
Chronos::setTestNow(new Chronos('1975-12-25 00:00:00'));
$time = new Chronos(); // 1975-12-25 00:00:00
$time = new Chronos('1 hour ago'); // 1975-12-24 23:00:00
To reset the fixation, simply call ``setTestNow()`` again with no parameter or
with ``null`` as a parameter.
+9
View File
@@ -0,0 +1,9 @@
import sys, os
# Append the top level directory of the docs, so we can import from the config dir.
sys.path.insert(0, os.path.abspath('..'))
# Pull in all the configuration options defined in the global config file..
from config.all import *
language = 'fr'
+7
View File
@@ -0,0 +1,7 @@
.. toctree::
:maxdepth: 2
:caption: CakePHP Chronos
/index
API <https://api.cakephp.org/chronos>
+329
View File
@@ -0,0 +1,329 @@
Chronos
#######
Chronos fournit une collection d'extensions sans aucune dépendance pour l'objet
``DateTime``. En plus de méthodes pratiques, Chronos fournit:
* Des objets ``Date`` pour représenter les dates du calendrier.
* Des objets immutables pour les dates et les datetimes.
* Un système de traduction intégrable. Seules les traductions anglaises sont
incluses dans la librairie. Cependant, ``cakephp/i18n`` peut être utilisé
pour un support complet d'autres langues.
Installation
------------
Pour installer Chronos, vous devez utiliser ``composer``. À partir du répertoire
ROOT de votre application (celui où se trouve le fichier composer.json),
exécutez ce qui suit::
php composer.phar require "cakephp/chronos:^2.0"
Vue d'Ensemble
--------------
Chronos fournit un certain nombre d'extensions pour les objets DateTime fournis
par PHP. Chronos fournit 5 classes qui gèrent les variantes mutables et
immutables de date/time et les extensions de ``DateInterval``.
* ``Cake\Chronos\Chronos`` est un objet de *date et heure* immutable.
* ``Cake\Chronos\ChronosDate`` est un objet de *date* immutable.
* ``Cake\Chronos\MutableDateTime`` est un objet de *date et heure* mutable.
* ``Cake\Chronos\MutableDate`` est un objet de *date* mutable.
* ``Cake\Chronos\ChronosInterval`` est une extension pour l'objet
``DateInterval``.
Créer des Instances
-------------------
Il y a plusieurs façons d'obtenir une instance de Chronos ou de Date. Il y a
un certain nombre de méthodes factory qui fonctionnent avec différents ensembles
d'arguments::
use Cake\Chronos\Chronos;
$now = Chronos::now();
$today = Chronos::today();
$yesterday = Chronos::yesterday();
$tomorrow = Chronos::tomorrow();
// Parse les expressions relatives
$date = Chronos::parse('+2 days, +3 hours');
// Des entiers indiquant la date et l'heure.
$date = Chronos::create(2015, 12, 25, 4, 32, 58);
// Des entiers indiquant la date ou l'heure.
$date = Chronos::createFromDate(2015, 12, 25);
$date = Chronos::createFromTime(11, 45, 10);
// Parse les valeurs formatées.
$date = Chronos::createFromFormat('m/d/Y', '06/15/2015');
Travailler avec les Objets Immutables
-------------------------------------
Si vous avez utilisé les objets ``DateTime`` de PHP, vous êtes à l'aise avec
les objets *mutable*. Chronos offre des objets mutables, mais elle fournit
également des objets *immutables*. Les objets Immutables créent des copies des
objets à chaque fois qu'un objet est modifié. Puisque les méthodes de
modification autour des datetimes ne sont pas toujours transparentes, les
données peuvent être modifiées accidentellement ou sans que le développeur ne
le sache. Les objets immutables évitent les changements accidentels des
données et permettent de s'affranchir de tout problème lié à l'ordre d'appel
des fonctions ou des dépendances. L'immutabilité signifie que vous devez vous
souvenir de remplacer les variables quand vous utilisez les modificateurs::
// Ce code ne fonctionne pas avec les objets immutables
$time->addDay(1);
doSomething($time);
return $time;
// Ceci fonctionne comme vous le souhaitez
$time = $time->addDay(1);
$time = doSomething($time);
return $time;
En capturant la valeur de retour pour chaque modification, votre code
fonctionnera comme souhaité. Si vous avez déjà créé un objet immutable, et que
vous souhaitez un objet mutable, vous pouvez utiliser ``toMutable()``::
$inplace = $time->toMutable();
Objets Date
-----------
PHP fournit seulement un unique objet DateTime. Représenter les dates de
calendrier peut être un peu gênant avec cette classe puisqu'elle inclut les
timezones, et les composants de time qui n'appartiennent pas vraiment
au concept d'un 'jour'. Chronos fournit un objet ``Date`` qui vous permet
de représenter les dates. Les time et timezone pour ces objets sont toujours
fixés à ``00:00:00 UTC`` et toutes les méthodes de formatage/différence
fonctionnent au niveau du jour::
use Cake\Chronos\ChronosDate;
$today = ChronosDate::today();
// Les changements selon le time/timezone sont ignorés.
$today->modify('+1 hours');
// Affiche '2015-12-20'
echo $today;
Bien que ``Date`` utilise en interne un fuseau horaire fixe, vous pouvez
spécifier le fuseau à utiliser pour l'heure courante telle que ``now()`` ou
``today()``::
use Cake\Chronos\ChronosDate:
// Prend l'heure courante pour le fuseau horaire de Tokyo
$today = ChronosDate::today('Asia/Tokyo');
Méthodes de Modification
------------------------
Les objets Chronos fournissent des méthodes de modification qui vous laissent
modifier la valeur d'une façon assez précise::
// Définit les composants de la valeur du datetime.
$halloween = Chronos::create()
->year(2015)
->month(10)
->day(31)
->hour(20)
->minute(30);
Vous pouvez aussi modifier les parties de la date de façon relative::
$future = Chronos::create()
->addYear(1)
->subMonth(2)
->addDays(15)
->addHours(20)
->subMinutes(2);
Il est également possible de faire des sauts vers des points définis dans le
temps::
$time = Chronos::create();
$time->startOfDay();
$time->endOfDay();
$time->startOfMonth();
$time->endOfMonth();
$time->startOfYear();
$time->endOfYear();
$time->startOfWeek();
$time->endOfWeek();
Ou de sauter à un jour spécifique de la semaine::
$time->next(Chronos::TUESDAY);
$time->previous(Chronos::MONDAY);
Quand vous modifiez des dates/heures au-delà d'un passage à l'heure d'été ou à
l'heure d'hiver, vous opérations peuvent gagner/perdre une heure de plus, de
sorte que les heures seront incorrectes. Vous pouvez éviter ce problème en
définissant d'abord le timezone à ``UTC``, ce qui change l'heure::
// Une heure de plus de gagnée.
$time = new Chronos('2014-03-30 00:00:00', 'Europe/London');
debug($time->modify('+24 hours')); // 2014-03-31 01:00:00
// Passez d'abord à UTC, et modifiez ensuite
$time = $time->setTimezone('UTC')
->modify('+24 hours');
Une fois que vous avez modifié l'heure, vous pouvez repasser au timezone
d'origine pour obtenir l'heure locale.
Méthodes de Comparaison
-----------------------
Une fois que vous avez 2 instances d'objets date/time de Chronos, vous pouvez
les comparer de plusieurs façons::
// Il existe une suite complète de comparateurs
// equals, notEquals, greaterThan, greaterThanOrEquals, lessThan, lessThanOrEquals
$first->equals($second);
$first->greaterThanOrEquals($second);
// Regarder si l'objet courant est entre deux autres.
$now->between($start, $end);
// Trouver l'argument le plus proche ou le plus éloigné.
$now->closest($june, $november);
$now->farthest($june, $november);
Vous pouvez aussi vous renseigner sur le moment où une valeur donnée tombe dans
le calendrier::
$now->isToday();
$now->isYesterday();
$now->isFuture();
$now->isPast();
// Vérifie le jour de la semaine
$now->isWeekend();
// Toutes les autres méthodes des jours de la semaine existent aussi.
$now->isMonday();
Vous pouvez aussi trouver si une valeur était dans une période de temps relative::
$time->wasWithinLast('3 days');
$time->isWithinNext('3 hours');
Générer des Différences
-----------------------
En plus de comparer les datetimes, calculer les différences ou les deltas entre
des valeurs est une tâche courante::
// Récupère un DateInterval représentant la différence
$first->diff($second);
// Récupère la différence en tant que nombre d'unités spécifiques.
$first->diffInHours($second);
$first->diffInDays($second);
$first->diffInWeeks($second);
$first->diffInYears($second);
Vous pouvez générer des différences lisibles qui peuvent vous servir pour
l'utilisation d'un feed ou d'une timeline::
// Différence à partir de maintenant.
echo $date->diffForHumans();
// Différence à partir d'un autre point du temps.
echo $date->diffForHumans($other); // 1 hour ago;
Formater les Chaînes
--------------------
Chronos fournit un certain nombre de méthodes pour afficher nos sorties d'objets
datetime::
// Utilise le format contrôlé par setToStringFormat()
echo $date;
// Différents formats standards
echo $time->toAtomString(); // 1975-12-25T14:15:16-05:00
echo $time->toCookieString(); // Thursday, 25-Dec-1975 14:15:16 EST
echo $time->toIso8601String(); // 1975-12-25T14:15:16-05:00
echo $time->toRfc822String(); // Thu, 25 Dec 75 14:15:16 -0500
echo $time->toRfc850String(); // Thursday, 25-Dec-75 14:15:16 EST
echo $time->toRfc1036String(); // Thu, 25 Dec 75 14:15:16 -0500
echo $time->toRfc1123String(); // Thu, 25 Dec 1975 14:15:16 -0500
echo $time->toRfc2822String(); // Thu, 25 Dec 1975 14:15:16 -0500
echo $time->toRfc3339String(); // 1975-12-25T14:15:16-05:00
echo $time->toRssString(); // Thu, 25 Dec 1975 14:15:16 -0500
echo $time->toW3cString(); // 1975-12-25T14:15:16-05:00
// Récupère le trimestre
echo $time->toQuarter(); // 4;
// Récupère la semaine
echo $time->toWeek(); // 52;
// Formatage générique
echo $time->toTimeString(); // 14:15:16
echo $time->toDateString(); // 1975-12-25
echo $time->toDateTimeString(); // 1975-12-25 14:15:16
echo $time->toFormattedDateString(); // Dec 25, 1975
echo $time->toDayDateTimeString(); // Thu, Dec 25, 1975 2:15 PM
Extraire des Fragments de Date
------------------------------
Il est possible de récupérer des parties d'un objet date en accédant directement
à ses propriétés::
$time = new Chronos('2015-12-31 23:59:58.123');
$time->year; // 2015
$time->month; // 12
$time->day; // 31
$time->hour // 23
$time->minute // 59
$time->second // 58
$time->micro // 123
Les autres propriétés accessibles sont:
- timezone
- timezoneName
- dayOfWeek
- dayOfMonth
- dayOfYear
- daysInMonth
- timestamp
- quarter
- half
Aides aux Tests
---------------
Quand vous écrivez des tests unitaires, il peut être utile de fixer le *time*
courant. Chronos vous permet de fixer le time courant pour chaque classe.
Pour l'intégrer dans votre processus de démarrage (bootstrap) de suite de tests,
vous pouvez inclure ce qui suit::
Chronos::setTestNow(Chronos::now());
MutableDateTime::setTestNow(MutableDateTime::now());
ChronosDate::setTestNow(ChronosDate::parse(Chronos::now()));
MutableDate::setTestNow(MutableDate::now());
Ceci va fixer le time courant de tous les objets selon le moment où la suite de
tests a démarré.
Par exemple, si vous fixez le ``Chronos`` à un moment du passé, chaque nouvelle
instance de ``Chronos`` créée avec ``now`` ou une chaine de temps relative, sera
retournée relativement à la date fixée::
Chronos::setTestNow(new Chronos('1975-12-25 00:00:00'));
$time = new Chronos(); // 1975-12-25 00:00:00
$time = new Chronos('1 hour ago'); // 1975-12-24 23:00:00
Pour réinitialiser la "fixation" du temps, appelez simplement ``setTestNow()``
sans paramètre ou avec ``null`` comme paramètre.
+9
View File
@@ -0,0 +1,9 @@
import sys, os
# Append the top level directory of the docs, so we can import from the config dir.
sys.path.insert(0, os.path.abspath('..'))
# Pull in all the configuration options defined in the global config file..
from config.all import *
language = 'ja'
+7
View File
@@ -0,0 +1,7 @@
.. toctree::
:maxdepth: 2
:caption: CakePHP Chronos
/index
API <https://api.cakephp.org/chronos>
+301
View File
@@ -0,0 +1,301 @@
Chronos
#######
Chronos (クロノス) は、 ``DateTime`` オブジェクトへの拡張の依存関係の無いコレクションを提供します。
便利なメソッドに加えて、Chronos は以下を提供します。
* カレンダー日付のための ``Date`` オブジェクト
* イミュータブルな日付と日時オブジェクト
* プラグインのような翻訳システム。ライブラリーは英語のみの翻訳を含んでいます。
しかし、全ての言語サポートのために、 ``cakephp/i18n`` を使うことができます。
インストール
------------
Chronos をインストールするためには、 ``composer`` を利用することができます。
アプリケーションの ROOT ディレクトリー(composer.json ファイルのある場所)
で以下のように実行します。 ::
php composer.phar require cakephp/chronos "@stable"
概要
----
Chronos は PHP が提供する DateTime オブジェクトのいくつかの拡張を提供します。
Chronos は ``DateInterval`` の拡張機能および、ミュータブル(変更可能)と
イミュータブル(変更不可)な 日付/時刻 の派生系をカバーする5つのクラスを提供します。
* ``Cake\Chronos\Chronos`` はイミュータブルな *日付と時刻* オブジェクト。
* ``Cake\Chronos\ChronosDate`` はイミュータブルな *日付* オブジェクト。
* ``Cake\Chronos\MutableDateTime`` はミュータブルな *日付と時刻* オブジェクト。
* ``Cake\Chronos\MutableDate`` はミュータブルな *日付* オブジェクト。
* ``Cake\Chronos\ChronosInterval````DateInterval`` の拡張機能。
インスタンスの作成
------------------
Chronos または Date のインスタンスを取得するためには、多くの方法があります。
異なる引数セットで動作する多くのファクトリーメソッドがあります。 ::
use Cake\Chronos\Chronos;
$now = Chronos::now();
$today = Chronos::today();
$yesterday = Chronos::yesterday();
$tomorrow = Chronos::tomorrow();
// 相対式のパース
$date = Chronos::parse('+2 days, +3 hours');
// 日付と時間の整数値
$date = Chronos::create(2015, 12, 25, 4, 32, 58);
// 日付または時間の整数値
$date = Chronos::createFromDate(2015, 12, 25);
$date = Chronos::createFromTime(11, 45, 10);
// 整形した値にパース
$date = Chronos::createFromFormat('m/d/Y', '06/15/2015');
イミュータブルオブジェクトの動作
--------------------------------
もしあなたが、PHP の ``DateTime`` オブジェクトを使用したことがあるなら、
*ミュータブル* オブジェクトは簡単に使用できます。
Chronos はミュータブルオブジェクトを提供しますが、これは *イミュータブル* オブジェクトにもなります。
イミュータブルオブジェクトはオブジェクトが変更されるたびにオブジェクトのコピーを作ります。
なぜなら、日時周りの変更メソッドは必ずしも透明でないため、データが誤って、
または開発者が知らない内に変更してしまうからです。
イミュータブルオブジェクトはデータが誤って変更されることを防止し、
順序ベースの依存関係の問題の無いコードを作ります。
不変性は、変更時に忘れずに変数を置き換える必要があることを意味しています。 ::
// このコードはイミュータブルオブジェクトでは動作しません
$time->addDay(1);
doSomething($time);
return $time
// このコードは期待通りに動作します
$time = $time->addDay(1);
$time = doSomething($time);
return $time
各修正の戻り値をキャプチャーすることによって、コードは期待通りに動作します。
イミュータブルオブジェクトを持っていて、ミュータブルオブジェクトを作りたい場合、
``toMutable()`` が使用できます。 ::
$inplace = $time->toMutable();
日付オブジェクト
------------------
PHP は単純な DateTime オブジェクトだけを提供します。このクラスのカレンダー日付の表現で、
タイムゾーンおよび、本当に「日」の概念に属していないタイムコンポーネントを含むと、
少し厄介な可能性があります。
Chronos は日時表現のための ``Date`` オブジェクトを提供します。
これらのオブジェクトの時間とタイムゾーンは常に ``00:00:00 UTC`` に固定されており、
全ての書式/差分のメソッドは一日単位で動作します。 ::
use Cake\Chronos\ChronosDate;
$today = ChronosDate::today();
// 時間/タイムゾーンの変更は無視されます
$today->modify('+1 hours');
// 出力 '2015-12-20'
echo $today;
変更メソッド
------------
Chronos オブジェクトは細やかに値を変更できるメソッドを提供します。 ::
// 日時の値のコンポーネントを設定
$halloween = Chronos::create()
->year(2015)
->month(10)
->day(31)
->hour(20)
->minute(30);
また、日時の部分を相対的に変更することもできます。 ::
$future = Chronos::create()
->addYear(1)
->subMonth(2)
->addDays(15)
->addHours(20)
->subMinutes(2);
また、ある時間の中で、定義された時点に飛ぶことも可能です。 ::
$time = Chronos::create();
$time->startOfDay();
$time->endOfDay();
$time->startOfMonth();
$time->endOfMonth();
$time->startOfYear();
$time->endOfYear();
$time->startOfWeek();
$time->endOfWeek();
また、1週間中の特定の日にも飛べます。 ::
$time->next(Chronos::TUESDAY);
$time->previous(Chronos::MONDAY);
:abbr:`DST (夏時間)` の遷移の前後で日付/時間を変更すると、
あなたの操作で時間が増減するかもしれませんが、その結果、意図しない時間の値になります。
これらの問題を回避するには、最初にタイムゾーンを ``UTC`` に変更し、時間を変更します。 ::
// 余分な時間が追加されました
$time = new Chronos('2014-03-30 00:00:00', 'Europe/London');
debug($time->modify('+24 hours')); // 2014-03-31 01:00:00
// 最初に UTC に切り替え、そして更新
$time = $time->setTimezone('UTC')
->modify('+24 hours');
時間を変更すると、元のタイムゾーンを追加してローカライズされた時間を取得することができます。
比較メソッド
------------
Chronos の日付/時間オブジェクトの2つのインスタンスを様々な方法で比較することができます。 ::
// 比較のフルセットが存在します
// equals, notEquals, greaterThan, greaterThanOrEquals, lessThan, lessThanOrEquals
$first->equals($second);
$first->greaterThanOrEquals($second);
// カレントオブジェクトが2つのオブジェクトの間にあるかどうかを確認します。
$now->between($start, $end);
// どちらの引数が最も近い (closest) か、または最も遠い (farthest) かを見つけます。
$now->closest($june, $november);
$now->farthest($june, $november);
また、与えられた値のカレンダーに当たる場所について問い合わせできます。 ::
$now->isToday();
$now->isYesterday();
$now->isFuture();
$now->isPast();
// 曜日をチェック
$now->isWeekend();
// 他の曜日のメソッドも全て存在します。
$now->isMonday();
また、値が相対的な期間内にあったかどうかを見つけることができます。 ::
$time->wasWithinLast('3 days');
$time->isWithinNext('3 hours');
差の生成
--------
日時比較に加えて、2つの値の差や変化の計算は一般的なタスクです。 ::
// 差をあらわす DateInterval を取得
$first->diff($second);
// 特定の単位での差を取得
$first->diffInHours($second);
$first->diffInDays($second);
$first->diffInWeeks($second);
$first->diffInYears($second);
フィードやタイムラインで使用するのに適した、人が読める形式の差を生成することができます。 ::
// 現在からの差
echo $date->diffForHumans();
// 別の時点からの差
echo $date->diffForHumans($other); // 1時間前;
フォーマットの設定
------------------
Chronos は、出力した日時オブジェクトを表示するための多くのメソッドを提供します。 ::
// setToStringFormat() が制御するフォーマットを使用します
echo $date;
// 別の標準フォーマット
echo $time->toAtomString(); // 1975-12-25T14:15:16-05:00
echo $time->toCookieString(); // Thursday, 25-Dec-1975 14:15:16 EST
echo $time->toIso8601String(); // 1975-12-25T14:15:16-05:00
echo $time->toRfc822String(); // Thu, 25 Dec 75 14:15:16 -0500
echo $time->toRfc850String(); // Thursday, 25-Dec-75 14:15:16 EST
echo $time->toRfc1036String(); // Thu, 25 Dec 75 14:15:16 -0500
echo $time->toRfc1123String(); // Thu, 25 Dec 1975 14:15:16 -0500
echo $time->toRfc2822String(); // Thu, 25 Dec 1975 14:15:16 -0500
echo $time->toRfc3339String(); // 1975-12-25T14:15:16-05:00
echo $time->toRssString(); // Thu, 25 Dec 1975 14:15:16 -0500
echo $time->toW3cString(); // 1975-12-25T14:15:16-05:00
// クォーター/週数を取得
echo $time->toQuarter(); // 4;
echo $time->toWeek(); // 52
// 一般的なフォーマット
echo $time->toTimeString(); // 14:15:16
echo $time->toDateString(); // 1975-12-25
echo $time->toDateTimeString(); // 1975-12-25 14:15:16
echo $time->toFormattedDateString(); // Dec 25, 1975
echo $time->toDayDateTimeString(); // Thu, Dec 25, 1975 2:15 PM
日付要素の抽出
--------------
日付オブジェクトのプロパティーに直接アクセスして要素を取得することができます。 ::
$time = new Chronos('2015-12-31 23:59:58');
$time->year; // 2015
$time->month; // 12
$time->day; // 31
$time->hour // 23
$time->minute // 59
$time->second // 58
以下のプロパティーにもアクセスできます。 :
- timezone
- timezoneName
- micro
- dayOfWeek
- dayOfMonth
- dayOfYear
- daysInMonth
- timestamp
- quarter
- half
テストの支援
------------
単体テストを書いている時、現在時刻を固定すると便利です。Chronos は、
各クラスの現在時刻を修正することができます。
テストスイートの bootstrap 処理に以下を含めることができます。 ::
Chronos::setTestNow(Chronos::now());
MutableDateTime::setTestNow(MutableDateTime::now());
ChronosDate::setTestNow(ChronosDate::parse(Chronos::now()));
MutableDate::setTestNow(MutableDate::now());
これでテストスイートが開始された時点で全てのオブジェクトの現在時刻を修正します。
例えば、 ``Chronos`` を過去のある瞬間に固定した場合、新たな ``Chronos``
のインスタンスが生成する ``now`` または相対時刻の文字列は、
固定された時刻の相対を返却します。 ::
Chronos::setTestNow(new Chronos('1975-12-25 00:00:00'));
$time = new Chronos(); // 1975-12-25 00:00:00
$time = new Chronos('1 hour ago'); // 1975-12-24 23:00:00
固定をリセットするには、 ``setTestNow()`` をパラメーター無し、または ``null`` を設定して
再び呼び出してください。
+9
View File
@@ -0,0 +1,9 @@
import sys, os
# Append the top level directory of the docs, so we can import from the config dir.
sys.path.insert(0, os.path.abspath('..'))
# Pull in all the configuration options defined in the global config file..
from config.all import *
language = 'pt'
+7
View File
@@ -0,0 +1,7 @@
.. toctree::
:maxdepth: 2
:caption: CakePHP Chronos
/index
API <https://api.cakephp.org/chronos>
+282
View File
@@ -0,0 +1,282 @@
Chronos
#######
O Chronos oferece uma coleção independente de extensões para lidar com o objeto
``DateTime``. Além de métodos de conveniência, o Chronos oferece:
* Objetos ``Date`` para representar datas de calendário.
* Objetos *date* e *datetime* imutáveis.
* Um sistema de tradução acoplável. Apenas traduções em inglês estão incluídas
na biblioteca. Todavia, ``cakephp/i18n`` pode ser usado para suporte completo
a idiomas.
Instalação
----------
Para instalar o Chronos, você deve usar o ``composer``. A partir do diretório
*ROOT* de sua aplicação (local onde o arquivo composer.json está localizado)
execute o seguinte comando::
php composer.phar require cakephp/chronos "@stable"
Visão geral
-----------
Chronos oferece extensões para lidar com objetos *DateTime* do PHP. 5 classes
cobrem variantes de data/hora mutáveis e imutáveis e uma extensão do objeto
``DateInterval``.
* ``Cake\Chronos\Chronos`` é um objeto *date & time* imutável.
* ``Cake\Chronos\ChronosDate`` é um objeto *date* imutável.
* ``Cake\Chronos\MutableDateTime`` é um objeto *date and time* mutável.
* ``Cake\Chronos\MutableDate`` é um objeto *date* mutável.
* ``Cake\Chronos\ChronosInterval`` é uma extensão do objeto ``DateInterval``.
Criando instâncias
------------------
Existem várias maneiras de criar instâncias do Chronos ou mesmo, do objeto Date.
Um número considerável de métodos padrão que funcionam com conjuntos diferentes
de argumentos::
use Cake\Chronos\Chronos;
$now = Chronos::now();
$today = Chronos::today();
$yesterday = Chronos::yesterday();
$tomorrow = Chronos::tomorrow();
// Interpreta expressões relativas.
$date = Chronos::parse('+2 days, +3 hours');
// Valores inteiros de Date e Time.
$date = Chronos::create(2015, 12, 25, 4, 32, 58);
// Valores inteiros de Date ou Time.
$date = Chronos::createFromDate(2015, 12, 25);
$date = Chronos::createFromTime(11, 45, 10);
// Interpreta valores formatados.
$date = Chronos::createFromFormat('m/d/Y', '06/15/2015');
Trabalhando com objetos imutáveis
---------------------------------
Se você é familiarizado com os objetos ``DateTime`` do PHP, você se sentirá
confortável com objetos *mutáveis*. Além de objetos mutáveis o Chronos também
oferece objetos imutáveis que por sua vez criam cópias de objetos toda vez que
um objeto é modificado. Devido ao fato de que metodos modificadores relativos
a data e hora nem sempre serem transparentes, informações podem ser modificadas
acidentalmente ou sem que o desenvolvedor saiba. Objetos imutáveis previnem
essas alterações acidentais nos dados. Imutabilidade significa que você deverá
lembrar de substituir variáveis usando modificadores::
// Esse código não funciona com objetos imutáveis
$time->addDay(1);
doSomething($time);
return $time;
// Esse funciona como o esperado
$time = $time->addDay(1);
$time = doSomething($time);
return $time;
Ao capturar o valor de retorno de cada modificação, seu código funcionará como o
esperado. Se você tem um objeto imutável e quer criar um mutável a partir do
mesmo, use ``toMutable()``::
$inplace = $time->toMutable();
Objetos Date
------------
O PHP disponibiliza um único objeto DateTime. Representar datas de calendário
pode ser um pouco desconfortável por essa classe, uma vez que ela inclui
*timezones* e componentes de hora que realmente não se encaixam no conceito de
'dia'. O Chronos oferece um objeto ``Date`` para representar datas. A hora e a
zona desse objeto é sempre fixado em ``00:00:00 UTC`` e todos os métodos de
formatação/diferença operam sob a resolução de dia::
use Cake\Chronos\ChronosDate;
$today = ChronosDate::today();
// Mudanças na hora/timezone são ignoradas
$today->modify('+1 hours');
// Exibe '2016-08-15'
echo $today;
Métodos modificadores
---------------------
Objetos Chronos disponibilizam métodos que permitem a modificação de valores de
forma granular::
// Define componentes do valor datetime
$halloween = Chronos::create()
->year(2015)
->month(10)
->day(31)
->hour(20)
->minute(30);
Você também pode modificar partes da data relativamente::
$future = Chronos::create()
->addYear(1)
->subMonth(2)
->addDays(15)
->addHours(20)
->subMinutes(2);
Também é possível realizar grandes saltos para períodos definidos no tempo::
$time = Chronos::create();
$time->startOfDay();
$time->startOfMonth();
$time->endOfMonth();
$time->endOfYear();
$time->startOfWeek();
$time->endOfWeek();
Ou ainda para dias específicos da semana::
$time->next(Chronos::TUESDAY);
$time->previous(Chronos::MONDAY);
Métodos de comparação
---------------------
Uma vez que você possui 2 instâncias de objetos data/hora do Chronos, é possível
compará-los de várias maneiras::
// Coleção completa de comparadores
// equals, notEquals, greaterThan, greaterThanOrEquals, lessThan, lessThanOrEquals
$first->equals($second);
$first->greaterThanOrEquals($second);
// Veja se o objeto atual está entre outros
$now->between($start, $end);
// Encontre qual argumento está mais perto ou mais longe
$now->closest($june, $november);
$now->farthest($june, $november);
Você também pode arguir sobre quando um determinado valor cai no calendário::
$now->isToday();
$now->isYesterday();
$now->isFuture();
$now->isPast();
// Verifica se o dia é no final de semana
$now->isWeekend();
// Todos os métodos para outros dias da semana existem também
$now->isMonday();
Você também pode verificar se um determinado valor está dentro de um período de
tempo relativo::
$time->wasWithinLast('3 days');
$time->isWithinNext('3 hours');
Gerando diferenças
------------------
Em adição à comparação de *datetimes*, calcular diferenças ou deltas entre
valores é uma tarefa simples::
// Recebe um DateInterval representando a diferença
$first->diff($second);
// Recebe a diferença como um contador de unidades específicas
$first->diffInHours($second);
$first->diffInDays($second);
$first->diffInWeeks($second);
$first->diffInYears($second);
Você pode gerar diferenças de fácil leitura para humanos para usar em um *feed*
ou *timeline*::
// Diferença em relação ao momento atual
echo $date->diffForHumans();
// Diferença em relação a outro período no tempo
echo $date->diffForHumans($other); // 1 hora atrás;
Formatando strings
------------------
O Chronos disponibiliza métodos para exibir nossos objetos *datetime*::
// Usa o formato controlado por setToStringFormat()
echo $date;
// Diferentes padrões de formato
echo $time->toAtomString(); // 1975-12-25T14:15:16-05:00
echo $time->toCookieString(); // Thursday, 25-Dec-1975 14:15:16 EST
echo $time->toIso8601String(); // 1975-12-25T14:15:16-05:00
echo $time->toRfc822String(); // Thu, 25 Dec 75 14:15:16 -0500
echo $time->toRfc850String(); // Thursday, 25-Dec-75 14:15:16 EST
echo $time->toRfc1036String(); // Thu, 25 Dec 75 14:15:16 -0500
echo $time->toRfc1123String(); // Thu, 25 Dec 1975 14:15:16 -0500
echo $time->toRfc2822String(); // Thu, 25 Dec 1975 14:15:16 -0500
echo $time->toRfc3339String(); // 1975-12-25T14:15:16-05:00
echo $time->toRssString(); // Thu, 25 Dec 1975 14:15:16 -0500
echo $time->toW3cString(); // 1975-12-25T14:15:16-05:00
// Recebe o trimestre
echo $time->toQuarter(); // 4;
Extraindo componentes de data
-----------------------------
Podemos receber partes de um objeto *date* acessando propriedades::
$time = new Chronos('2015-12-31 23:59:58');
$time->year; // 2015
$time->month; // 12
$time->day; // 31
$time->hour // 23
$time->minute // 59
$time->second // 58
Outras propriedades que podem ser acessadas são:
- timezone
- timezoneName
- micro
- dayOfWeek
- dayOfMonth
- dayOfYear
- daysInMonth
- timestamp
- quarter
- half
Auxílio para testes
-------------------
Ao escrever testes unitários, fixar a hora atual é bastante útil. O Chronos
lhe permite fixar a hora atual para cada classe. Como parte das suas ferramentas
de testes, você pode incluir o seguinte::
Chronos::setTestNow(Chronos::now());
MutableDateTime::setTestNow(MutableDateTime::now());
ChronosDate::setTestNow(ChronosDate::parse(Chronos::now()));
MutableDate::setTestNow(MutableDate::now());
Isso irá corrigir a hora atual de todos os objetos para o momento em que o
processo de testes foi iniciado.
Por exemplo, se você fixar o ``Chronos`` em algum momento no passado, qualquer
nova instância do ``Chronos`` criada com ``now`` ou uma *string* de tempo
relativa, teremos um retorno referente ao tempo fixado::
Chronos::setTestNow(new Chronos('1975-12-25 00:00:00'));
$time = new Chronos(); // 1975-12-25 00:00:00
$time = new Chronos('1 hour ago'); // 1975-12-24 23:00:00
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+83
View File
@@ -0,0 +1,83 @@
<?php
declare(strict_types=1);
/**
* Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
* @link https://cakephp.org CakePHP(tm) Project
* @license https://www.opensource.org/licenses/mit-license.php MIT License
*/
namespace Cake\Chronos;
use DatePeriod;
use Iterator;
/**
* DatePeriod wrapper that returns Chronos instances.
*
* @template TKey int
* @template TValue \Cake\Chronos\ChronosDate
* @template-implements \Iterator<int, \Cake\Chronos\ChronosDate>
*/
class ChronosDatePeriod implements Iterator
{
/**
* @var \Iterator<int, \DateTimeInterface>
*/
protected Iterator $iterator;
/**
* @param \DatePeriod $period
*/
public function __construct(DatePeriod $period)
{
/** @var \Iterator<int, \DateTimeInterface> $iterator */
$iterator = $period->getIterator();
$this->iterator = $iterator;
}
/**
* @return \Cake\Chronos\ChronosDate
*/
public function current(): ChronosDate
{
return new ChronosDate($this->iterator->current());
}
/**
* @return int
*/
public function key(): int
{
return $this->iterator->key();
}
/**
* @return void
*/
public function next(): void
{
$this->iterator->next();
}
/**
* @return void
*/
public function rewind(): void
{
$this->iterator->rewind();
}
/**
* @return bool
*/
public function valid(): bool
{
return $this->iterator->valid();
}
}
+83
View File
@@ -0,0 +1,83 @@
<?php
declare(strict_types=1);
/**
* Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
* @link https://cakephp.org CakePHP(tm) Project
* @license https://www.opensource.org/licenses/mit-license.php MIT License
*/
namespace Cake\Chronos;
use DatePeriod;
use Iterator;
/**
* DatePeriod wrapper that returns Chronos instances.
*
* @template TKey int
* @template TValue \Cake\Chronos\Chronos
* @template-implements \Iterator<int, \Cake\Chronos\Chronos>
*/
class ChronosPeriod implements Iterator
{
/**
* @var \Iterator<int, \DateTimeInterface>
*/
protected Iterator $iterator;
/**
* @param \DatePeriod $period
*/
public function __construct(DatePeriod $period)
{
/** @var \Iterator<int, \DateTimeInterface> $iterator */
$iterator = $period->getIterator();
$this->iterator = $iterator;
}
/**
* @return \Cake\Chronos\Chronos
*/
public function current(): Chronos
{
return new Chronos($this->iterator->current());
}
/**
* @return int
*/
public function key(): int
{
return $this->iterator->key();
}
/**
* @return void
*/
public function next(): void
{
$this->iterator->next();
}
/**
* @return void
*/
public function rewind(): void
{
$this->iterator->rewind();
}
/**
* @return bool
*/
public function valid(): bool
{
return $this->iterator->valid();
}
}
+493
View File
@@ -0,0 +1,493 @@
<?php
declare(strict_types=1);
/**
* Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
* @link https://cakephp.org CakePHP(tm) Project
* @license https://www.opensource.org/licenses/mit-license.php MIT License
*/
namespace Cake\Chronos;
use DateTimeImmutable;
use DateTimeInterface;
use DateTimeZone;
use InvalidArgumentException;
use Stringable;
/**
* @phpstan-consistent-constructor
*/
class ChronosTime implements Stringable
{
/**
* @var int
*/
protected const TICKS_PER_MICROSECOND = 1;
/**
* @var int
*/
protected const TICKS_PER_SECOND = 1000000;
/**
* @var int
*/
protected const TICKS_PER_MINUTE = self::TICKS_PER_SECOND * 60;
/**
* @var int
*/
protected const TICKS_PER_HOUR = self::TICKS_PER_MINUTE * 60;
/**
* @var int
*/
protected const TICKS_PER_DAY = self::TICKS_PER_HOUR * 24;
/**
* Default format to use for __toString method.
*
* @var string
*/
public const DEFAULT_TO_STRING_FORMAT = 'H:i:s';
/**
* Format to use for __toString method.
*
* @var string
*/
protected static string $toStringFormat = self::DEFAULT_TO_STRING_FORMAT;
/**
* @var int
*/
protected int $ticks;
/**
* Copies time from onther instance or from time string in the format HH[:.]mm or HH[:.]mm[:.]ss.u.
*
* Defaults to server time.
*
* @param \Cake\Chronos\ChronosTime|\DateTimeInterface|string|null $time Time
* @param \DateTimeZone|string|null $timezone The timezone to use for now
*/
public function __construct(
ChronosTime|DateTimeInterface|string|null $time = null,
DateTimeZone|string|null $timezone = null,
) {
if ($time === null) {
$time = Chronos::getTestNow() ?? Chronos::now();
if ($timezone !== null) {
$time = $time->setTimezone($timezone);
}
$this->ticks = static::parseString($time->format('H:i:s.u'));
} elseif (is_string($time)) {
$this->ticks = static::parseString($time);
} elseif ($time instanceof ChronosTime) {
$this->ticks = $time->ticks;
} else {
$this->ticks = static::parseString($time->format('H:i:s.u'));
}
}
/**
* Copies time from onther instance or from string in the format HH[:.]mm or HH[:.]mm[:.]ss.u
*
* Defaults to server time.
*
* @param \Cake\Chronos\ChronosTime|\DateTimeInterface|string $time Time
* @param \DateTimeZone|string|null $timezone The timezone to use for now
* @return static
*/
public static function parse(
ChronosTime|DateTimeInterface|string|null $time = null,
DateTimeZone|string|null $timezone = null,
): static {
return new static($time, $timezone);
}
/**
* @param string $time Time string in the format HH[:.]mm or HH[:.]mm[:.]ss.u
* @return int
*/
protected static function parseString(string $time): int
{
if (!preg_match('/^\s*(\d{1,2})[:.](\d{1,2})(?|[:.](\d{1,2})[.](\d+)|[:.](\d{1,2}))?\s*$/', $time, $matches)) {
throw new InvalidArgumentException(
sprintf('Time string `%s` is not in expected format `HH[:.]mm` or `HH[:.]mm[:.]ss.u`.', $time),
);
}
$hours = (int)$matches[1];
$minutes = (int)$matches[2];
$seconds = (int)($matches[3] ?? 0);
$microseconds = (int)substr($matches[4] ?? '', 0, 6);
if ($hours > 24 || $minutes > 59 || $seconds > 59 || $microseconds > 999_999) {
throw new InvalidArgumentException(sprintf('Time string `%s` contains invalid values.', $time));
}
$ticks = $hours * self::TICKS_PER_HOUR;
$ticks += $minutes * self::TICKS_PER_MINUTE;
$ticks += $seconds * self::TICKS_PER_SECOND;
$ticks += $microseconds * self::TICKS_PER_MICROSECOND;
return $ticks % self::TICKS_PER_DAY;
}
/**
* Returns instance set to server time.
*
* @param \DateTimeZone|string|null $timezone The timezone to use for now
* @return static
*/
public static function now(DateTimeZone|string|null $timezone = null): static
{
return new static(null, $timezone);
}
/**
* Returns instance set to midnight.
*
* @return static
*/
public static function midnight(): static
{
return new static('00:00:00');
}
/**
* Returns instance set to noon.
*
* @return static
*/
public static function noon(): static
{
return new static('12:00:00');
}
/**
* Returns instance set to end of day - either
* 23:59:59 or 23:59:59.999999 if `$microseconds` is true
*
* @param bool $microseconds Whether to set microseconds or not
* @return static
*/
public static function endOfDay(bool $microseconds = false): static
{
if ($microseconds) {
return new static('23:59:59.999999');
}
return new static('23:59:59');
}
/**
* Returns clock microseconds.
*
* @return int
*/
public function getMicroseconds(): int
{
return intdiv($this->ticks % self::TICKS_PER_SECOND, self::TICKS_PER_MICROSECOND);
}
/**
* Sets clock microseconds.
*
* @param int $microseconds Clock microseconds
* @return static
*/
public function setMicroseconds(int $microseconds): static
{
$baseTicks = $this->ticks - $this->ticks % self::TICKS_PER_SECOND;
$newTicks = static::mod($baseTicks + $microseconds * self::TICKS_PER_MICROSECOND, self::TICKS_PER_DAY);
$clone = clone $this;
$clone->ticks = $newTicks;
return $clone;
}
/**
* Return clock seconds.
*
* @return int
*/
public function getSeconds(): int
{
$secondsTicks = $this->ticks % self::TICKS_PER_MINUTE - $this->ticks % self::TICKS_PER_SECOND;
return intdiv($secondsTicks, self::TICKS_PER_SECOND);
}
/**
* Set clock seconds.
*
* @param int $seconds Clock seconds
* @return static
*/
public function setSeconds(int $seconds): static
{
$baseTicks = $this->ticks - ($this->ticks % self::TICKS_PER_MINUTE - $this->ticks % self::TICKS_PER_SECOND);
$newTicks = static::mod($baseTicks + $seconds * self::TICKS_PER_SECOND, self::TICKS_PER_DAY);
$clone = clone $this;
$clone->ticks = $newTicks;
return $clone;
}
/**
* Returns clock minutes.
*
* @return int
*/
public function getMinutes(): int
{
$minutesTicks = $this->ticks % self::TICKS_PER_HOUR - $this->ticks % self::TICKS_PER_MINUTE;
return intdiv($minutesTicks, self::TICKS_PER_MINUTE);
}
/**
* Set clock minutes.
*
* @param int $minutes Clock minutes
* @return static
*/
public function setMinutes(int $minutes): static
{
$baseTicks = $this->ticks - ($this->ticks % self::TICKS_PER_HOUR - $this->ticks % self::TICKS_PER_MINUTE);
$newTicks = static::mod($baseTicks + $minutes * self::TICKS_PER_MINUTE, self::TICKS_PER_DAY);
$clone = clone $this;
$clone->ticks = $newTicks;
return $clone;
}
/**
* Returns clock hours.
*
* @return int
*/
public function getHours(): int
{
$hoursInTicks = $this->ticks - $this->ticks % self::TICKS_PER_HOUR;
return intdiv($hoursInTicks, self::TICKS_PER_HOUR);
}
/**
* Set clock hours.
*
* @param int $hours Clock hours
* @return static
*/
public function setHours(int $hours): static
{
$baseTicks = $this->ticks - ($this->ticks - $this->ticks % self::TICKS_PER_HOUR);
$newTicks = static::mod($baseTicks + $hours * self::TICKS_PER_HOUR, self::TICKS_PER_DAY);
$clone = clone $this;
$clone->ticks = $newTicks;
return $clone;
}
/**
* Sets clock time.
*
* @param int $hours Clock hours
* @param int $minutes Clock minutes
* @param int $seconds Clock seconds
* @param int $microseconds Clock microseconds
* @return static
*/
public function setTime(int $hours = 0, int $minutes = 0, int $seconds = 0, int $microseconds = 0): static
{
$ticks = $hours * self::TICKS_PER_HOUR +
$minutes * self::TICKS_PER_MINUTE +
$seconds * self::TICKS_PER_SECOND +
$microseconds * self::TICKS_PER_MICROSECOND;
$ticks = static::mod($ticks, self::TICKS_PER_DAY);
$clone = clone $this;
$clone->ticks = $ticks;
return $clone;
}
/**
* @param int $a Left side
* @param int $a Right side
* @return int
*/
protected static function mod(int $a, int $b): int
{
if ($a < 0) {
return $a % $b + $b;
}
return $a % $b;
}
/**
* Formats string using the same syntax as `DateTimeImmutable::format()`.
*
* As this uses DateTimeImmutable::format() to format the string, non-time formatters
* will still be interpreted. Be sure to escape those characters first.
*
* @param string $format Format string
* @return string
*/
public function format(string $format): string
{
return $this->toDateTimeImmutable()->format($format);
}
/**
* Reset the format used to the default when converting to a string
*
* @return void
*/
public static function resetToStringFormat(): void
{
static::setToStringFormat(static::DEFAULT_TO_STRING_FORMAT);
}
/**
* Set the default format used when converting to a string
*
* @param string $format The format to use in future __toString() calls.
* @return void
*/
public static function setToStringFormat(string $format): void
{
static::$toStringFormat = $format;
}
/**
* Format the instance as a string using the set format
*
* @return string
*/
public function __toString(): string
{
return $this->format(static::$toStringFormat);
}
/**
* Returns whether time is equal to target time.
*
* @param \Cake\Chronos\ChronosTime $target Target time
* @return bool
*/
public function equals(ChronosTime $target): bool
{
return $this->ticks === $target->ticks;
}
/**
* Returns whether time is greater than target time.
*
* @param \Cake\Chronos\ChronosTime $target Target time
* @return bool
*/
public function greaterThan(ChronosTime $target): bool
{
return $this->ticks > $target->ticks;
}
/**
* Returns whether time is greater than or equal to target time.
*
* @param \Cake\Chronos\ChronosTime $target Target time
* @return bool
*/
public function greaterThanOrEquals(ChronosTime $target): bool
{
return $this->ticks >= $target->ticks;
}
/**
* Returns whether time is less than target time.
*
* @param \Cake\Chronos\ChronosTime $target Target time
* @return bool
*/
public function lessThan(ChronosTime $target): bool
{
return $this->ticks < $target->ticks;
}
/**
* Returns whether time is less than or equal to target time.
*
* @param \Cake\Chronos\ChronosTime $target Target time
* @return bool
*/
public function lessThanOrEquals(ChronosTime $target): bool
{
return $this->ticks <= $target->ticks;
}
/**
* Returns whether time is between time range.
*
* @param \Cake\Chronos\ChronosTime $start Start of target range
* @param \Cake\Chronos\ChronosTime $end End of target range
* @param bool $equals Whether to include the beginning and end of range
* @return bool
*/
public function between(ChronosTime $start, ChronosTime $end, bool $equals = true): bool
{
if ($start->greaterThan($end)) {
[$start, $end] = [$end, $start];
}
if ($equals) {
return $this->greaterThanOrEquals($start) && $this->lessThanOrEquals($end);
}
return $this->greaterThan($start) && $this->lessThan($end);
}
/**
* Returns an `DateTimeImmutable` instance set to this clock time.
*
* @param \DateTimeZone|string|null $timezone Time zone the DateTimeImmutable instance will be in
* @return \DateTimeImmutable
*/
public function toDateTimeImmutable(DateTimeZone|string|null $timezone = null): DateTimeImmutable
{
$timezone = is_string($timezone) ? new DateTimeZone($timezone) : $timezone;
return (new DateTimeImmutable(timezone: $timezone))->setTime(
$this->getHours(),
$this->getMinutes(),
$this->getSeconds(),
$this->getMicroseconds(),
);
}
/**
* Returns an `DateTimeImmutable` instance set to this clock time.
*
* Alias of `toDateTimeImmutable()`.
*
* @param \DateTimeZone|string|null $timezone Time zone the DateTimeImmutable instance will be in
* @return \DateTimeImmutable
*/
public function toNative(DateTimeZone|string|null $timezone = null): DateTimeImmutable
{
return $this->toDateTimeImmutable($timezone);
}
}
+47
View File
@@ -0,0 +1,47 @@
<?php
declare(strict_types=1);
namespace Cake\Chronos;
/**
* Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
* @link https://cakephp.org CakePHP(tm) Project
* @license https://www.opensource.org/licenses/mit-license.php MIT License
*/
use DateTimeImmutable;
use DateTimeZone;
use Psr\Clock\ClockInterface;
/**
* PSR-20 Clock implementation.
*/
class ClockFactory implements ClockInterface
{
private DateTimeZone|string|null $timezone;
/**
* Constructor.
*
* @param \DateTimeZone|string|null $timezone The timezone
*/
public function __construct(DateTimeZone|string|null $timezone = null)
{
$this->timezone = $timezone;
}
/**
* Returns the current time object.
*
* @return \Cake\Chronos\Chronos The current time
*/
public function now(): DateTimeImmutable
{
return Chronos::now($this->timezone);
}
}
@@ -0,0 +1,114 @@
<?php
declare(strict_types=1);
/**
* Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
* @copyright Copyright (c) Brian Nesbitt <brian@nesbot.com>
* @link https://cakephp.org CakePHP(tm) Project
* @license https://www.opensource.org/licenses/mit-license.php MIT License
*/
namespace Cake\Chronos;
use DateTimeInterface;
/**
* Handles formatting differences in text.
*
* Provides a swappable component for other libraries to leverage.
* when localizing or customizing the difference output.
*
* @internal
*/
class DifferenceFormatter implements DifferenceFormatterInterface
{
/**
* The text translator object
*
* @var \Cake\Chronos\Translator
*/
protected Translator $translate;
/**
* Constructor.
*
* @param \Cake\Chronos\Translator|null $translate The text translator object.
*/
public function __construct(?Translator $translate = null)
{
$this->translate = $translate ?: new Translator();
}
/**
* @inheritDoc
*/
public function diffForHumans(
ChronosDate|DateTimeInterface $first,
ChronosDate|DateTimeInterface|null $second = null,
bool $absolute = false,
): string {
$isNow = $second === null;
if ($second === null) {
if ($first instanceof ChronosDate) {
$second = new ChronosDate(Chronos::now());
} else {
$second = Chronos::now($first->getTimezone());
}
}
assert(
($first instanceof ChronosDate && $second instanceof ChronosDate) ||
($first instanceof DateTimeInterface && $second instanceof DateTimeInterface),
);
$diffInterval = $first->diff($second);
switch (true) {
case $diffInterval->y > 0:
$unit = 'year';
$count = $diffInterval->y;
break;
case $diffInterval->m >= 2:
$unit = 'month';
$count = $diffInterval->m;
break;
case $diffInterval->days >= Chronos::DAYS_PER_WEEK * 3:
$unit = 'week';
$count = (int)($diffInterval->days / Chronos::DAYS_PER_WEEK);
break;
case $diffInterval->d > 0:
$unit = 'day';
$count = $diffInterval->d;
break;
case $diffInterval->h > 0:
$unit = 'hour';
$count = $diffInterval->h;
break;
case $diffInterval->i > 0:
$unit = 'minute';
$count = $diffInterval->i;
break;
default:
$count = $diffInterval->s;
$unit = 'second';
break;
}
$time = $this->translate->plural($unit, $count, ['count' => $count]);
if ($absolute) {
return $time;
}
$isFuture = $diffInterval->invert === 1;
$transId = $isNow ? ($isFuture ? 'from_now' : 'ago') : ($isFuture ? 'after' : 'before');
// Some langs have special pluralization for past and future tense.
$tryKeyExists = $unit . '_' . $transId;
if ($this->translate->exists($tryKeyExists)) {
$time = $this->translate->plural($tryKeyExists, $count, ['count' => $count]);
}
return $this->translate->singular($transId, ['time' => $time]);
}
}
@@ -0,0 +1,36 @@
<?php
declare(strict_types=1);
/**
* Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
* @link https://cakephp.org CakePHP(tm) Project
* @license https://www.opensource.org/licenses/mit-license.php MIT License
*/
namespace Cake\Chronos;
use DateTimeInterface;
/**
* Interface for formatting differences in text.
*/
interface DifferenceFormatterInterface
{
/**
* Get the difference in a human readable format.
*
* @param \Cake\Chronos\ChronosDate|\DateTimeInterface $first The datetime to start with.
* @param \Cake\Chronos\ChronosDate|\DateTimeInterface|null $second The datetime to compare against.
* @param bool $absolute removes time difference modifiers ago, after, etc
* @return string The difference between the two days in a human readable format
*/
public function diffForHumans(
ChronosDate|DateTimeInterface $first,
ChronosDate|DateTimeInterface|null $second = null,
bool $absolute = false,
): string;
}
+287
View File
@@ -0,0 +1,287 @@
<?php
declare(strict_types=1);
/**
* Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
* @copyright Copyright (c) Brian Nesbitt <brian@nesbot.com>
* @link https://cakephp.org CakePHP(tm) Project
* @license https://www.opensource.org/licenses/mit-license.php MIT License
*/
namespace Cake\Chronos;
use DateTime;
/**
* Provides string formatting methods for datetime instances.
*
* Expects implementing classes to define static::$toStringFormat
*
* @internal
*/
trait FormattingTrait
{
/**
* Resets the __toString() format to ``DEFAULT_TO_STRING_FORMAT``.
*
* @return void
*/
public static function resetToStringFormat(): void
{
static::setToStringFormat(static::DEFAULT_TO_STRING_FORMAT);
}
/**
* Sets the __toString() format.
*
* @param string $format See ``format()`` for accepted specifiers.
* @return void
*/
public static function setToStringFormat(string $format): void
{
static::$toStringFormat = $format;
}
/**
* Returns a formatted string specified by ``setToStringFormat()``
* or the default ``DEFAULT_TO_STRING_FORMAT`` format.
*
* @return string
*/
public function __toString(): string
{
return $this->format(static::$toStringFormat);
}
/**
* Format the instance as date
*
* @return string
*/
public function toDateString(): string
{
return $this->format('Y-m-d');
}
/**
* Format the instance as a readable date
*
* @return string
*/
public function toFormattedDateString(): string
{
return $this->format('M j, Y');
}
/**
* Format the instance as time
*
* @return string
*/
public function toTimeString(): string
{
return $this->format('H:i:s');
}
/**
* Format the instance as date and time
*
* @return string
*/
public function toDateTimeString(): string
{
return $this->format('Y-m-d H:i:s');
}
/**
* Format the instance with day, date and time
*
* @return string
*/
public function toDayDateTimeString(): string
{
return $this->format('D, M j, Y g:i A');
}
/**
* Format the instance as ATOM
*
* @return string
*/
public function toAtomString(): string
{
return $this->format(DateTime::ATOM);
}
/**
* Format the instance as COOKIE
*
* @return string
*/
public function toCookieString(): string
{
return $this->format(DateTime::COOKIE);
}
/**
* Format the instance as ISO8601
*
* @return string
*/
public function toIso8601String(): string
{
return $this->format(DateTime::ATOM);
}
/**
* Format the instance as RFC822
*
* @return string
* @link https://tools.ietf.org/html/rfc822
*/
public function toRfc822String(): string
{
return $this->format(DateTime::RFC822);
}
/**
* Format the instance as RFC850
*
* @return string
* @link https://tools.ietf.org/html/rfc850
*/
public function toRfc850String(): string
{
return $this->format(DateTime::RFC850);
}
/**
* Format the instance as RFC1036
*
* @return string
* @link https://tools.ietf.org/html/rfc1036
*/
public function toRfc1036String(): string
{
return $this->format(DateTime::RFC1036);
}
/**
* Format the instance as RFC1123
*
* @return string
* @link https://tools.ietf.org/html/rfc1123
*/
public function toRfc1123String(): string
{
return $this->format(DateTime::RFC1123);
}
/**
* Format the instance as RFC2822
*
* @return string
* @link https://tools.ietf.org/html/rfc2822
*/
public function toRfc2822String(): string
{
return $this->format(DateTime::RFC2822);
}
/**
* Format the instance as RFC3339
*
* @return string
* @link https://tools.ietf.org/html/rfc3339
*/
public function toRfc3339String(): string
{
return $this->format(DateTime::RFC3339);
}
/**
* Format the instance as RSS
*
* @return string
*/
public function toRssString(): string
{
return $this->format(DateTime::RSS);
}
/**
* Format the instance as W3C
*
* @return string
*/
public function toW3cString(): string
{
return $this->format(DateTime::W3C);
}
/**
* Returns a UNIX timestamp.
*
* @return string UNIX timestamp
*/
public function toUnixString(): string
{
return $this->format('U');
}
/**
* Returns the quarter
*
* Deprecated 3.3.0: The $range parameter is deprecated. Use toQuarterRange() for quarter ranges.
*
* @param bool $range Range.
* @return array|int 1, 2, 3, or 4 quarter of year or array if $range true
*/
public function toQuarter(bool $range = false): int|array
{
$quarter = (int)ceil((int)$this->format('m') / 3);
if ($range === false) {
return $quarter;
}
trigger_error(
'Using toQuarter() with `$range=true` is deprecated. Use `toQuarterRange()` instead.',
E_USER_DEPRECATED,
);
return $this->toQuarterRange();
}
/**
* Returns the quarter range
*
* @return array{0: string, 1: string} Array with start and end date of quarter in Y-m-d format
*/
public function toQuarterRange(): array
{
/** @var int<1, 4> $quarter */
$quarter = (int)ceil((int)$this->format('m') / 3);
$year = $this->format('Y');
return match ($quarter) {
1 => [$year . '-01-01', $year . '-03-31'],
2 => [$year . '-04-01', $year . '-06-30'],
3 => [$year . '-07-01', $year . '-09-30'],
4 => [$year . '-10-01', $year . '-12-31'],
};
}
/**
* Returns ISO 8601 week number of year, weeks starting on Monday
*
* @return int ISO 8601 week number of year
*/
public function toWeek(): int
{
return (int)$this->format('W');
}
}
+97
View File
@@ -0,0 +1,97 @@
<?php
declare(strict_types=1);
/**
* Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
* @link https://cakephp.org CakePHP(tm) Project
* @license https://www.opensource.org/licenses/mit-license.php MIT License
*/
namespace Cake\Chronos;
/**
* Basic english only 'translator' for diffForHumans()
*
* @internal
*/
class Translator
{
/**
* Translation strings.
*
* @var array
*/
public static array $strings = [
'year' => '1 year',
'year_plural' => '{count} years',
'month' => '1 month',
'month_plural' => '{count} months',
'week' => '1 week',
'week_plural' => '{count} weeks',
'day' => '1 day',
'day_plural' => '{count} days',
'hour' => '1 hour',
'hour_plural' => '{count} hours',
'minute' => '1 minute',
'minute_plural' => '{count} minutes',
'second' => '1 second',
'second_plural' => '{count} seconds',
'ago' => '{time} ago',
'from_now' => '{time} from now',
'after' => '{time} after',
'before' => '{time} before',
];
/**
* Check if a translation key exists.
*
* @param string $key The key to check.
* @return bool Whether the key exists.
*/
public function exists(string $key): bool
{
return isset(static::$strings[$key]);
}
/**
* Get a plural message.
*
* @param string $key The key to use.
* @param int $count The number of items in the translation.
* @param array $vars Additional context variables.
* @return string The translated message or ''.
*/
public function plural(string $key, int $count, array $vars = []): string
{
if ($count === 1) {
return $this->singular($key, $vars);
}
return $this->singular($key . '_plural', ['count' => $count] + $vars);
}
/**
* Get a singular message.
*
* @param string $key The key to use.
* @param array $vars Additional context variables.
* @return string The translated message or ''.
*/
public function singular(string $key, array $vars = []): string
{
if (isset(static::$strings[$key])) {
$varKeys = array_keys($vars);
foreach ($varKeys as $i => $k) {
$varKeys[$i] = '{' . $k . '}';
}
return str_replace($varKeys, $vars, static::$strings[$key]);
}
return '';
}
}