Skip to content

Instantly share code, notes, and snippets.

@timvisee
Created May 2, 2015 17:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save timvisee/e0504c46d332c69abec0 to your computer and use it in GitHub Desktop.
Save timvisee/e0504c46d332c69abec0 to your computer and use it in GitHub Desktop.
Carbon CMS DateTime Classes
<?php
namespace carbon\core\datetime\interval;
use carbon\core\datetime\DateTime;
use DateInterval as PHPDateInterval;
use DomainException;
use Exception;
use InvalidArgumentException;
// Prevent direct requests to this set_file due to security reasons
defined('CARBON_CORE_INIT') or die('Access denied!');
/**
* Class DateInterval
*
* @package carbon\core\datetime
*
* @TODO Update these properties below!
* @TODO Rename this to 'daysOfWeek'?
*
* property-read int $daysExcludeWeeks Total days remaining in the final week of the current instance (days % 7).
*/
class DateInterval extends PHPDateInterval {
// TODO: Should we create a DateDuration class which is similar to this class?
// TODO: Throw better exceptions!
// TODO: Rename sub... methods to subtract...?
/**
* The date interval specification prefix designator.
*
* @const string The period prefix.
*/
const PERIOD_PREFIX = 'P';
/**
* The date interval specification year designator.
*
* @const string The year prefix.
*/
const PERIOD_YEARS = 'Y';
/**
* The date interval specification month designator.
*
* @const string The month prefix.
*/
const PERIOD_MONTHS = 'M';
/**
* The date interval specification day designator.
*
* @const string The day prefix.
*/
const PERIOD_DAYS = 'D';
/**
* The date interval specification time designator.
*
* @const string The time prefix.
*/
const PERIOD_TIME_PREFIX = 'T';
/**
* The date interval specification hour designator.
*
* @const string The hour prefix.
*/
const PERIOD_HOURS = 'H';
/**
* The date interval specification minute designator.
*
* @const string The minute prefix.
*/
const PERIOD_MINUTES = 'M';
/**
* The date interval specification second designator.
*
* @const string The second prefix.
*/
const PERIOD_SECONDS = 'S';
/**
* Constructor.
*
* @param string|PHPDateInterval|PHPDateInterval|null $dateIntervalSpec [optional] A date interval specification, a DateInterval or PHPDateInterval instance, or null to use a zero specification.
* @param bool $inverted [optional] Defines whether the date interval specification is inverted or not, this parameter is ignored if a DateInterval or PHPDateInterval instance is given for the $dateIntervalSpec parameter.
*
* @throws \Exception Throws an exception on failure.
*/
public function __construct($dateIntervalSpec, $inverted = false) {
// Parse string specifications
if(is_string($dateIntervalSpec)) {
// Make sure the specification is valid
if(!DateIntervalSpecUtils::isValid($dateIntervalSpec))
throw new \DomainException('Invalid date interval specification (\'' . $dateIntervalSpec . '\' was given)');
// Set the specification
$spec = $dateIntervalSpec;
}
// Parse DateInterval instances
else if($dateIntervalSpec instanceof self) {
// Set whether this date interval is inverted and create a specification string
$inverted = $dateIntervalSpec->invert;
$spec = $dateIntervalSpec->toSpecString();
}
// Parse PHPDateInterval instances
else if($dateIntervalSpec instanceof parent) {
// Set whether this date interval is inverted and create a specification string
$inverted = $dateIntervalSpec->invert;
$spec = DateIntervalSpecUtils::create($dateIntervalSpec->y, $dateIntervalSpec->m, null, $dateIntervalSpec->d, $dateIntervalSpec->h, $dateIntervalSpec->i, $dateIntervalSpec->s);
}
// Use a zero specification if the parameter is null
else if($dateIntervalSpec === null)
// Create a zero specification
$spec = DateIntervalFactory::zero();
// No valid date interval specification was given, throw an exception
else
throw new \DomainException('Invalid date interval specification (\'' . $dateIntervalSpec . '\' was given)');
// Construct the parent object, and set whether the date interval is inverted
parent::__construct($spec);
$this->setInverted($inverted);
}
/**
* Parse a date interval. A new instance may be created.
*
* This method allows better fluent syntax because it makes method chaining possible.
*
* @param PHPDateInterval|PHPDateInterval|string|null $dateInterval [optional] A DateInterval or PHPDateInterval instance, a date interval specification, or null to use a zero specification.
*
* @return static A DateInterval instance, or null on failure.
*/
// TODO: Don't use exception catching? Is it bad?
// TODO: Accept relative times, such as '-2 days'!
public static function parse($dateInterval) {
// Return the object if it's already a DateInterval instance
if($dateInterval instanceof self)
return $dateInterval;
// Make sure the spec is valid if th date interval parameter is a string
if(is_string($dateInterval))
if(!DateIntervalSpecUtils::isValid($dateInterval))
return null;
// Parse and return the date and time, return the default value on failure
try {
// TODO: This object can't be constructed (currently) using this single parameter, use better parsing!
return new static($dateInterval);
} catch(InvalidArgumentException $ex) {
return null;
}
}
/**
* Create a DateInterval instance from a DateInterval one. Can not instance
* DateInterval objects created from DateTime::diff() as you can't externally
* set the $days field.
*
* @param PHPDateInterval|PHPDateInterval|string $dateInterval
*
* @throws InvalidArgumentException
*
* @return static A new DateTime instance.
*/
// TODO: Update docs!
// TODO: Parse the date interval parameter?
// TODO: Support null!
public static function instance($dateInterval) {
// TODO: Is this necessary?
if(DateIntervalUtils::isCreatedFromDiff($dateInterval))
throw new \InvalidArgumentException("Can not instance a DateInterval object created from DateTime::diff().");
// Parse DateInterval instances, create a new instance
if($dateInterval instanceof self)
return new static($dateInterval->toSpecString(), $dateInterval->isInverted());
// Try to parse and instantiate other specifications and return the result
return static::parse($dateInterval);
}
/**
* Create a copy of this instance.
*
* @return PHPDateInterval The DateInterval instance copy.
*/
public function copy() {
return static::instance($this);
}
/**
* Clone this instance.
*
* @return PHPDateInterval A DateInterval instance clone.
*/
public function __clone() {
return $this->copy();
}
/**
* Add the given number of years, months, weeks, days, hours, minutes and seconds to the date interval.
* The resulting values may not be a negative number, or an exception will be thrown.
*
* @param int|null $years The number of years to add to the interval. Null to ignore this value.
* @param int|null $months The number of months to add to the interval. Null to ignore this value.
* @param int|null $weeks The number of weeks to add to the interval, this is converted into and added to the number of days. Null to ignore this value.
* @param int|null $days The number of days to add to the interval. Null to ignore this value.
* @param int|null $hours The number of hours to add to the interval. Null to ignore this value.
* @param int|null $minutes The number of minutes to add to the interval. Null to ignore this value.
* @param int|null $seconds The number of seconds to add to the interval. Null to ignore this value.
*
* @return static The DateTime instance for method chaining.
*
* @throws DomainException|Exception Throws an exception on failure.
*/
public function addDateTime($years = null, $months = null, $weeks = null, $days = null, $hours = null, $minutes = null, $seconds = null) {
// Add the date and time part
$this->addDate($years, $months, $weeks, $days);
$this->addTime($hours, $minutes, $seconds);
// Return this instance
return $this;
}
/**
* Subtract the given number of years, months, weeks, days, hours, minutes and seconds to the date interval.
* The resulting values may not be a negative number, or an exception will be thrown.
*
* @param int|null $years The number of years to subtract to the interval. Null to ignore this value.
* @param int|null $months The number of months to subtract to the interval. Null to ignore this value.
* @param int|null $weeks The number of weeks to subtract to the interval, this is converted into and added to the number of days. Null to ignore this value.
* @param int|null $days The number of days to subtract to the interval. Null to ignore this value.
* @param int|null $hours The number of hours to subtract to the interval. Null to ignore this value.
* @param int|null $minutes The number of minutes to subtract to the interval. Null to ignore this value.
* @param int|null $seconds The number of seconds to subtract to the interval. Null to ignore this value.
*
* @return static The DateTime instance for method chaining.
*
* @throws DomainException|Exception Throws an exception on failure.
*/
public function subDateTime($years = null, $months = null, $weeks = null, $days = null, $hours = null, $minutes = null, $seconds = null) {
// Subtract the date and time part
$this->subDate($years, $months, $weeks, $days);
$this->subTime($hours, $minutes, $seconds);
// Return this instance
return $this;
}
/**
* Set the time part of the interval. This changes the specified hours, minutes and seconds.
*
* @param int|null $years The number of years of the interval. Null to ignore this value.
* @param int|null $months The number of months of the interval. Null to ignore this value.
* @param int|null $weeks The number of weeks of the interval, this is converted into and added to the number of days. Null to ignore this value.
* @param int|null $days The number of days of the interval. Null to ignore this value.
* @param int|null $hours The number of hours of the interval. Null to ignore this value.
* @param int|null $minutes The number of minutes of the interval. Null to ignore this value.
* @param int|null $seconds The number of seconds of the interval. Null to ignore this value.
*
* @return static This DateInterval instance for method chaining.
*/
public function setDateTime($years = null, $months = null, $weeks = null, $days = null, $hours = null, $minutes = null, $seconds = null) {
// Set the date and time part
$this->setDate($years, $months, $weeks, $days);
$this->setTime($hours, $minutes, $seconds);
// Return this instance
return $this;
}
/**
* Add the given number of years, months, weeks and days to the date interval.
* The resulting values may not be a negative number, or an exception will be thrown.
*
* @param int|null $years The number of years to add to the interval. Null to ignore this value.
* @param int|null $months The number of months to add to the interval. Null to ignore this value.
* @param int|null $weeks The number of weeks to add to the interval, this is converted into and added to the number of days. Null to ignore this value.
* @param int|null $days The number of days to add to the interval. Null to ignore this value.
*
* @return static The DateTime instance for method chaining.
*
* @throws DomainException|Exception Throws an exception on failure.
*/
public function addDate($years = null, $months = null, $weeks = null, $days = null) {
// Add the number of years and months if set
if(!empty($years))
$this->addYears($years);
if(!empty($months))
$this->addMonths($months);
// Add the number of weeks and days
$this->addWeeksAndDays($weeks, $days);
// Return this instance for method chaining
return $this;
}
/**
* Subtract the given number of years, months, weeks and days to the date interval.
* The resulting values may not be a negative number, or an exception will be thrown.
*
* @param int|null $years The number of years to subtract of the interval. Null to ignore this value.
* @param int|null $months The number of months to subtract of the interval. Null to ignore this value.
* @param int|null $weeks The number of weeks to subtract of the interval, this is converted into and added to the number of days. Null to ignore this value.
* @param int|null $days The number of days to subtract of the interval. Null to ignore this value.
*
* @return static The DateTime instance for method chaining.
*
* @throws DomainException|Exception Throws an exception on failure.
*/
public function subDate($years = null, $months = null, $weeks = null, $days = null) {
// Subtract the number of years and months if set
if(!empty($years))
$this->subYears($years);
if(!empty($months))
$this->subMonths($months);
// Subtract the number of weeks and days
$this->subWeeksAndDays($weeks, $days);
// Return this instance for method chaining
return $this;
}
/**
* Set the date part of the interval. This changes the specified years, months and days.
*
* @param int|null $years The number of years of the interval. Null to ignore this value.
* @param int|null $months The number of months of the interval. Null to ignore this value.
* @param int|null $weeks The number of weeks of the interval, this is converted into and added to the number of days. Null to ignore this value.
* @param int|null $days The number of days of the interval. Null to ignore this value.
*
* @return static This DateInterval instance for method chaining.
*/
public function setDate($years = null, $months = null, $weeks = null, $days = null) {
// Set the years and months if set
if(!empty($years))
$this->setYears($years);
if(!empty($months))
$this->setMonths($months);
// Set the days
$this->setWeeksAndDays($weeks, $days);
// Return this instance
return $this;
}
/**
* Get the number of years.
*
* @return int Number of years.
*/
public function getYears() {
return $this->y;
}
/**
* Add the given number of years to the date interval.
* The resulting number of years may not be a negative number, or an exception will be thrown.
*
* @param int $years [optional] The number of years to add.
*
* @return static The DateTime instance for method chaining.
*
* @throws DomainException|Exception Throws an exception on failure.
*/
public function addYears($years = 1) {
// Make sure the years parameter is an integer
if(!is_int($years))
throw new DomainException('Invalid value for years, must be an integer (\'' . $years . '\' was given)');
// Calculate the new number of years
$years = $this->getYears() + intval($years);
// Make sure the number isn't negative
if($years < 0)
throw new Exception('The resulting number of years may not be negative (' . $years . ' is negative)');
// Set the number of years
$this->setYears($years);
// Return this instance for method chaining
return $this;
}
/**
* Add one, or the given number of years to the date interval.
* The resulting number of years may not be a negative number, or an exception will be thrown.
*
* @param int $years [optional] The number of years to add.
*
* @return static The DateTime instance for method chaining.
*
* @throws DomainException|Exception Throws an exception on failure.
*/
public function addYear($years = 1) {
return $this->addYears($years);
}
/**
* Subtract the given number of years to the date interval.
* The resulting number of years may not be a negative number, or an exception will be thrown.
*
* @param int $years [optional] The number of years to subtract.
*
* @return static The DateTime instance for method chaining.
*
* @throws DomainException|Exception Throws an exception on failure.
*/
public function subYears($years = 1) {
// Make sure the years parameter is an integer
if(!is_int($years))
throw new \DomainException('Invalid value for years, must be an integer (\'' . $years . '\' was given)');
// Subtract the number of years, return the result
return $this->addYears($years * -1);
}
/**
* Subtract one, or the given number of years to the date interval.
* The resulting number of years may not be a negative number, or an exception will be thrown.
*
* @param int $years [optional] The number of years to subtract.
*
* @return static The DateTime instance for method chaining.
*
* @throws DomainException|Exception Throws an exception on failure.
*/
public function subYear($years = 1) {
return $this->subYears($years);
}
/**
* Set the number of years.
*
* @param int $years The number of years, must be zero or a positive number.
*
* @return static The DateTime instance for method chaining.
*
* @throws \DomainException Throws an exception on failure.
*/
public function setYears($years) {
// Make sure the value is a positive number or zero
if(!is_int($years) || $years < 0)
throw new \DomainException('Invalid value for years, must be zero or a positive number (\'' . $years . '\' was given)');
// Set the years, return this instance
$this->y = $years;
return $this;
}
/**
* Get the number of months.
*
* @return int Number of months.
*/
public function getMonths() {
return $this->m;
}
/**
* Add the given number of months to the date interval.
* The resulting number of months may not be a negative number, or an exception will be thrown.
*
* @param int $months [optional] The number of months to add.
*
* @return static The DateTime instance for method chaining.
*
* @throws DomainException|Exception Throws an exception on failure.
*/
public function addMonths($months = 1) {
// Make sure the months parameter is an integer
if(!is_int($months))
throw new DomainException('Invalid value for months, must be an integer (\'' . $months . '\' was given)');
// Calculate the new number of months
$months = $this->getMonths() + intval($months);
// Make sure the number isn't negative
if($months < 0)
throw new Exception('The resulting number of months may not be negative (' . $months . ' is negative)');
// Set the number of months
$this->setMonths($months);
// Return this instance for method chaining
return $this;
}
/**
* Add one, or the given number of months to the date interval.
* The resulting number of months may not be a negative number, or an exception will be thrown.
*
* @param int $months [optional] The number of months to add.
*
* @return static The DateTime instance for method chaining.
*
* @throws DomainException|Exception Throws an exception on failure.
*/
public function addMonth($months = 1) {
return $this->addMonths($months);
}
/**
* Subtract the given number of months to the date interval.
* The resulting number of months may not be a negative number, or an exception will be thrown.
*
* @param int $months [optional] The number of months to subtract.
*
* @return static The DateTime instance for method chaining.
*
* @throws DomainException|Exception Throws an exception on failure.
*/
public function subMonths($months = 1) {
// Make sure the months parameter is an integer
if(!is_int($months))
throw new \DomainException('Invalid value for months, must be an integer (\'' . $months . '\' was given)');
// Subtract the number of months, return the result
return $this->addMonths($months * -1);
}
/**
* Subtract one, or the given number of months to the date interval.
* The resulting number of months may not be a negative number, or an exception will be thrown.
*
* @param int $months [optional] The number of months to subtract.
*
* @return static The DateTime instance for method chaining.
*
* @throws DomainException|Exception Throws an exception on failure.
*/
public function subMonth($months = 1) {
return $this->subMonths($months);
}
/**
* Set the number of months.
*
* @param int $months The number of months, must be zero or a positive number.
*
* @return static The DateTime instance for method chaining.
*
* @throws \DomainException Throws an exception on failure.
*/
public function setMonths($months) {
// Make sure the value is a positive number or zero
if(!is_int($months) || $months < 0)
throw new \DomainException('Invalid value for months, must be zero or a positive number (\'' . $months . '\' was given)');
// Set the months, return this instance
$this->m = $months;
return $this;
}
/**
* Add the given number of weeks and days to the date interval.
* The resulting number of days may not be a negative number, or an exception will be thrown.
*
* @param int|null $weeks [optional] The number of weeks to add. Null to ignore this value.
* @param int|null $days [optional] The number of days to add. Null to ignore this value.
*
* @return static The DateTime instance for method chaining.
*
* @throws DomainException|Exception Throws an exception on failure.
*/
public function addWeeksAndDays($weeks = null, $days = null) {
// Calculate the total number of days
$totalDays = 0;
// Append the number of weeks if set
if(is_int($weeks))
$totalDays += intval($weeks) * DateTime::DAYS_PER_WEEK;
else if(!empty($weeks))
throw new \DomainException('Invalid value for weeks (\'' . $weeks . '\' was given)');
// Append the number of days if set
if(is_int($days))
$totalDays += intval($days);
else if(!empty($days))
throw new \DomainException('Invalid value for days (\'' . $days . '\' was given)');
// Set the number of days
if(!empty($totalDays)) {
// Make sure the number of days isn't negative
if(($this->getDays() + $totalDays) < 0)
throw new \DomainException('The resulting number of days may not be below zero (got ' . $totalDays . ' days)');
// Add the number of days
$this->addDays($totalDays);
}
// Return this instance
return $this;
}
/**
* Subtract the given number of weeks and days to the date interval.
* The resulting number of days may not be a negative number, or an exception will be thrown.
*
* @param int|null $weeks [optional] The number of weeks to subtract. Null to ignore this value.
* @param int|null $days [optional] The number of days to subtract. Null to ignore this value.
*
* @return static The DateTime instance for method chaining.
*
* @throws DomainException|Exception Throws an exception on failure.
*/
public function subWeeksAndDays($weeks = null, $days = null) {
// Calculate the total number of days
$totalDays = 0;
// Append the number of weeks if set
if(is_int($weeks))
$totalDays += intval($weeks) * DateTime::DAYS_PER_WEEK;
else if(!empty($weeks))
throw new \DomainException('Invalid value for weeks (\'' . $weeks . '\' was given)');
// Append the number of days if set
if(is_int($days))
$totalDays += intval($days);
else if(!empty($days))
throw new \DomainException('Invalid value for days (\'' . $days . '\' was given)');
// Set the number of days
if(!empty($totalDays)) {
// Make sure the number of days isn't negative
if(($this->getDays() + $totalDays) < 0)
throw new \DomainException('The resulting number of days may not be below zero (got ' . $totalDays . ' days)');
// Subtract the number of days
$this->subDays($totalDays);
}
// Return this instance
return $this;
}
/**
* Set the number of days based ont he given number of weeks and days.
*
* @param int|null $weeks The number of weeks of the interval, this is converted into and added to the number of days. Null to ignore this value.
* @param int|null $days The number of days of the interval. Null to ignore this value.
*
* @return static This DateTime instance for method chaining.
*/
public function setWeeksAndDays($weeks = null, $days = null) {
// Calculate the total number of days
$totalDays = 0;
// Append the number of weeks if set
if(is_int($weeks))
$totalDays += intval($weeks) * DateTime::DAYS_PER_WEEK;
else if(!empty($weeks))
throw new \DomainException('Invalid value for weeks (\'' . $weeks . '\' was given)');
// Append the number of days if set
if(is_int($days))
$totalDays += intval($days);
else if(!empty($days))
throw new \DomainException('Invalid value for days (\'' . $days . '\' was given)');
// Set the number of days
if(!empty($totalDays)) {
// Make sure the number of days isn't negative
if($totalDays < 0)
throw new \DomainException('The total number of days may not be below zero (' . $totalDays . ' total days)');
// Set the number of days
$this->setDays($totalDays);
}
// Return this instance
return $this;
}
/**
* Get the approximate number of weeks. This value is based on the number of days specified, and thus isn't exact.
*
* @return int The approximate number of weeks.
*/
public function getApproximateWeeks() {
return (int) ($this->getDays() / DateTime::DAYS_PER_WEEK);
}
/**
* Add the given number of days to the date interval specified as weeks.
* The resulting number of days may not be a negative number, or an exception will be thrown.
*
* @param int $weeks [optional] The number of weeks to add.
*
* @return static The DateTime instance for method chaining.
*
* @throws DomainException|Exception Throws an exception on failure.
*/
public function addWeeks($weeks = 1) {
// Make sure the weeks parameter is an integer
if(!is_int($weeks))
throw new DomainException('Invalid value for weeks, must be an integer (\'' . $weeks . '\' was given)');
// Calculate the new number of days
$days = $this->getDays() + (intval($weeks) * DateTime::DAYS_PER_WEEK);
// Make sure the number isn't negative
if($days < 0)
throw new Exception('The resulting number of days may not be negative (' . $days . ' is negative)');
// Set the number of days
$this->setDays($weeks);
// Return this instance for method chaining
return $this;
}
/**
* Add one, or the given number of days to the date interval specified as weeks.
* The resulting number of days may not be a negative number, or an exception will be thrown.
*
* @param int $weeks [optional] The number of weeks to add.
*
* @return static The DateTime instance for method chaining.
*
* @throws DomainException|Exception Throws an exception on failure.
*/
public function addWeek($weeks = 1) {
return $this->addWeeks($weeks);
}
/**
* Subtract the given number of days to the date interval specified as weeks.
* The resulting number of days may not be a negative number, or an exception will be thrown.
*
* @param int $weeks [optional] The number of weeks to subtract.
*
* @return static The DateTime instance for method chaining.
*
* @throws DomainException|Exception Throws an exception on failure.
*/
public function subWeeks($weeks = 1) {
// Make sure the weeks parameter is an integer
if(!is_int($weeks))
throw new \DomainException('Invalid value for weeks, must be an integer (\'' . $weeks . '\' was given)');
// Subtract the number of weeks, return the result
return $this->addWeeks($weeks * -1);
}
/**
* Subtract one, or the given number of days to the date interval specified as weeks.
* The resulting number of days may not be a negative number, or an exception will be thrown.
*
* @param int $weeks [optional] The number of weeks to subtract.
*
* @return static The DateTime instance for method chaining.
*
* @throws DomainException|Exception Throws an exception on failure.
*/
public function subWeek($weeks = 1) {
return $this->subWeeks($weeks);
}
/**
* Set the number of days based on the given number of weeks.
* Note: This will change the number of days.
*
* @param int $weeks The number of weeks, must be zero or a positive number.
*
* @return static The DateTime instance for method chaining.
*
* @throws \DomainException Throws an exception on failure.
*/
public function setWeeks($weeks) {
// Make sure the value is a positive number or zero
if(!is_int($weeks) || $weeks < 0)
throw new \DomainException('Invalid value for months, must be zero or a positive number (\'' . $weeks . '\' was given)');
// Set the days, return this instance
$this->d = $weeks * DateTime::DAYS_PER_WEEK;
return $this;
}
/**
* Get the number of days.
*
* @return int Number of days.
*/
public function getDays() {
return $this->d;
}
/**
* Add the given number of days to the date interval.
* The resulting number of days may not be a negative number, or an exception will be thrown.
*
* @param int $days [optional] The number of days to add.
*
* @return static The DateTime instance for method chaining.
*
* @throws DomainException|Exception Throws an exception on failure.
*/
public function addDays($days = 1) {
// Make sure the days parameter is an integer
if(!is_int($days))
throw new DomainException('Invalid value for days, must be an integer (\'' . $days . '\' was given)');
// Calculate the new number of days
$days = $this->getDays() + intval($days);
// Make sure the number isn't negative
if($days < 0)
throw new Exception('The resulting number of days may not be negative (' . $days . ' is negative)');
// Set the number of days
$this->setDays($days);
// Return this instance for method chaining
return $this;
}
/**
* Add one, or the given number of days to the date interval.
* The resulting number of days may not be a negative number, or an exception will be thrown.
*
* @param int $days [optional] The number of days to add.
*
* @return static The DateTime instance for method chaining.
*
* @throws DomainException|Exception Throws an exception on failure.
*/
public function addDay($days = 1) {
return $this->addDays($days);
}
/**
* Subtract the given number of days to the date interval.
* The resulting number of days may not be a negative number, or an exception will be thrown.
*
* @param int $days [optional] The number of days to subtract.
*
* @return static The DateTime instance for method chaining.
*
* @throws DomainException|Exception Throws an exception on failure.
*/
public function subDays($days = 1) {
// Make sure the days parameter is an integer
if(!is_int($days))
throw new \DomainException('Invalid value for days, must be an integer (\'' . $days . '\' was given)');
// Subtract the number of days, return the result
return $this->addDays($days * -1);
}
/**
* Subtract one, or the given number of days to the date interval.
* The resulting number of days may not be a negative number, or an exception will be thrown.
*
* @param int $days [optional] The number of days to subtract.
*
* @return static The DateTime instance for method chaining.
*
* @throws DomainException|Exception Throws an exception on failure.
*/
public function subDay($days = 1) {
return $this->subDays($days);
}
/**
* Set the number of days.
*
* @param int $days The number of days, must be zero or a positive number.
*
* @return static The DateTime instance for method chaining.
*
* @throws DomainException Throws an exception on failure.
*/
public function setDays($days) {
// Make sure the value is a positive number or zero
if(!is_int($days) || $days < 0)
throw new DomainException('Invalid value for days, must be zero or a positive number (\'' . $days . '\' was given)');
// Set the days, return this instance
$this->d = $days;
return $this;
}
/**
* Add the given number of hours, minutes and seconds to the date interval.
* The resulting values may not be a negative number, or an exception will be thrown.
*
* @param int|null $hours The number of hours to add to the interval. Null to ignore this value.
* @param int|null $minutes The number of minutes to add to the interval. Null to ignore this value.
* @param int|null $seconds The number of seconds to add to the interval. Null to ignore this value.
*
* @return static The DateTime instance for method chaining.
*
* @throws DomainException|Exception Throws an exception on failure.
*/
public function addTime($hours = null, $minutes = null, $seconds = null) {
// Add the number of hours, minutes and seconds if set
if(!empty($hours))
$this->addHours($hours);
if(!empty($minutes))
$this->addMinutes($minutes);
if(!empty($seconds))
$this->addSecond($seconds);
// Return this instance for method chaining
return $this;
}
/**
* Subtract the given number of hours, minutes and seconds to the date interval.
* The resulting values may not be a negative number, or an exception will be thrown.
*
* @param int|null $hours The number of hours to subtract to the interval. Null to ignore this value.
* @param int|null $minutes The number of minutes to subtract to the interval. Null to ignore this value.
* @param int|null $seconds The number of seconds to subtract to the interval. Null to ignore this value.
*
* @return static The DateTime instance for method chaining.
*
* @throws DomainException|Exception Throws an exception on failure.
*/
public function subTime($hours = null, $minutes = null, $seconds = null) {
// Subtract the number of hours, minutes and seconds if set
if(!empty($hours))
$this->subHours($hours);
if(!empty($minutes))
$this->subMinutes($minutes);
if(!empty($seconds))
$this->subSecond($seconds);
// Return this instance for method chaining
return $this;
}
/**
* Set the date and time part of the interval. This changes the specified years, months, days, hours, minutes and seconds.
*
* @param int|null $hours The number of hours of the interval. Null to ignore this value.
* @param int|null $minutes The number of minutes of the interval. Null to ignore this value.
* @param int|null $seconds The number of seconds of the interval. Null to ignore this value.
*
* @return static This DateInterval instance for method chaining.
*/
public function setTime($hours = null, $minutes = null, $seconds = null) {
// Set the hours, minutes and seconds
if(!empty($hours))
$this->setHours($hours);
if(!empty($minutes))
$this->setMinutes($minutes);
if(!empty($seconds))
$this->setSeconds($seconds);
// Return this instance
return $this;
}
/**
* Get the number of hours.
*
* @return int Number of hours.
*/
public function getHours() {
return $this->h;
}
/**
* Add the given number of hours to the date interval.
* The resulting number of hours may not be a negative number, or an exception will be thrown.
*
* @param int $hours [optional] The number of hours to add.
*
* @return static The DateTime instance for method chaining.
*
* @throws DomainException|Exception Throws an exception on failure.
*/
public function addHours($hours = 1) {
// Make sure the hours parameter is an integer
if(!is_int($hours))
throw new DomainException('Invalid value for hours, must be an integer (\'' . $hours . '\' was given)');
// Calculate the new number of hours
$hours = $this->getHours() + intval($hours);
// Make sure the number isn't negative
if($hours < 0)
throw new Exception('The resulting number of hours may not be negative (' . $hours . ' is negative)');
// Set the number of hours
$this->setHours($hours);
// Return this instance for method chaining
return $this;
}
/**
* Add one, or the given number of hours to the date interval.
* The resulting number of hours may not be a negative number, or an exception will be thrown.
*
* @param int $hours [optional] The number of hours to add.
*
* @return static The DateTime instance for method chaining.
*
* @throws DomainException|Exception Throws an exception on failure.
*/
public function addHour($hours = 1) {
return $this->addHours($hours);
}
/**
* Subtract the given number of hours to the date interval.
* The resulting number of hours may not be a negative number, or an exception will be thrown.
*
* @param int $hours [optional] The number of hours to subtract.
*
* @return static The DateTime instance for method chaining.
*
* @throws DomainException|Exception Throws an exception on failure.
*/
public function subHours($hours = 1) {
// Make sure the hours parameter is an integer
if(!is_int($hours))
throw new \DomainException('Invalid value for hours, must be an integer (\'' . $hours . '\' was given)');
// Subtract the number of hours, return the result
return $this->addHours($hours * -1);
}
/**
* Subtract one, or the given number of hours to the date interval.
* The resulting number of hours may not be a negative number, or an exception will be thrown.
*
* @param int $hours [optional] The number of hours to subtract.
*
* @return static The DateTime instance for method chaining.
*
* @throws DomainException|Exception Throws an exception on failure.
*/
public function subHour($hours = 1) {
return $this->subHours($hours);
}
/**
* Set the number of hours.
*
* @param int $hours The number of hours, must be zero or a positive number.
*
* @return static The DateTime instance for method chaining.
*
* @throws \DomainException Throws an exception on failure.
*/
public function setHours($hours) {
// Make sure the value is a positive number or zero
if(!is_int($hours) || $hours < 0)
throw new \DomainException('Invalid value for hours, must be zero or a positive number (\'' . $hours . '\' was given)');
// Set the hours, return this instance
$this->h = $hours;
return $this;
}
/**
* Get the number of minutes.
*
* @return int Number of minutes.
*/
public function getMinutes() {
return $this->i;
}
/**
* Add the given number of minutes to the date interval.
* The resulting number of minutes may not be a negative number, or an exception will be thrown.
*
* @param int $minutes [optional] The number of minutes to add.
*
* @return static The DateTime instance for method chaining.
*
* @throws DomainException|Exception Throws an exception on failure.
*/
public function addMinutes($minutes = 1) {
// Make sure the minutes parameter is an integer
if(!is_int($minutes))
throw new DomainException('Invalid value for minutes, must be an integer (\'' . $minutes . '\' was given)');
// Calculate the new number of minutes
$minutes = $this->getMinutes() + intval($minutes);
// Make sure the number isn't negative
if($minutes < 0)
throw new Exception('The resulting number of minutes may not be negative (' . $minutes . ' is negative)');
// Set the number of minutes
$this->setMinutes($minutes);
// Return this instance for method chaining
return $this;
}
/**
* Add one, or the given number of minutes to the date interval.
* The resulting number of minutes may not be a negative number, or an exception will be thrown.
*
* @param int $minutes [optional] The number of minutes to add.
*
* @return static The DateTime instance for method chaining.
*
* @throws DomainException|Exception Throws an exception on failure.
*/
public function addMinute($minutes = 1) {
return $this->addMinutes($minutes);
}
/**
* Subtract the given number of minutes to the date interval.
* The resulting number of minutes may not be a negative number, or an exception will be thrown.
*
* @param int $minutes [optional] The number of minutes to subtract.
*
* @return static The DateTime instance for method chaining.
*
* @throws DomainException|Exception Throws an exception on failure.
*/
public function subMinutes($minutes = 1) {
// Make sure the minutes parameter is an integer
if(!is_int($minutes))
throw new \DomainException('Invalid value for minutes, must be an integer (\'' . $minutes . '\' was given)');
// Subtract the number of minutes, return the result
return $this->addMinutes($minutes * -1);
}
/**
* Subtract one, or the given number of minutes to the date interval.
* The resulting number of minutes may not be a negative number, or an exception will be thrown.
*
* @param int $minutes [optional] The number of minutes to subtract.
*
* @return static The DateTime instance for method chaining.
*
* @throws DomainException|Exception Throws an exception on failure.
*/
public function subMinute($minutes = 1) {
return $this->subMinutes($minutes);
}
/**
* Set the number of minutes.
*
* @param int $minutes The number of minutes, must be zero or a positive number.
*
* @return static The DateTime instance for method chaining.
*
* @throws \DomainException Throws an exception on failure.
*/
public function setMinutes($minutes) {
// Make sure the value is a positive number or zero
if(!is_int($minutes) || $minutes < 0)
throw new \DomainException('Invalid value for minutes, must be zero or a positive number (\'' . $minutes . '\' was given)');
// Set the minutes, return this instance
$this->i = $minutes;
return $this;
}
/**
* Get the number of seconds.
*
* @return int Number of seconds.
*/
public function getSeconds() {
return $this->s;
}
/**
* Add the given number of seconds to the date interval.
* The resulting number of seconds may not be a negative number, or an exception will be thrown.
*
* @param int $seconds [optional] The number of seconds to add.
*
* @return static The DateTime instance for method chaining.
*
* @throws DomainException|Exception Throws an exception on failure.
*/
public function addSeconds($seconds = 1) {
// Make sure the seconds parameter is an integer
if(!is_int($seconds))
throw new DomainException('Invalid value for seconds, must be an integer (\'' . $seconds . '\' was given)');
// Calculate the new number of seconds
$seconds = $this->getSeconds() + intval($seconds);
// Make sure the number isn't negative
if($seconds < 0)
throw new Exception('The resulting number of seconds may not be negative (' . $seconds . ' is negative)');
// Set the number of seconds
$this->setSeconds($seconds);
// Return this instance for method chaining
return $this;
}
/**
* Add one, or the given number of seconds to the date interval.
* The resulting number of seconds may not be a negative number, or an exception will be thrown.
*
* @param int $seconds [optional] The number of seconds to add.
*
* @return static The DateTime instance for method chaining.
*
* @throws DomainException|Exception Throws an exception on failure.
*/
public function addSecond($seconds = 1) {
return $this->addSeconds($seconds);
}
/**
* Subtract the given number of seconds to the date interval.
* The resulting number of seconds may not be a negative number, or an exception will be thrown.
*
* @param int $seconds [optional] The number of seconds to subtract.
*
* @return static The DateTime instance for method chaining.
*
* @throws DomainException|Exception Throws an exception on failure.
*/
public function subSeconds($seconds = 1) {
// Make sure the seconds parameter is an integer
if(!is_int($seconds))
throw new \DomainException('Invalid value for seconds, must be an integer (\'' . $seconds . '\' was given)');
// Subtract the number of seconds, return the result
return $this->addSeconds($seconds * -1);
}
/**
* Subtract one, or the given number of seconds to the date interval.
* The resulting number of seconds may not be a negative number, or an exception will be thrown.
*
* @param int $seconds [optional] The number of seconds to subtract.
*
* @return static The DateTime instance for method chaining.
*
* @throws DomainException|Exception Throws an exception on failure.
*/
public function subSecond($seconds = 1) {
return $this->subSeconds($seconds);
}
/**
* Set the number of seconds.
*
* @param int $seconds The number of seconds, must be zero or a positive number.
*
* @return static The DateTime instance for method chaining.
*
* @throws \DomainException Throws an exception on failure.
*/
public function setSeconds($seconds) {
// Make sure the value is a positive number or zero
if(!is_int($seconds) || $seconds < 0)
throw new \DomainException('Invalid value for seconds, must be zero or a positive number (\'' . $seconds . '\' was given)');
// Set the seconds, return this instance
$this->s = $seconds;
return $this;
}
/**
* Check whether the date interval is inverted.
*
* @return bool True if the date interval is inverted, false if not.
*/
public function isInverted() {
return $this->invert !== 0;
}
/**
* Set whether the date interval is inverted.
*
* @param int|bool $inverted One or true if the date interval is inverted, zero or false if not.
*
* @return static This DateInterval instance.
*/
public function setInverted($inverted) {
// Parse the parameter value
$inverted = empty($inverted) ? 0 : 1;
// Set whether the interval is inverted, return this instance
$this->invert = $inverted;
return $this;
}
/**
* Get the day span of this interval. This only works for objects created with DateTime::diff().
*
* @return int|null The day span of this interval, or null on failure.
*/
public function getDaySpan() {
return $this->isCreatedFromDiff() ? $this->days : null;
}
/**
* Check whether this is a zero date interval.
*
* @return bool True if this date interval is zero, false if not.
*/
public function isZero() {
return ($this->getYears() == 0 && $this->getMonths() == 0 && $this->getDays() == 0 &&
$this->getHours() == 0 && $this->getMinutes() == 0 && $this->getSeconds() == 0);
}
/**
* Check whether this date time object was created using DateTime::diff() or PHPDateTime::diff().
*
* @return bool True if this date interval object was created by a diff() method, false if not. If the date interval isn't an instance of DateInterval false will also be returned.
*/
public function isCreatedFromDiff() {
return DateIntervalUtils::isCreatedFromDiff($this);
}
/**
* Add the passed interval of the current instance
*
* @param PHPDateInterval|PHPDateInterval|string|null $dateInterval The DateInterval or PHPDateInterval instance, the date interval specification as a string or null to use a zero specification.
*
* @return static|null This DateInterval instance for method chaining, or null on failure.
*/
public function add($dateInterval) {
// Parse the date interval, return null on failure
if(($dateInterval = static::parse($dateInterval)) === null)
return null;
// Calculate the factor to multiply each value with
$factor = $dateInterval->isInverted() ? -1 : 1;
/*if(DateIntervalUtils::isCreatedFromDiff($dateInterval))
$this->setDays($this->getDays() + ($dateInterval->getDaySpan() * $factor));
else*/
// Add the date and time
$this->addDateTime(
$dateInterval->getYears() * $factor,
$dateInterval->getMonths() * $factor,
null,
$dateInterval->getDays() * $factor,
$dateInterval->getHours() * $factor,
$dateInterval->getMinutes() * $factor,
$dateInterval->getSeconds() * $factor);
// Return this instance
return $this;
}
/**
* Subtract the passed interval of the current instance.
*
* @param PHPDateInterval|PHPDateInterval|string|null $dateInterval The DateInterval or PHPDateInterval instance, the date interval specification as a string or null to use a zero specification.
*
* @return static|null This DateInterval instance for method chaining, or null on failure.
*/
public function sub($dateInterval) {
// Parse the date interval as a new instance, return null on failure
if(($dateInterval = static::instance($dateInterval)) === null)
return null;
// Invert the date interval
$dateInterval->setInverted(!$dateInterval->isInverted());
// Subtract and return the result
return $this->add($dateInterval);
}
/**
* Create a ISO-8601 date interval specification string.
*
* @return string The date interval specification string.
*/
public function toSpecString() {
return DateIntervalSpecUtils::create($this->getYears(), $this->getMonths(), null, $this->getDays(), $this->getHours(), $this->getMinutes(), $this->getSeconds());
}
/**
* Get the date interval as a string.
*
* @return string The date interval string.
*/
public function toString() {
return $this->toSpecString();
}
// TODO: toString() for humans!
/**
* Get the date interval as a string.
*
* @return string The date interval string.
*/
public function __toString() {
return ($result = $this->toString()) === null ? '' : $result;
}
// TODO: Create a wrapper for createFromDateString();
/*
/**
* Get a date interval attribute.
*
* @param string $name The name of the attribute to get.
*
* @return int The value of the getter.
*
* @throws \InvalidArgumentException Throws an exception on failure.
* /
public function __get($name) {
// Get the number of years
if(StringUtils::equals($name, 'years', true))
return $this->getYears();
// Get the number of months
if(StringUtils::equals($name, 'months', true))
return $this->getMonths();
// Get the number of days
if(StringUtils::equals($name, 'days', true))
return $this->getDays();
// Get the number of hours
if(StringUtils::equals($name, 'hours', true))
return $this->getHours();
// Get the number of minutes
if(StringUtils::equals($name, 'minutes', true))
return $this->getMinutes();
// Get the number of seconds
if(StringUtils::equals($name, 'seconds', true))
return $this->getSeconds();
switch($name) {
case 'weeks':
return (int) floor($this->d / DateTime::DAYS_PER_WEEK);
case 'daysExcludeWeeks':
return $this->d % DateTime::DAYS_PER_WEEK;
default:
throw new \InvalidArgumentException('Unknown getter \'' . $name . '\'');
}
}
/**
* Set an attribute of the date interval object.
*
* @param string $name The name of the attribute to set.
* @param int $value The value to set the attribute to.
*
* @return static The DateTime instance.
*
* @throws \InvalidArgumentException Throw an exception on failure.
* /
public function __set($name, $value) {
// Set the number of years
if(StringUtils::equals($name, 'years', true))
return $this->setYears($value);
// Set the number of months
if(StringUtils::equals($name, 'months', true))
return $this->setMonths($value);
// Set the number of days
if(StringUtils::equals($name, 'days', true))
return $this->setDays($value);
// Set the number of hours
if(StringUtils::equals($name, 'hours', true))
return $this->setHours($value);
// Set the number of minutes
if(StringUtils::equals($name, 'minutes', true))
return $this->setMInutes($value);
// Set the number of seconds
if(StringUtils::equals($name, 'seconds', true))
return $this->setSeconds($value);
switch ($name) {
case 'weeks':
$this->d = $value * DateTime::DAYS_PER_WEEK;
break;
}
}
/**
* Allow fluent calls on the setters. CarbonInterval::years(3)->months(5)->day().
*
* Note: This is done using the magic method to allow static and instance methods to have the same names.
*
* @param string $name The name of the method being called.
* @param Array $args An array of method parameters.
*
* @return static The DateTime instance, which could be used for method chaining.
* /
public function __call($name, $args) {
// Get the delimiter value
$arg = count($args) == 0 ? 1 : $args[0];
// Handle the years setter
if(StringUtils::equals($name, Array('years', 'year'), true)) {
$this->years = $arg;
return $this;
}
// Handle the months setter
if(StringUtils::equals($name, Array('months', 'month'), true)) {
$this->months = $arg;
return $this;
}
// Handle the weeks setter
if(StringUtils::equals($name, Array('weeks', 'week'), true)) {
$this->days = $arg * DateTime::DAYS_PER_WEEK;
return $this;
}
// Handle the days setter
if(StringUtils::equals($name, Array('days', 'day'), true)) {
$this->days = $arg;
return $this;
}
// Handle the hours setter
if(StringUtils::equals($name, Array('hours', 'hour'), true)) {
$this->hours = $arg;
return $this;
}
// Handle the minutes setter
if(StringUtils::equals($name, Array('minutes', 'minute'), true)) {
$this->minutes = $arg;
return $this;
}
// Handle the seconds setter
if(StringUtils::equals($name, Array('seconds', 'second'), true)) {
$this->seconds = $arg;
return $this;
}
// Return this instance
return $this;
}
/**
* Provide static helpers to create instances.
* Allows CarbonInterval::years(3).
*
* Note: This is done using the magic method to allow static and instance methods to have the same names.
*
* @param string $name The name of the static method being called.
* @param Array $args An array of method parameters.
*
* @return static The DateInterval instance.
* /
public static function __callStatic($name, $args) {
// Get the delimiter value if any argument has been given
$delimiterValue = count($args) == 0 ? 1 : $args[0];
// Handle the years delimiter
if(StringUtils::equals($name, Array('years', 'year'), true))
return DateIntervalFactory::create($delimiterValue);
// Handle the months delimiter
if(StringUtils::equals($name, Array('months', 'month'), true))
return DateIntervalFactory::create(null, $delimiterValue);
// Handle the weeks delimiter
if(StringUtils::equals($name, Array('weeks', 'week'), true))
return DateIntervalFactory::create(null, null, $delimiterValue);
// Handle the days delimiter
if(StringUtils::equals($name, Array('days', 'day'), true))
return DateIntervalFactory::create(null, null, null, $delimiterValue);
// Handle the hours delimiter
if(StringUtils::equals($name, Array('hours', 'hour'), true))
return DateIntervalFactory::create(null, null, null, null, $delimiterValue);
// Handle the minutes delimiter
if(StringUtils::equals($name, Array('minutes', 'minute'), true))
return DateIntervalFactory::create(null, null, null, null, null, $delimiterValue);
// Handle the seconds delimiter
if(StringUtils::equals($name, Array('seconds', 'second'), true))
return DateIntervalFactory::create(null, null, null, null, null, null, $delimiterValue);
}
*/
}
<?php
namespace carbon\core\datetime\interval;
// Prevent direct requests to this set_file due to security reasons
defined('CARBON_CORE_INIT') or die('Access denied!');
class DateIntervalFactory {
// TODO: Make sure all DateTime and PHPDateTime instances are correct!
/**
* Create a new DateInterval instance from specific values.
*
* @param int $years [optional] The number of years, or null to ignore this value.
* @param int $months [optional] The number of months, or null to ignore this value.
* @param int $weeks [optional] The number of weeks, or null to ignore this value.
* @param int $days [optional] The number of days, or null to ignore this value.
* @param int $hours [optional] The number of hours, or null to ignore this value.
* @param int $minutes [optional] The number of minutes, or null to ignore this value.
* @param int $seconds [optional] The number of seconds, or null to ignore this value.
* @param bool $inverted [optional] Define whether the date interval is inverted or not.
* @param mixed|null $default [optional] The default value returned on failure.
*
* @return DateInterval|mixed A new DateInterval instance, or the default value on failure.
*/
public static function create($years = null, $months = null, $weeks = null, $days = null, $hours = null, $minutes = null, $seconds = null, $inverted = false, $default = null) {
// Create the specification, and make sure it's valid
if(($spec = DateIntervalSpecUtils::create($years, $months, $weeks, $days, $hours, $minutes, $seconds)) === null)
return $default;
// Construct the DateInterval object
return new DateInterval($spec, $inverted);
}
/**
* Get a date interval object of zero.
*
* @return DateInterval|null The DateInterval object.
*/
public static function zero() {
return static::create();
}
/**
* Get a date interval object for one, or the given number of years.
*
* @param int $years [optional] The number of years. Null to use one year.
* @param bool $inverted [optional] True to invert the date interval, false if not.
* @param mixed|null $default [optional] The default value returned on failure.
*
* @return DateInterval|mixed The DateInterval instance, or the default value on failure.
*/
public static function year($years = 1, $inverted = false, $default = null) {
// Parse the year parameter, and make sure it's valid
if($years === null)
$years = 1;
// Create and return a new DateInterval instance, or return the default value on failure
return static::create(null, null, null, $years, null, null, null, $inverted, $default);
}
/**
* Alias of year();
*
* Get a date interval object for one, or the given number of years.
*
* @param int $years [optional] The number of years. Null to use one year.
* @param bool $inverted [optional] True to invert the date interval, false if not.
* @param mixed|null $default [optional] The default value returned on failure.
*
* @return DateInterval|mixed The DateInterval instance, or the default value on failure.
*/
public static function years($years = 1, $inverted = false, $default = null) {
return static::year($years, $inverted, $default);
}
/**
* Get a date interval object for one, or the given number of months.
*
* @param int $months [optional] The number of months. Null to use one month.
* @param bool $inverted [optional] True to invert the date interval, false if not.
* @param mixed|null $default [optional] The default value returned on failure.
*
* @return DateInterval|mixed The DateInterval instance, or the default value on failure.
*/
public static function month($months = 1, $inverted = false, $default = null) {
// Parse the month parameter, and make sure it's valid
if($months === null)
$months = 1;
// Create and return a new DateInterval instance, or return the default value on failure
return static::create(null, null, null, $months, null, null, null, $inverted, $default);
}
/**
* Alias of month();
*
* Get a date interval object for one, or the given number of months.
*
* @param int $months [optional] The number of months. Null to use one month.
* @param bool $inverted [optional] True to invert the date interval, false if not.
* @param mixed|null $default [optional] The default value returned on failure.
*
* @return DateInterval|mixed The DateInterval instance, or the default value on failure.
*/
public static function months($months = 1, $inverted = false, $default = null) {
return static::month($months, $inverted, $default);
}
/**
* Get a date interval object for one, or the given number of weeks.
*
* @param int $weeks [optional] The number of weeks. Null to use one week.
* @param bool $inverted [optional] True to invert the date interval, false if not.
* @param mixed|null $default [optional] The default value returned on failure.
*
* @return DateInterval|mixed The DateInterval instance, or the default value on failure.
*/
public static function week($weeks = 1, $inverted = false, $default = null) {
// Parse the week parameter, and make sure it's valid
if($weeks === null)
$weeks = 1;
// Create and return a new DateInterval instance, or return the default value on failure
return static::create(null, null, null, $weeks, null, null, null, $inverted, $default);
}
/**
* Alias of week();
*
* Get a date interval object for one, or the given number of weeks.
*
* @param int $weeks [optional] The number of weeks. Null to use one week.
* @param bool $inverted [optional] True to invert the date interval, false if not.
* @param mixed|null $default [optional] The default value returned on failure.
*
* @return DateInterval|mixed The DateInterval instance, or the default value on failure.
*/
public static function weeks($weeks = 1, $inverted = false, $default = null) {
return static::week($weeks, $inverted, $default);
}
/**
* Get a date interval object for one, or the given number of days.
*
* @param int $days [optional] The number of days. Null to use one day.
* @param bool $inverted [optional] True to invert the date interval, false if not.
* @param mixed|null $default [optional] The default value returned on failure.
*
* @return DateInterval|mixed The DateInterval instance, or the default value on failure.
*/
public static function day($days = 1, $inverted = false, $default = null) {
// Parse the day parameter, and make sure it's valid
if($days === null)
$days = 1;
// Create and return a new DateInterval instance, or return the default value on failure
return static::create(null, null, null, $days, null, null, null, $inverted, $default);
}
/**
* Alias of day();
*
* Get a date interval object for one, or the given number of days.
*
* @param int $days [optional] The number of days. Null to use one day.
* @param bool $inverted [optional] True to invert the date interval, false if not.
* @param mixed|null $default [optional] The default value returned on failure.
*
* @return DateInterval|mixed The DateInterval instance, or the default value on failure.
*/
public static function days($days = 1, $inverted = false, $default = null) {
return static::day($days, $inverted, $default);
}
/**
* Get a date interval object for one, or the given number of hours.
*
* @param int $hours [optional] The number of hours. Null to use one hour.
* @param bool $inverted [optional] True to invert the date interval, false if not.
* @param mixed|null $default [optional] The default value returned on failure.
*
* @return DateInterval|mixed The DateInterval instance, or the default value on failure.
*/
public static function hour($hours = 1, $inverted = false, $default = null) {
// Parse the hour parameter, and make sure it's valid
if($hours === null)
$hours = 1;
// Create and return a new DateInterval instance, or return the default value on failure
return static::create(null, null, null, $hours, null, null, null, $inverted, $default);
}
/**
* Alias of hour();
*
* Get a date interval object for one, or the given number of hours.
*
* @param int $hours [optional] The number of hours. Null to use one hour.
* @param bool $inverted [optional] True to invert the date interval, false if not.
* @param mixed|null $default [optional] The default value returned on failure.
*
* @return DateInterval|mixed The DateInterval instance, or the default value on failure.
*/
public static function hours($hours = 1, $inverted = false, $default = null) {
return static::hour($hours, $inverted, $default);
}
/**
* Get a date interval object for one, or the given number of minutes.
*
* @param int $minutes [optional] The number of minutes. Null to use one minute.
* @param bool $inverted [optional] True to invert the date interval, false if not.
* @param mixed|null $default [optional] The default value returned on failure.
*
* @return DateInterval|mixed The DateInterval instance, or the default value on failure.
*/
public static function minute($minutes = 1, $inverted = false, $default = null) {
// Parse the minute parameter, and make sure it's valid
if($minutes === null)
$minutes = 1;
// Create and return a new DateInterval instance, or return the default value on failure
return static::create(null, null, null, $minutes, null, null, null, $inverted, $default);
}
/**
* Alias of minute();
*
* Get a date interval object for one, or the given number of minutes.
*
* @param int $minutes [optional] The number of minutes. Null to use one minute.
* @param bool $inverted [optional] True to invert the date interval, false if not.
* @param mixed|null $default [optional] The default value returned on failure.
*
* @return DateInterval|mixed The DateInterval instance, or the default value on failure.
*/
public static function minutes($minutes = 1, $inverted = false, $default = null) {
return static::minute($minutes, $inverted, $default);
}
/**
* Get a date interval object for one, or the given number of seconds.
*
* @param int $seconds [optional] The number of seconds. Null to use one second.
* @param bool $inverted [optional] True to invert the date interval, false if not.
* @param mixed|null $default [optional] The default value returned on failure.
*
* @return DateInterval|mixed The DateInterval instance, or the default value on failure.
*/
public static function second($seconds = 1, $inverted = false, $default = null) {
// Parse the second parameter, and make sure it's valid
if($seconds === null)
$seconds = 1;
// Create and return a new DateInterval instance, or return the default value on failure
return static::create(null, null, null, $seconds, null, null, null, $inverted, $default);
}
/**
* Alias of second();
*
* Get a date interval object for one, or the given number of seconds.
*
* @param int $seconds [optional] The number of seconds. Null to use one second.
* @param bool $inverted [optional] True to invert the date interval, false if not.
* @param mixed|null $default [optional] The default value returned on failure.
*
* @return DateInterval|mixed The DateInterval instance, or the default value on failure.
*/
public static function seconds($seconds = 1, $inverted = false, $default = null) {
return static::second($seconds, $inverted, $default);
}
}
<?php
namespace carbon\core\datetime\interval;
// Prevent direct requests to this set_file due to security reasons
defined('CARBON_CORE_INIT') or die('Access denied!');
class DateIntervalSet {
private $intervals = Array();
// TODO: Create this class!
}
<?php
namespace carbon\core\datetime\interval;
use carbon\core\datetime\DateTime;
// Prevent direct requests to this set_file due to security reasons
defined('CARBON_CORE_INIT') or die('Access denied!');
class DateIntervalSpecUtils {
// TODO: Make sure all DateTime and PHPDateTime instances are correct!
/**
* Defines the regex to use to validate a date interval specification string according to ISO-8601.
*
* @const string The date interval validation regex.
*/
const DATE_INTERVAL_SPEC_REGEX = '/^\s*P((((([0-9]+Y([0-9]+M)?([0-9]+[DW])?)|([0-9]+M([0-9]+[DW])?)|([0-9]+[DW]))(T(([0-9]+H([0-9]+M)?([0-9]+S)?)|([0-9]+M([0-9]+S)?)|([0-9]+S)))?|(T(([0-9]+H([0-9]+M)?([0-9]+S)?)|([0-9]+M([0-9]+S)?)|([0-9]+S)))))|(([0-9]{4}-(0[0-9]|1[0-2])-([0-2][0-9]|3[0-1]))T(([0-1][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9])))\s*$/';
/**
* Create a date interval specification based on the given parameters.
*
* @param int|null $years [optional] The number of years, must be zero or a positive number. Null to ignore this value.
* @param int|null $months [optional] The number of months, must be zero or a positive number. Null to ignore this value.
* @param int|null $weeks [optional] The number of weeks, must be zero or a positive number. Null to ignore this value. The weeks are converted into days.
* @param int|null $days [optional] The number of days, must be zero or a positive number. Null to ignore this value.
* @param int|null $hours [optional] The number of hours, must be zero or a positive number. Null to ignore this value.
* @param int|null $minutes [optional] The number of minutes, must be zero or a positive number. Null to ignore this value.
* @param int|null $seconds [optional] The number of seconds, must be zero or a positive number. Null to ignore this value.
*
* @return string|null The date interval spec as a string, or null on failure.
*/
public static function create($years = null, $months = null, $weeks = null, $days = null, $hours = null, $minutes = null, $seconds = null) {
// Build the date interval specification string
$dateIntervalSpec = DateInterval::PERIOD_PREFIX;
// Check whether the weeks parameter is used, append the number of days
if(!empty($weeks))
$days += (int) ($weeks * DateTime::DAYS_PER_WEEK);
// Reading all non-zero date parts
$date = array_filter(array(
DateInterval::PERIOD_YEARS => $years,
DateInterval::PERIOD_MONTHS => $months,
DateInterval::PERIOD_DAYS => $days
));
// Reading all non-zero time parts
$time = array_filter(array(
DateInterval::PERIOD_HOURS => $hours,
DateInterval::PERIOD_MINUTES => $minutes,
DateInterval::PERIOD_SECONDS => $seconds
));
// Make sure at least one part is available
if(empty($date) && empty($time))
$date = array(DateInterval::PERIOD_YEARS => 0);
// Append each date part to the specification string
foreach($date as $key => $value)
$dateIntervalSpec .= $value . $key;
// Append each time part to the specification string if available
if(!empty($time)) {
// Prefix the time designator
$dateIntervalSpec .= DateInterval::PERIOD_TIME_PREFIX;
// Append each time part to the specification string
foreach($time as $key => $value)
$dateIntervalSpec .= $value . $key;
}
// Return the spec if it's valid, return null otherwise
return static::isValid($dateIntervalSpec) ? $dateIntervalSpec : null;
}
/**
* Validate whether a date interval specification string is valid or not based on ISO-8601.
*
* @param string $dateIntervalSpec The date interval specification string to validate.
*
* @return bool True if the date interval specification is valid, false otherwise.
*/
public static function isValid($dateIntervalSpec) {
// Make sure the param is a string
if(!is_string($dateIntervalSpec))
return false;
// Check whether the specification is valid using a regular expression, return the result
return preg_match(static::DATE_INTERVAL_SPEC_REGEX, $dateIntervalSpec) > 0;
}
}
<?php
namespace carbon\core\datetime\interval;
use DateInterval as PHPDateInterval;
// Prevent direct requests to this set_file due to security reasons
defined('CARBON_CORE_INIT') or die('Access denied!');
class DateIntervalUtils {
// TODO: Make sure all DateTime and PHPDateTime instances are correct!
/**
* Before PHP 5.4.20/5.5.4 instead of false days will be set to -99999 when the interval instance was created by DateTime:diff().
*
* @const int The old PHP false value of days.
*/
const PHP_OLD_FALSE_DAYS = -99999;
/**
* Parse a date interval. A new instance may be created.
*
* This method allows better fluent syntax because it makes method chaining possible.
*
* @param DateInterval|PHPDateInterval|string|null $dateInterval [optional] A DateInterval or PHPDateInterval instance, a date interval specification, or null to use a zero specification.
* @param mixed|null $default [optional] The default value to be returned on failure.
*
* @return static|mixed A DateInterval instance, or the default value on failure.
*/
public static function parse($dateInterval, $default = null) {
return ($result = DateInterval::parse($dateInterval)) === null ? $default : $result;
}
/**
* Check whether this date time object was created using DateTime::diff() or PHPDateTime::diff().
*
* @param DateInterval|PHPDateInterval $dateInterval The DateInterval or PHPDateInterval instance.
*
* @return bool True if this date interval object was created by a diff() method, false if not. If the date interval isn't an instance of DateInterval false will also be returned.
*/
// TODO: Improve the performance of this method, just check whether it's false or -99999?
public static function isCreatedFromDiff($dateInterval) {
// Make sure the date interval isn't null
if($dateInterval == null)
return false;
// Make sure the date interval is a DateInterval or PHPDateInterval instance
if(!($dateInterval instanceof PHPDateInterval))
return false;
// Get the value to compare the days to, this differs depending on the installed PHP version
$compareTo = (
version_compare(phpversion(), '5.4.20', '<') ||
(version_compare(phpversion(), '5.0', '>=') && version_compare(phpversion(), '5.5.4', '<'))
) ? static::PHP_OLD_FALSE_DAYS : false;
// Make sure the number of days, return the result
return $dateInterval->days != $compareTo;
}
}
<?php
namespace carbon\core\datetime\period;
use DatePeriod as PHPDatePeriod;
// Prevent direct requests to this set_file due to security reasons
defined('CARBON_CORE_INIT') or die('Access denied!');
class DatePeriod extends PHPDatePeriod {
// TODO: Parse method!
}
<?php
/**
* DateTime.php
*
* A class to representation date and time as an object.
* This class allows you to get the current date and time of the server, to format the date and time in many different
* ways using different timezones and also to travel through time.
* Note: Even though this class uses futuristic technology to make date and time calculations, it doesn't allow humans
* to travel through time.
*
* @author Tim Visee
* @website http://timvisee.com/
* @copyright Copyright (c) Carbon CMS 2015. All rights reserved.
*/
namespace carbon\core\datetime;
use carbon\core\datetime\interval\DateInterval;
use carbon\core\datetime\period\DatePeriod;
use carbon\core\datetime\zone\DateTimeZone;
use carbon\core\datetime\zone\DateTimeZoneUtils;
use carbon\core\util\StringUtils;
use Closure;
use DateTime as PHPDateTime;
use DateTimeZone as PHPDateTimeZone;
// Prevent direct requests to this file due to security reasons
defined('CARBON_CORE_INIT') or die('Access denied!');
/**
* A class to represent, format and transform date and time.
*
* Used the Carbon DateTime library as basis for this class.
*
* @package carbon\core\datetime
*
* @property int $year The year.
* @property int $yearIso The ISO year.
* @property int $month The month.
* @property int $day The day.
* @property int $hour The hour.
* @property int $minute The minute.
* @property int $second The second.
* @property int $timestamp seconds since the Unix Epoch
* @property DateTimeZone|PHPDateTimeZone|string|DateTime|PHPDateTime|null $timezone A DateTimeZone or PHPDateTimeZone instance, the timezone ID as a string, a DateTime or PHPDateTime instance to use it's timezone or null to use the default timezone.
* @property DateTimeZone $tz Alias of $timezone.
* @property-read int $micro Read the number of micro seconds.
* @property-read int $dayOfWeek Get the day of the week as a number, 0 (for Sunday) through 6 (for Saturday).
* @property-read int $dayOfYear Get the day of the year, 0 through 365.
* @property-read int $weekOfMonth Get the week of the month, 1 through 5.
* @property-read int $weekOfYear Get the ISO-8601 week number of year, weeks starting on Monday.
* @property-read int $daysInMonth Get the number of days in the given month.
* @property-read int $age Get the number of years passed since now().
* @property-read int $quarter Get the the quarter of this instance, from 1 to 4.
* @property-read int $offset Get the timezone offset in seconds from UTC.
* @property-read int $offsetHours Get the timezone offset in hours from UTC.
* @property-read bool $dst Check whether daylight saving time is enabled, true if DST, false otherwise.
* @property-read bool $local Check whether the timezone is local, true if local, false otherwise.
* @property-read bool $utc Check whether the timezone is UTC, true if UTC, false otherwise.
* @property-read string $timezoneName Get the timezone name or ID.
* @property-read string $tzName Alias for $timezoneName.
*/
class DateTime extends PHPDateTime {
// TODO: Does this class have support for all date's, (an almost-infinite range)!
// TODO: Return null on failure, instead of false, for everything?
// TODO: Create a class for DateInterval, with the possibility to add or subtract from this date and time.
// TODO: Option to set a preferred parsing format?
// TODO: Support for all types of calendars!
// TODO: Add the possibility to extend this class, with some functions, closures and so on.
// TODO: Make sure the mock DateTime is used everywhere it's needed, such as the now(); method!
// TODO: Add proper exceptions for everything!
// TODO: Should we overwrite all/most methods provided by the base class.
// TODO: Should we name these differently, because the name is currently the same as PHP's classes
// TODO: Make sure all DateTime and PHPDateTime instances are correct!
/**
* The day constant for sunday, this defines an integer for this week day.
*
* @const int Day index.
*/
const SUNDAY = 0;
/**
* The day constant for monday, this defines an integer for this week day.
*
* @const int Day index.
*/
const MONDAY = 1;
/**
* The day constant for tuesday, this defines an integer for this week day.
*
* @const int Day index.
*/
const TUESDAY = 2;
/**
* The day constant for wednesday, this defines an integer for this week day.
*
* @const int Day index.
*/
const WEDNESDAY = 3;
/**
* The day constant for thursday, this defines an integer for this week day.
*
* @const int Day index.
*/
const THURSDAY = 4;
/**
* The day constant for friday, this defines an integer for this week day.
*
* @const int Day index.
*/
const FRIDAY = 5;
/**
* The day constant for saturday, this defines an integer for this week day.
*
* @const int Day index.
*/
const SATURDAY = 6;
/**
* Define the names of each weekday as an array, indexed by the day constants.
*
* @var Array An array containing all weekday names.
*/
protected static $DAY_NAMES = array(
self::SUNDAY => 'Sunday',
self::MONDAY => 'Monday',
self::TUESDAY => 'Tuesday',
self::WEDNESDAY => 'Wednesday',
self::THURSDAY => 'Thursday',
self::FRIDAY => 'Friday',
self::SATURDAY => 'Saturday'
);
/**
* Terms used to detect if a time passed is a relative date for testing purposes.
*
* @var Array An array of relative keywords.
*/
protected static $RELATIVE_KEYWORDS = Array(
'this',
'next',
'last',
'tomorrow',
'yesterday',
'+',
'-',
'first',
'last',
'ago'
);
/**
* Defines the format to use for most getter names.
*
* @var Array An array of getter formats.
*/
protected static $GETTER_FORMATS = Array(
'year' => 'Y',
'yearIso' => 'o',
'month' => 'n',
'day' => 'j',
'hour' => 'G',
'minute' => 'i',
'second' => 's',
'micro' => 'u',
'dayOfWeek' => 'w',
'dayOfYear' => 'z',
'weekOfYear' => 'W',
'daysInMonth' => 't',
'timestamp' => 'U'
);
// TODO: Move this stuff to a DateTimeUnits class?
/**
* Defines the years per century, for time calculations.
*
* @const int Years per century.
*/
const YEARS_PER_CENTURY = 100;
/**
* Defines the years per decade, for time calculations.
*
* @const int Years per decade.
*/
const YEARS_PER_DECADE = 10;
/**
* Defines the months per year, for time calculations.
*
* @const int Months per year.
*/
const MONTHS_PER_YEAR = 12;
/**
* Defines the weeks per year, for time calculations.
*
* @const int Weeks per year.
*/
const WEEKS_PER_YEAR = 52;
/**
* Defines the days per week, for time calculations.
*
* @const int Days per week.
*/
const DAYS_PER_WEEK = 7;
/**
* Defines the hours per day, for time calculations.
*
* @const int Hours per day.
*/
const HOURS_PER_DAY = 24;
/**
* Defines the minutes per hour, for time calculations.
*
* @const int Minutes per hour.
*/
const MINUTES_PER_HOUR = 60;
/**
* Defines the seconds per minute, for time calculations.
*
* @const int Seconds per minute.
*/
const SECONDS_PER_MINUTE = 60;
/**
* Defines the default date format used when date and time is represented as a string.
*
* @const string The default date and time format.
*/
const DEFAULT_FORMAT = 'Y-m-d H:i:s';
/**
* Defines the default date format used when a date is represented as a string.
*
* @const string The default date format.
*/
const DEFAULT_FORMAT_DATE = 'Y-m-d';
/**
* Defines the default time format used when time is represented as a string.
*
* @const string The default time format.
*/
const DEFAULT_FORMAT_TIME = 'H:i:s';
/**
* Defines the default date and time format that includes everything in the string.
*
* @const string The default complete date and time format.
*/
// TODO: Give this constant a proper name!
const DEFAULT_FORMAT_COMPLETE = 'Y-m-d H:i:s.u e O';
/**
* An optional mock DateTime instance to return when the now() method is called.
*
* @var DateTime The mock DateTime instance, or null to use the default.
*/
protected static $mockNow;
/**
* Constructor.
*
* @param string|DateTime|PHPDateTime $dateTime [optional] The date and time as a string, the date and time as DateTime or PHPDateTime instance or null to use the current time.
* @param DateTimeZone|PHPDateTimeZone|string|DateTime|PHPDateTime $timezone [optional] The timezone the specified time is in, or null to use the default timezone. A DateTime or PHPDateTime instance to use it's timezone.
*
* @throws \Exception Throws an exception on failure.
*/
public function __construct($dateTime = null, $timezone = null) {
// Parse the timezone if it isn't null and make sure it's valid
if($timezone !== null)
if(($timezone = DateTimeZoneUtils::parse($timezone, null)) === null)
// TODO: Add a better exception, with a better description!
throw new \Exception('Invalid timezone!');
// Handle DateTime instances
if($dateTime instanceof DateTime) {
// Construct the parent object with the proper properties
parent::__construct($dateTime->toCompleteString(), $dateTime->getTimezone());
return $this;
}
// Handle PHPDateTime instances
if($dateTime instanceof PHPDateTime) {
// Construct the parent object with the proper properties
parent::__construct($dateTime->format(self::DEFAULT_FORMAT_COMPLETE), $dateTime->getTimezone());
return $this;
}
// Check whether we should use the now time
if(empty($dateTime) || StringUtils::equals($dateTime, 'now', false))
// Return a new instance of the mock time if set
if(static::hasMockNow())
return clone static::getMockNow();
// Check whether the time contains relative keywords
if(static::hasRelativeKeywords($dateTime)) {
// Get a new DateTime instance, and modify the date and time according to the time parameter
$dateTime = static::now()->modify($dateTime);
// Shift the timezone if it's set
if($timezone !== null && !$timezone->equals(static::getMockNow()))
$dateTime->setTimezone($timezone);
else
$timezone = $dateTime->getTimezone();
// Update the time parameter with the modified time
$dateTime = $dateTime->toCompleteString();
}
// Construct the parent object
parent::__construct($dateTime, $timezone);
return $this;
}
/**
* Create a copy of a DateTime instance.
*
* @param DateTime $other The other instance.
*
* @return static The new DateTime instance.
*/
// TODO: Parse the parameter for better flexibility, make sure an instance isn't created twice.
public static function instance(DateTime $other) {
return new static($other->format(self::DEFAULT_FORMAT_COMPLETE), $other->getTimeZone());
}
/**
* Create a copy of this DateTime instance.
*
* @return static A new DateTime zone instance.
*/
public function copy() {
return static::instance($this);
}
/**
* Create a copy of this DateTime instance. Called by PHP when the DateTime object is cloned.
*
* @return static A new DateTime zone instance
*/
public function __clone() {
return $this->copy();
}
/**
* Parse date and time with a specific timezone. A new instance may be created if required.
*
* If the $time parameter is a DateTime zone instance, the instance will be returned and the $timezone parameter is ignored.
* If the $time parameter is anything other than a DateTime zone the date, time and the timezone is parsed through the constructor.
*
* This method allows better fluent syntax because it makes method chaining possible.
*
* @param DateTime|string|null $dateTime [optional] A DateTime instance, the time as a string, or null to use the current time.
* @param DateTimeZone|PHPDateTimeZone|string|DateTime|PHPDateTime|null $timezone [optional] The timezone the specified time is in, or null to use the default timezone if the $time param isn't a DateTime instance. A DateTime or PHPDateTime instance to use it's timezone.
*
* @return DateTime|null The parsed DateTime instance, or null on failure.
*/
// TODO: Should we move the parse code to this class, instead of the utils class?
public static function parse($dateTime = null, $timezone = null) {
return DateTimeUtils::parse($dateTime, $timezone, null);
}
/**
* Create a DateTime instance for the current date and time.
*
* @param DateTimeZone|PHPDateTimeZone|string $timezone [optional] The preferred timezone to use, or null to use the default timezone.
* @param bool $real [optional] True to return the real now() value which ignores the mock date and time, false to return the normal value.
*
* @return static The DateTime instance.
*/
public static function now($timezone = null, $real = false) {
// Check whether the regular or the real now should be returned
if(!$real)
return new static(null, $timezone);
return new static(new PHPDateTime('now', $timezone), $timezone);
}
/**
* Create a DateTime instance for the start of the current day.
*
* @param DateTimeZone|PHPDateTimeZone|string $timezone [optional] The preferred timezone to use, or null to use the default timezone.
* @param bool $real [optional] True to use the real now() value which ignores the mock date and time, false to return the normal value.
*
* @return static The DateTime instance.
*/
public static function today($timezone = null, $real = false) {
return static::now($timezone, $real)->startOfDay();
}
/**
* Create a DateTime instance for the start of tomorrow.
*
* @param DateTimeZone|PHPDateTimeZone|string $timezone [optional] The preferred timezone to use, or null to use the default timezone.
* @param bool $real [optional] True to use the real now() value which ignores the mock date and time, false to return the normal value.
*
* @return static The DateTime instance.
*/
public static function tomorrow($timezone = null, $real = false) {
return static::today($timezone, $real)->addDay();
}
/**
* Create a DateTime instance for the start of yesterday.
*
* @param DateTimeZone|PHPDateTimeZone|string $timezone [optional] The preferred timezone to use, or null to use the default timezone.
* @param bool $real [optional] True to use the real now() value which ignores the mock date and time, false to return the normal value.
*
* @return static The DateTime instance.
*/
public static function yesterday($timezone = null, $real = false) {
return static::today($timezone, $real)->subtractDay();
}
/**
* Create a DateTime instance for the greatest supported date and time.
*
* @return static The DateTime instance.
*/
public static function greatestDate() {
return static::createFromTimestamp(PHP_INT_MAX);
}
/**
* Create a DateTime instance for the lowest supported date and time.
*
* @return static The DateTime instance.
*/
public static function lowestDate() {
return static::createFromTimestamp(~PHP_INT_MAX);
}
/**
* Create a new DateTime instance from a specific date and time.
*
* If the $year, $month or $day parameters are set to null their now() value will be used.
*
* If $hour is null it will be set to its now() value and the default values for $minute and $second will be their now() values.
* If $hour is not null, then the default values for $minute and $second will be 0.
*
* @param int $year [optional] The specified year, or null to use the current year.
* @param int $month [optional] The specified month, or null to use the current month.
* @param int $day [optional] The specified day, or null to use the current day.
* @param int $hour [optional] The specified hour, or null to use the current hour.
* @param int $minute [optional] The specified minute, or null.
* @param int $second [optional] The specified second, or null.
* @param DateTimeZone|PHPDateTimeZone|string|DateTime|PHPDateTime|null $timezone [optional] The preferred timezone to use, or null to use the default timezone. A DateTime or PHPDateTime instance to use it's timezone.
*
* @return static The DateTime instance.
*/
// TODO: Does this method return null on some sort of failure?
// TODO: Redo this method!
// TODO: Does this only return full hours when no parameter is given?
public static function create($year = null, $month = null, $day = null, $hour = null, $minute = null, $second = null, $timezone = null) {
// Specify the date and time parts
$year = $year === null ? date('Y') : $year;
$month = $month === null ? date('n') : $month;
$day = $day === null ? date('j') : $day;
$hour = $hour === null ? date('G') : $hour;
$minute = $minute === null ? ($hour === null ? date('i') : 0) : $minute;
$second = $second === null ? ($hour === null ? date('s') : 0) : $second;
// Create a DateTime instance from the time parts
return static::createFromFormat('Y-n-j G:i:s', sprintf('%s-%s-%s %s:%02s:%02s', $year, $month, $day, $hour, $minute, $second), $timezone);
}
/**
* Create a DateTime instance with a specific date. The time portion is set to now.
*
* If the $year, $month or $day parameters are set to null their now() value will be used.
*
* @param int $year [optional] The specified year, or null to use the current year.
* @param int $month [optional] The specified month, or null to use the current month.
* @param int $day [optional] The specified day, or null to use the current day.
* @param DateTimeZone|PHPDateTimeZone|string $timezone The preferred timezone to use, or null to use the default timezone.
*
* @return static The DateTime instance.
*/
public static function createFromDate($year = null, $month = null, $day = null, $timezone = null) {
return static::create($year, $month, $day, null, null, null, $timezone);
}
/**
* Create a DateTime instance with a specific time. The date portion is set to today.
*
* If $hour is null it will be set to its now() value and the default values for $minute and $second will be their now() values.
* If $hour is not null, then the default values for $minute and $second will be 0.
*
* @param int $hour [optional] The specified hour, or null to use the current hour.
* @param int $minute [optional] The specified minute, or null.
* @param int $second [optional] The specified second, or null.
* @param DateTimeZone|PHPDateTimeZone|string $timezone The preferred timezone to use, or null to use the default timezone.
*
* @return static The DateTime instance.
*/
public static function createFromTime($hour = null, $minute = null, $second = null, $timezone = null) {
return static::create(null, null, null, $hour, $minute, $second, $timezone);
}
/**
* Create a DateTime instance from a string with a specified format.
*
* @param string $format The format used to parse the date time.
* @param string $time The date time to parse as a string.
* @param DateTimeZone|PHPDateTimeZone|string $timezone The preferred timezone to use, or null to use the default timezone.
*
* @return static The DateTime instance or null on failure.
*/
// TODO: Review this method!
public static function createFromFormat($format, $time, $timezone = null) {
// Try to create a DateTime instance based on the input
if($timezone !== null)
$dateTime = parent::createFromFormat($format, $time, DateTimeZoneUtils::safeCreateDateTimeZone($timezone));
else
$dateTime = parent::createFromFormat($format, $time);
// Make sure the object is valid
if($dateTime === false)
return null;
// Parse and return the date time
return self::parse($dateTime, $timezone);
}
/**
* Create a DateTime instance based on a Unix timestamp.
*
* @param int $timestamp The timestamp to get the DateTime instance for.
* @param DateTimeZone|PHPDateTimeZone|string $timezone The preferred timezone to use, or null to use the default timezone.
*
* @return static The DateTime instance, or null on failure.
*/
public static function createFromTimestamp($timestamp, $timezone = null) {
// Create a DateTime instance and make sure it's valid
if(($dateTime = static::now($timezone)->setTimestamp($timestamp)) === false)
return null;
// Return the DateTime instance
return $dateTime;
}
/**
* Create a DateTime instance based on a UTC timestamp.
*
* @param int $timestamp The UTC timestamp.
*
* @return static The DateTime instance.
*/
public static function createFromTimestampUTC($timestamp) {
return new static('@' . $timestamp);
}
/**
* Get the year.
*
* @return int The year.
*/
public function getYear() {
return (int) $this->format(static::$GETTER_FORMATS['year']);
}
/**
* Change the year.
*
* @param int $year The year.
*
* @return static|null A DateTime instance on success for method chaining, null on failure.
*/
public function setYear($year) {
// Set the year
try {
$this->year = $year;
return $this;
} catch(\Exception $ex) {
return null;
}
}
/**
* Get the month.
*
* @return int The month.
*/
public function getMonth() {
return (int) $this->format(static::$GETTER_FORMATS['month']);
}
/**
* Change the month.
*
* @param int $month The month.
*
* @return static|null A DateTime instance on success for method chaining, null on failure.
*/
public function setMonth($month) {
// Set the month
try {
$this->month = $month;
return $this;
} catch(\Exception $ex) {
return null;
}
}
/**
* Get the day.
*
* @return int The day.
*/
public function getDay() {
return (int) $this->format(static::$GETTER_FORMATS['day']);
}
/**
* Change the day.
*
* @param int $day The day.
*
* @return static|null A DateTime instance on success for method chaining, null on failure.
*/
public function setDay($day) {
// Set the day
try {
$this->day = $day;
return $this;
} catch(\Exception $ex) {
return null;
}
}
/**
* Get the hour.
*
* @return int The hour.
*/
public function getHour() {
return (int) $this->format(static::$GETTER_FORMATS['hour']);
}
/**
* Change the hour.
*
* @param int $hour The hour.
*
* @return static|null A DateTime instance on success for method chaining, null on failure.
*/
public function setHour($hour) {
// Set the hour
try {
$this->hour = $hour;
return $this;
} catch(\Exception $ex) {
return null;
}
}
/**
* Get the minute.
*
* @return int The minute.
*/
public function getMinute() {
return (int) $this->format(static::$GETTER_FORMATS['minute']);
}
/**
* Change the minute.
*
* @param int $minute The minute.
*
* @return static|null A DateTime instance on success for method chaining, null on failure.
*/
public function setMinute($minute) {
// Set the minute
try {
$this->minute = $minute;
return $this;
} catch(\Exception $ex) {
return null;
}
}
/**
* Get the second.
*
* @return int The second.
*/
public function getSecond() {
return (int) $this->format(static::$GETTER_FORMATS['second']);
}
/**
* Change the second.
*
* @param int $second The second.
*
* @return static|null A DateTime instance on success for method chaining, null on failure.
*/
public function setSecond($second) {
// Set the second
try {
$this->second = $second;
return $this;
} catch(\Exception $ex) {
return null;
}
}
/**
* Set the timestamp.
*
* @param int $timestamp The timestamp.
*
* @return static|null A DateTime instance on success for method chaining, null on failure.
*/
public function setTimestamp($timestamp) {
// Set the timestamp
try {
$this->timestamp = $timestamp;
return $this;
} catch(\Exception $ex) {
return null;
}
}
/**
* Get the timezone.
*
* @return DateTimeZone|null The timezone, or null on failure.
*/
public function getTimezone() {
return DateTimeZoneUtils::parse(parent::getTimezone());
}
/**
* Set the timezone.
*
* @param DateTimeZone|PHPDateTimeZone|string|DateTime|PHPDateTime $timezone A DateTimeZone or PHPDateTimeZone instance or the timezone ID as a string. A DateTime or PHPDateTime instance to use it's timezone.
*
* @return static|null A DateTime instance on success for method chaining, null on failure.
*/
public function setTimezone($timezone) {
// Parse the timezone, return null on failure
if(($timezone = DateTimeZoneUtils::parse($timezone)) === null)
return null;
// Set the timezone, and return the current instance for method chaining
parent::setTimezone($timezone);
return $this;
}
/**
* Get a mock DateTime instance which is returned when the now() method is called.
*
* @return DateTime The mock DateTime instance, or null when no mock instance is set.
*/
public static function getMockNow() {
return static::$mockNow;
}
/**
* Check whether a mock DateTime instance is set.
*
* @return bool True if any mock DateTime instance is set, false otherwise.
*/
public static function hasMockNow() {
return static::getMockNow() !== null;
}
/**
* Set a mock DateTime instance which is returned when the now() method is called.
* A new DateTime instance will be created if $mockNow needs to be parsed into a DateTime instance.
* This affects all methods using the now() method as default when no time data is supplied.
*
* The timezone doesn't have any effect on this method.
*
* To reset the mock instance, call this method using the default parameter of null.
*
* @param DateTime|PHPDateTime|string|null $mockNow [optional] A DateTime or PHPDateTime instance, the date and time as a string or null to reset the mock date and time.
*
* @return bool True on success, false on failure.
*/
public static function setMockNow($mockNow = null) {
// Check whether the mock instance should be reset
if($mockNow === null) {
static::$mockNow = null;
return true;
}
// Parse the mock date and time, return false on failure
if(($mockNow = static::parse($mockNow)) === null)
return false;
// Set the mock instance, return the result
static::$mockNow = $mockNow;
return true;
}
/**
* Get the micro.
*
* @return int The micro.
*/
public function getMicro() {
return (int) $this->format(static::$GETTER_FORMATS['micro']);
}
/**
* Get the day of the week.
*
* @return int The day of the week.
*/
public function getDayOfWeek() {
return (int) $this->format(static::$GETTER_FORMATS['dayOfWeek']);
}
/**
* Get the day of the year.
*
* @return int The day of the year.
*/
public function getDayOfYear() {
return (int) $this->format(static::$GETTER_FORMATS['dayOfYear']);
}
/**
* Get the week of the year.
*
* @return int The week of the year.
*/
public function getWeekOfYear() {
return (int) $this->format(static::$GETTER_FORMATS['weekOfYear']);
}
/**
* Get the number of days in this month.
*
* @return int The number of days.
*/
public function getDaysInMonth() {
return (int) $this->format(static::$GETTER_FORMATS['daysInMonth']);
}
/**
* Set the date of the object.
*
* @param int|null $year [optional] The year, or null to leave the year unchanged.
* @param int|null $month [optional] The month, or null to leave the month unchanged.
* @param int|null $day [optional] The day, or null to leave the day unchanged.
*
* @return DateTime|null The DateTime instance for method chaining, or null on failure.
*/
public function setDate($year = null, $month = null, $day = null) {
// Make sure the parameters are valid or null
if(($year !== null && !is_int($year)) || ($month !== null && !is_int($month)) || ($day !== null && !is_int($day)))
return null;
// Handle the null parameters
if($year === null)
$year = $this->getYear();
if($month === null)
$month = $this->getMonth();
if($day === null)
$day = $this->getDay();
// Set the date using the parent function, return this or null on failure
return parent::setDate($year, $month, $day) === false ? null : $this;
}
/**
* Set the time of the object.
*
* @param int|null $hour [optional] The hour, or null to leave the hour unchanged.
* @param int|null $minute [optional] The minute, or null to leave the minute unchanged.
* @param int|null $second [optional] The second, or null to leave the second unchanged.
*
* @return DateTime|null The DateTime instance for method chaining, or null on failure.
*/
public function setTime($hour = null, $minute = null, $second = null) {
// Make sure the parameters are valid or null
if(($hour !== null && !is_int($hour)) || ($minute !== null && !is_int($minute)) || ($second !== null && !is_int($second)))
return null;
// Handle the null parameters
if($hour === null)
$hour = $this->getHour();
if($minute === null)
$minute = $this->getMinute();
if($second === null)
$second = $this->getSecond();
// Set the time using the parent function, return this or null on failure
return parent::setTime($hour, $minute, $second) === false ? null : $this;
}
/**
* Get a part of the DateTime object.
*
* @param string $name The getter name.
*
* @return string|int|DateTimeZone|PHPDateTimeZone
*
* @throws \InvalidArgumentException
*/
// TODO: Handle these getters through the real get... setters!
public function __get($name) {
// Parse the getter based on the getter formats list
if(array_key_exists($name, static::$GETTER_FORMATS))
return (int) $this->format(static::$GETTER_FORMATS[$name]);
// Get the week number of the month
if(StringUtils::equals($name, 'weekOfMonth', false))
return (int) ceil($this->day / static::DAYS_PER_WEEK);
// Get the age
if(StringUtils::equals($name, 'age', false))
return $this->getAge();
// Ge the current quarter number
if(StringUtils::equals($name, 'quarter', false))
return (int) ceil($this->month / 3);
// Get the offset
if(StringUtils::equals($name, 'offset', false))
return $this->getOffset();
// Get the offset hours
if(StringUtils::equals($name, 'offsetHours', false))
return $this->getOffset() / static::SECONDS_PER_MINUTE / static::MINUTES_PER_HOUR;
// Check whether daylight saving time is active
if(StringUtils::equals($name, 'dst', false))
return $this->format('I') == '1';
// Check if the timezone is local
if(StringUtils::equals($name, 'local', false))
return $this->getTimezone()->isLocal(DateTimeZoneUtils::getDefaultTimezone());
// Check whether the time is in UTC
if(StringUtils::equals($name, 'utc', false))
return $this->offset == 0;
// Get the timezone
if(StringUtils::equals($name, Array('timezone', 'tz'), false))
return $this->getTimezone();
// Get the timezone name
if(StringUtils::equals($name, Array('timezoneName', 'tzName'), false))
return $this->getTimezone()->getName();
// The field name is unknown, throw an exception
// TODO: Should we throw an error, or is returning nothing fine?
throw new \InvalidArgumentException('Unknown getter \'' . $name . '\'');
}
/**
* Check if an attribute exists on the object.
*
* @param string $name The name of the attribute.
*
* @return bool True if the attribute exists, false otherwise.
*/
public function __isset($name) {
try {
// Try to get an attribute
$this->__get($name);
} catch(\InvalidArgumentException $e) {
// The attribute doesn't exist, return the result
return false;
}
// The attribute does exist, return the result
return true;
}
/**
* Set a part of the DateTime object.
*
* @param string $name The name of the attribute to set.
* @param string|int|DateTimeZone|PHPDateTimeZone $value The value to set it to.
*
* @throws \Exception|\InvalidArgumentException Throws an exception on failure.
*/
// TODO: Handle these setters through the real set... setters!
public function __set($name, $value) {
// Set the year
if(StringUtils::equals($name, 'year', true)) {
if($this->setDate($value, null, null) === null)
throw new \DomainException('Invalid type for \'' . $name . '\'');
return;
}
// Set the month
if(StringUtils::equals($name, 'month', true)) {
if($this->setDate(null, $value, null) === null)
throw new \DomainException('Invalid type for \'' . $name . '\'');
return;
}
// Set the day
if(StringUtils::equals($name, 'day', true)) {
if($this->setDate(null, null, $value) === null)
throw new \DomainException('Invalid type for \'' . $name . '\'');
return;
}
// Set the hour
if(StringUtils::equals($name, 'hour', true)) {
if($this->setTime($value, null, null) === null)
throw new \DomainException('Invalid type for \'' . $name . '\'');
return;
}
// Set the minute
if(StringUtils::equals($name, 'minute', true)) {
if($this->setTime(null, $value, null) === null)
throw new \DomainException('Invalid type for \'' . $name . '\'');
return;
}
// Set the second
if(StringUtils::equals($name, 'second', true)) {
if($this->setTime(null, null, $value) === null)
throw new \DomainException('Invalid type for \'' . $name . '\'');
return;
}
// Set the timestamp
if(StringUtils::equals($name, 'timestamp', true)) {
if(parent::setTimestamp($value) === false)
throw new \DomainException('Invalid type for \'' . $name . '\'');
return;
}
// Set the timezone
if(StringUtils::equals($name, Array('timezone', 'tz'), true)) {
if($this->setTimezone($value) === null)
throw new \DomainException('Invalid type for ' . $name);
return;
}
// Failed to set the attribute, throw an exception
// TODO: Should we throw an error, or is returning nothing fine?
throw new \InvalidArgumentException('Unknown setter \'' . $name . '\'');
}
/**
* Set the date and time of the object.
*
* @param int|null $year [optional] The year, or null to leave the year unchanged.
* @param int|null $month [optional] The month, or null to leave the month unchanged.
* @param int|null $day [optional] The day, or null to leave the day unchanged.
* @param int|null $hour [optional] The hour, or null to leave the hour unchanged.
* @param int|null $minute [optional] The minute, or null to leave the minute unchanged.
* @param int|null $second [optional] The second, or null to leave the second unchanged.
*
* @return static|null The DateTime instance, or null on failure
*/
public function setDateTime($year, $month, $day, $hour, $minute, $second = 0) {
// Set the date, return null on failure
if($this->setDate($year, $month, $day) === null)
return null;
// Set the time and return this, return null on failure
return $this->setTime($hour, $minute, $second) === null ? null : $this;
}
/**
* Check whether there is a relative keyword in the date and time string, this is to create dates relative to now for test instances. e.g.: next tuesday
*
* @param string $time The date and time string to check.
*
* @return bool True if there is a relative keyword in the date and time string, false otherwise.
*/
public static function hasRelativeKeywords($time) {
// Check whether the time string contains any relative keywords
// Skip a common time format
if(preg_match('/[0-9]{4}-[0-9]{1,2}-[0-9]{1,2}/', $time) !== 1)
foreach(static::$RELATIVE_KEYWORDS as $keyword)
if(StringUtils::contains($time, $keyword, false))
return true;
// The time string doesn't contain any relative keywords, return the result
return false;
}
// TODO: Put all translation and to string stuff here...!
/**
* Check whether the date equals to the date of the specified date and time parameter.
*
* @param DateTime|PHPDateTime|string|null $dateTime [optional] The other DateTime or PHPDateTime instance, the date and time as a string or null to use the now() time.
*
* @return bool True if the date equals the date of the specified date and time, false otherwise. False will also be returned if the specified date and time was invalid.
*/
public function equals($dateTime = null) {
// Parse the date and time, return false on failure
if(($dateTime = static::parse($dateTime)) === null)
return null;
// Compare the date and time of both objects, return the result
return StringUtils::equals($this->toCompleteString(), $dateTime->toCompleteString());
}
/**
* Check whether the date is greater than the date of the specified date and time parameter.
*
* @param DateTime|PHPDateTime|string|null $dateTime [optional] The other DateTime or PHPDateTime instance, the date and time as a string or null to use the now() time.
*
* @return bool|null True if the date is greater than the specified date and time, false otherwise. Null will be returned if the specified date and time was invalid.
*/
public function isGreaterThan($dateTime = null) {
// Parse the date and time, return false on failure
if(($dateTime = static::parse($dateTime)) === null)
return null;
// Compare the date and time, return the result
return $this > $dateTime;
}
/**
* Check whether the date is greater or equal to the date of the specified date and time parameter.
*
* @param DateTime|PHPDateTime|string|null $dateTime [optional] The other DateTime or PHPDateTime instance, the date and time as a string or null to use the now() time.
*
* @return bool|null True if the date is greater or equal to the specified date and time, false otherwise. Null will be returned if the specified date and time was invalid.
*/
public function isGreaterOrEqualTo($dateTime = null) {
// Parse the date and time, return false on failure
if(($dateTime = static::parse($dateTime)) === null)
return null;
// Compare the date and time, return the result
return $this >= $dateTime;
}
/**
* Check whether the date is less than the date of the specified date and time parameter.
*
* @param DateTime|PHPDateTime|string|null $dateTime [optional] The other DateTime or PHPDateTime instance, the date and time as a string or null to use the now() time.
*
* @return bool|null True if the date is less than the specified date and time, false otherwise. Null will be returned if the specified date and time was invalid.
*/
public function isLessThan($dateTime = null) {
// Parse the date and time, return false on failure
if(($dateTime = static::parse($dateTime)) === null)
return null;
// Compare the date and time, return the result
return $this < $dateTime;
}
/**
* Check whether the date is less or equal to the date of the specified date and time parameter.
*
* @param DateTime|PHPDateTime|string|null $dateTime [optional] The other DateTime or PHPDateTime instance, the date and time as a string or null to use the now() time.
*
* @return bool|null True if the date is less or equal to the specified date and time, false otherwise. Null will be returned if the specified date and time was invalid.
*/
public function isLessOrEqualTo($dateTime = null) {
// Parse the date and time, return false on failure
if(($dateTime = static::parse($dateTime)) === null)
return null;
// Compare the date and time, return the result
return $this <= $dateTime;
}
/**
* Check whether the specified date and time is between a and b.
* The $a and $b parameter may not be null at the same time or false will be returned.
*
* @param DateTime|PHPDateTime|string|null $a The date and time as DateTime or PHPDateTime instance, the date and time as a string or null to use the now() time.
* @param DateTime|PHPDateTime|string|null $b The date and time as DateTime or PHPDateTime instance, the date and time as a string or null to use the now() time.
* @param bool $equals [optional] True to also return true if the date equals one of the specified date and times, false otherwise.
*
* @return bool|null True if the date is between the specified date and time, or if it equals one of the date and times while $equals is set to true. False will be returned otherwise. Null will be returned on failure.
*/
public function isBetween($a = null, $b = null, $equals = true) {
// The a and b parameters may not be null at the same time
if($a === null && $b === null)
return null;
// Parse the date and times, return null on failure
if(($a = static::parse($a)) === null || ($b = static::parse($b)) === null)
return null;
// Get the lowest and greatest date
$aGreater = $a->isGreaterThan($b);
$lowest = $aGreater ? $b : $a;
$greatest = $aGreater ? $a : $b;
// Check whether the dates may equal
if($equals)
// Check whether the date is in between or equals, return the result
return $this->isGreaterOrEqualTo($lowest) && $this->isLessOrEqualTo($greatest);
// Check whether the date is in between, return the result
return $this->isGreaterThan($lowest) && $this->isLessThan($greatest);
}
/**
* Get the greatest date and time of this instance and the specified date and time.
*
* @param DateTime|PHPDateTime|string|null $dateTime [optional] A DateTime or PHPDateTime instance, the date and time as a string or null to use the now() time.
*
* @return DateTime|null The greatest DateTime instance, or null on failure.
*/
public function max($dateTime = null) {
// Parse the date and time, return false on failure
if(($dateTime = self::parse($dateTime)) === null)
return null;
// Return the greatest date and time
return $this->isGreaterOrEqualTo($dateTime) ? $this : $dateTime;
}
/**
* Get the lowest date and time of this instance and the specified date and time.
*
* @param DateTime|PHPDateTime|string|null $dateTime [optional] A DateTime or PHPDateTime instance, the date and time as a string or null to use the now() time.
*
* @return DateTime|null The lowest DateTime instance, or null on failure.
*/
public function min($dateTime = null) {
// Parse the date and time, return false on failure
if(($dateTime = self::parse($dateTime)) === null)
return null;
// Return the greatest date and time
return $this->isLessOrEqualTo($dateTime) ? $this : $dateTime;
}
/**
* Check whether this is a weekday (monday to friday).
*
* @return bool True if this is a weekday, false otherwise.
*/
public function isWeekday() {
return $this->dayOfWeek != static::SUNDAY && $this->dayOfWeek != static::SATURDAY;
}
/**
* Check whether this is a weekend day (saturday or sunday).
*
* @return bool True if this is a weekend day, false otherwise.
*/
public function isWeekend() {
return !$this->isWeekday();
}
/**
* Check whether this is today.
*
* @return bool True if this is today, false if not.
*/
public function isToday() {
return StringUtils::equals($this->toDateString(), static::now($this->getTimezone())->toDateString());
}
/**
* Check whether this is tomorrow.
*
* @return bool True if this is tomorrow, false if not.
*/
public function isTomorrow() {
return StringUtils::equals($this->toDateString(), static::tomorrow($this->getTimezone())->toDateString());
}
/**
* Check whether this is yesterday.
*
* @return bool True if this is yesterday, false if not.
*/
public function isYesterday() {
return StringUtils::equals($this->toDateString(), static::yesterday($this->getTimezone())->toDateString());
}
/**
* Check whether this is in the future. If the date and time equals the now() date and time false is returned.
*
* @return bool True if this is in the future, false if not.
*/
public function isFuture() {
return $this->isGreaterThan(static::now($this->getTimezone()));
}
/**
* Check whether this is in the past. If the date and time equals the now() date and time false is returned.
*
* @return bool True if this is in the past, false if not.
*/
public function isPast() {
return $this->isLessThan(static::now($this->getTimezone()));
}
/**
* Check whether this is a leap year.
*
* @return bool True if this is a leap year, false if not.
*/
public function isLeapYear() {
return StringUtils::equals($this->format('L'), '1');
}
/**
* Check whether the year equals the specified date.
*
* @param DateTime|PHPDateTime|string|null $dateTime [optional] A DateTime or PHPDateTime instance, the date and time as a string or null to use the now() time.
*
* @return bool True if year is the same as the specified date, false otherwise. False will also be returned on failure.
*/
public function isSameYear($dateTime) {
// Parse the date and time, return false on failure
if(($dateTime = static::parse($dateTime, $this->getTimezone())) === null)
return false;
// Check whether the week is equal, return the result
return StringUtils::equals($this->format('Y'), $dateTime->format('Y'));
}
/**
* Check whether the month equals the specified date.
*
* @param DateTime|PHPDateTime|string|null $dateTime [optional] A DateTime or PHPDateTime instance, the date and time as a string or null to use the now() time.
*
* @return bool True if month is the same as the specified date, false otherwise. False will also be returned on failure.
*/
public function isSameMonth($dateTime) {
// Parse the date and time, return false on failure
if(($dateTime = static::parse($dateTime, $this->getTimezone())) === null)
return false;
// Check whether the week is equal, return the result
return StringUtils::equals($this->format('Y-m'), $dateTime->format('Y-m'));
}
/**
* Check whether the ISO-8601 week equals the specified date.
*
* @param DateTime|PHPDateTime|string|null $dateTime [optional] A DateTime or PHPDateTime instance, the date and time as a string or null to use the now() time.
*
* @return bool True if the ISO-8601 week is the same as the specified date, false otherwise. False will also be returned on failure.
*/
public function isSameWeek($dateTime) {
// Parse the date and time, return false on failure
if(($dateTime = static::parse($dateTime, $this->getTimezone())) === null)
return false;
// Check whether the week is equal, return the result
return StringUtils::equals($this->format('Y-W'), $dateTime->format('Y-W'));
}
/**
* Check whether the date is equal to the specified date.
*
* @param DateTime|PHPDateTime|string|null $dateTime [optional] A DateTime or PHPDateTime instance, the date and time as a string or null to use the now() time.
*
* @return bool True if the date is the same as the specified date, false otherwise. False will also be returned on failure.
*/
public function isSameDate($dateTime) {
// Parse the date and time, return false on failure
if(($dateTime = static::parse($dateTime, $this->getTimezone())) === null)
return false;
// Check whether the date is equal
return StringUtils::equals($this->toDateString(), $dateTime->toDateString());
}
/**
* Check whether the hour equals the specified date.
*
* @param DateTime|PHPDateTime|string|null $dateTime [optional] A DateTime or PHPDateTime instance, the date and time as a string or null to use the now() time.
* @param bool $checkDate [optional] True to make sure the dates are equal, false to just compare the time.
*
* @return bool True if hour is the same as the specified date, false otherwise. False will also be returned on failure.
*/
public function isSameHour($dateTime, $checkDate = true) {
// Parse the date and time, return false on failure
if(($dateTime = static::parse($dateTime, $this->getTimezone())) === null)
return false;
// Compare the date
if($checkDate)
if(!$this->isSameDate($dateTime))
return false;
// Check whether the week is equal, return the result
return StringUtils::equals($this->format('H'), $dateTime->format('H'));
}
/**
* Check whether the minute equals the specified date.
*
* @param DateTime|PHPDateTime|string|null $dateTime [optional] A DateTime or PHPDateTime instance, the date and time as a string or null to use the now() time.
* @param bool $checkDate [optional] True to make sure the dates are equal, false to just compare the time.
*
* @return bool True if minute is the same as the specified date, false otherwise. False will also be returned on failure.
*/
public function isSameMinute($dateTime, $checkDate = true) {
// Parse the date and time, return false on failure
if(($dateTime = static::parse($dateTime, $this->getTimezone())) === null)
return false;
// Compare the date
if($checkDate)
if(!$this->isSameDate($dateTime))
return false;
// Check whether the week is equal, return the result
return StringUtils::equals($this->format('H:i'), $dateTime->format('H:i'));
}
/**
* Check whether the second equals the specified date.
*
* @param DateTime|PHPDateTime|string|null $dateTime [optional] A DateTime or PHPDateTime instance, the date and time as a string or null to use the now() time.
* @param bool $checkDate [optional] True to make sure the dates are equal, false to just compare the time.
*
* @return bool True if second is the same as the specified date, false otherwise. False will also be returned on failure.
*/
public function isSameTime($dateTime, $checkDate = true) {
// Parse the date and time, return false on failure
if(($dateTime = static::parse($dateTime, $this->getTimezone())) === null)
return false;
// Compare the date
if($checkDate)
if(!$this->isSameDate($dateTime))
return false;
// Check whether the week is equal, return the result
return StringUtils::equals($this->toTimeString(), $dateTime->toTimeString());
}
/**
* Alter the date and time by incrementing or decrementing based on the modify parameter in a format accepted by strtotime().
* If an empty string, or null is provided null will be returned.
*
* @param string $modify A date/time string in a format accepted by PHPs strtotime();.
*
* @return DateTime|null The DateTime instance for method chaining, or null on failure.
*/
public function modify($modify) {
// Make sure the modify parameter isn't empty
if(empty($modify))
return $this;
// Modify the date and time using the parent method, return null on failure
if(parent::modify($modify) === false)
return null;
// Return the current instance for method chaining
return $this;
}
/**
* Travel the specified number of years forward in time. A positive number of years will travel forward in time, while a negative number of years travels backward.
*
* @param int $years The number of years to travel forward in time.
*
* @return DateTime|null The DateTime instance for method chaining, or null on failure.
*/
public function addYears($years) {
// Make sure the years value is an integer
if(!is_int($years))
return null;
// Travel the specified number of years in time
// TODO: Should we prefix this add sign, or make it dynamic? (For all similar methods)
if($this->modify($years . ' year') === false)
return null;
// Return this for method chaining
return $this;
}
/**
* Travel a year, or the specified number of years forward in time. A positive number of years will travel forward in time, while a negative number of years travels backward.
*
* @param int $years [optional] The number of years to travel forward in time.
*
* @return DateTime|null The DateTime instance for method chaining, or null on failure.
*/
public function addYear($years = 1) {
return $this->addYears($years);
}
/**
* Travel the specified number of years backward in time. A positive number of years will travel backward in time, while a negative number of years travels forward.
*
* @param int $years The number of years to travel backward in time.
*
* @return DateTime|null The DateTime instance for method chaining, or null on failure.
*/
// TODO: Should we rename these methods to sub..., because that same term is used in PHPs methods!?
public function subtractYears($years) {
return $this->addYears($years * -1);
}
/**
* Travel a year, or the specified number of years backward in time. A positive number of years will travel backward in time, while a negative number of years will travel forward.
*
* @param int $years [optional] The number of years to travel backward in time.
*
* @return DateTime|null The DateTime instance for method chaining, or null on failure.
*/
public function subtractYear($years = 1) {
return $this->subtractYears($years);
}
/**
* Travel the specified number of months forward in time. A positive number of months will travel forward in time, while a negative number of months travels backward.
*
* @param int $months The number of months to travel forward in time.
*
* @return DateTime|null The DateTime instance for method chaining, or null on failure.
*/
public function addMonths($months) {
// Make sure the months value is an integer
if(!is_int($months))
return null;
// Travel the specified number of months in time
if($this->modify($months . ' month') === false)
return null;
// Return this for method chaining
return $this;
}
/**
* Travel a month, or the specified number of months forward in time. A positive number of months will travel forward in time, while a negative number of months travels backward.
*
* @param int $months [optional] The number of months to travel forward in time.
*
* @return DateTime|null The DateTime instance for method chaining, or null on failure.
*/
public function addMonth($months = 1) {
return $this->addMonths($months);
}
/**
* Travel the specified number of months backward in time. A positive number of months will travel backward in time, while a negative number of months travels forward.
*
* @param int $months The number of months to travel backward in time.
*
* @return DateTime|null The DateTime instance for method chaining, or null on failure.
*/
public function subtractMonths($months) {
return $this->addMonths($months * -1);
}
/**
* Travel a month, or the specified number of months backward in time. A positive number of months will travel backward in time, while a negative number of months will travel forward.
*
* @param int $months [optional] The number of months to travel backward in time.
*
* @return DateTime|null The DateTime instance for method chaining, or null on failure.
*/
public function subtractMonth($months = 1) {
return $this->subtractMonths($months);
}
/**
* Travel the specified number of days forward in time. A positive number of days will travel forward in time, while a negative number of days travels backward.
*
* @param int $days The number of days to travel forward in time.
*
* @return DateTime|null The DateTime instance for method chaining, or null on failure.
*/
public function addDays($days) {
// Make sure the days value is an integer
if(!is_int($days))
return null;
// Travel the specified number of days in time
if($this->modify($days . ' day') === false)
return null;
// Return this for method chaining
return $this;
}
/**
* Travel a day, or the specified number of days forward in time. A positive number of days will travel forward in time, while a negative number of days travels backward.
*
* @param int $days [optional] The number of days to travel forward in time.
*
* @return DateTime|null The DateTime instance for method chaining, or null on failure.
*/
public function addDay($days = 1) {
return $this->addDays($days);
}
/**
* Travel the specified number of days backward in time. A positive number of days will travel backward in time, while a negative number of days travels forward.
*
* @param int $days The number of days to travel backward in time.
*
* @return DateTime|null The DateTime instance for method chaining, or null on failure.
*/
public function subtractDays($days) {
return $this->addDays($days * -1);
}
/**
* Travel a day, or the specified number of days backward in time. A positive number of days will travel backward in time, while a negative number of days will travel forward.
*
* @param int $days [optional] The number of days to travel backward in time.
*
* @return DateTime|null The DateTime instance for method chaining, or null on failure.
*/
public function subtractDay($days = 1) {
return $this->subtractDays($days);
}
/**
* Travel the specified number of weekdays forward in time. A positive number of weekdays will travel forward in time, while a negative number of weekdays travels backward.
*
* @param int $weekdays The number of weekdays to travel forward in time.
*
* @return DateTime|null The DateTime instance for method chaining, or null on failure.
*/
public function addWeekdays($weekdays) {
// Make sure the weekdays value is an integer
if(!is_int($weekdays))
return null;
// Travel the specified number of weekdays in time
if($this->modify($weekdays . ' weekday') === false)
return null;
// Return this for method chaining
return $this;
}
/**
* Travel a weekday, or the specified number of weekdays forward in time. A positive number of weekdays will travel forward in time, while a negative number of weekdays travels backward.
*
* @param int $weekdays [optional] The number of weekdays to travel forward in time.
*
* @return DateTime|null The DateTime instance for method chaining, or null on failure.
*/
public function addWeekday($weekdays = 1) {
return $this->addWeekdays($weekdays);
}
/**
* Travel the specified number of weekdays backward in time. A positive number of weekdays will travel backward in time, while a negative number of weekdays travels forward.
*
* @param int $weekdays The number of weekdays to travel backward in time.
*
* @return DateTime|null The DateTime instance for method chaining, or null on failure.
*/
public function subtractWeekdays($weekdays) {
return $this->addWeekdays($weekdays * -1);
}
/**
* Travel a weekday, or the specified number of weekdays backward in time. A positive number of weekdays will travel backward in time, while a negative number of weekdays will travel forward.
*
* @param int $weekdays [optional] The number of weekdays to travel backward in time.
*
* @return DateTime|null The DateTime instance for method chaining, or null on failure.
*/
public function subtractWeekday($weekdays = 1) {
return $this->subtractWeekdays($weekdays);
}
/**
* Travel the specified number of weeks forward in time. A positive number of weeks will travel forward in time, while a negative number of weeks travels backward.
*
* @param int $weeks The number of weeks to travel forward in time.
*
* @return DateTime|null The DateTime instance for method chaining, or null on failure.
*/
public function addWeeks($weeks) {
// Make sure the weeks value is an integer
if(!is_int($weeks))
return null;
// Travel the specified number of weeks in time
if($this->modify($weeks . ' week') === false)
return null;
// Return this for method chaining
return $this;
}
/**
* Travel a week, or the specified number of weeks forward in time. A positive number of weeks will travel forward in time, while a negative number of weeks travels backward.
*
* @param int $weeks [optional] The number of weeks to travel forward in time.
*
* @return DateTime|null The DateTime instance for method chaining, or null on failure.
*/
public function addWeek($weeks = 1) {
return $this->addWeeks($weeks);
}
/**
* Travel the specified number of weeks backward in time. A positive number of weeks will travel backward in time, while a negative number of weeks travels forward.
*
* @param int $weeks The number of weeks to travel backward in time.
*
* @return DateTime|null The DateTime instance for method chaining, or null on failure.
*/
public function subtractWeeks($weeks) {
return $this->addWeeks($weeks * -1);
}
/**
* Travel a week, or the specified number of weeks backward in time. A positive number of weeks will travel backward in time, while a negative number of weeks will travel forward.
*
* @param int $weeks [optional] The number of weeks to travel backward in time.
*
* @return DateTime|null The DateTime instance for method chaining, or null on failure.
*/
public function subtractWeek($weeks = 1) {
return $this->subtractWeeks($weeks);
}
/**
* Travel the specified number of hours forward in time. A positive number of hours will travel forward in time, while a negative number of hours travels backward.
*
* @param int $hours The number of hours to travel forward in time.
*
* @return DateTime|null The DateTime instance for method chaining, or null on failure.
*/
public function addHours($hours) {
// Make sure the hours value is an integer
if(!is_int($hours))
return null;
// Travel the specified number of hours in time
if($this->modify($hours . ' hour') === false)
return null;
// Return this for method chaining
return $this;
}
/**
* Travel a hour, or the specified number of hours forward in time. A positive number of hours will travel forward in time, while a negative number of hours travels backward.
*
* @param int $hours [optional] The number of hours to travel forward in time.
*
* @return DateTime|null The DateTime instance for method chaining, or null on failure.
*/
public function addHour($hours = 1) {
return $this->addHours($hours);
}
/**
* Travel the specified number of hours backward in time. A positive number of hours will travel backward in time, while a negative number of hours travels forward.
*
* @param int $hours The number of hours to travel backward in time.
*
* @return DateTime|null The DateTime instance for method chaining, or null on failure.
*/
public function subtractHours($hours) {
return $this->addHours($hours * -1);
}
/**
* Travel a hour, or the specified number of hours backward in time. A positive number of hours will travel backward in time, while a negative number of hours will travel forward.
*
* @param int $hours [optional] The number of hours to travel backward in time.
*
* @return DateTime|null The DateTime instance for method chaining, or null on failure.
*/
public function subtractHour($hours = 1) {
return $this->subtractHours($hours);
}
/**
* Travel the specified number of minutes forward in time. A positive number of minutes will travel forward in time, while a negative number of minutes travels backward.
*
* @param int $minutes The number of minutes to travel forward in time.
*
* @return DateTime|null The DateTime instance for method chaining, or null on failure.
*/
public function addMinutes($minutes) {
// Make sure the minutes value is an integer
if(!is_int($minutes))
return null;
// Travel the specified number of minutes in time
if($this->modify($minutes . ' minute') === false)
return null;
// Return this for method chaining
return $this;
}
/**
* Travel a minute, or the specified number of minutes forward in time. A positive number of minutes will travel forward in time, while a negative number of minutes travels backward.
*
* @param int $minutes [optional] The number of minutes to travel forward in time.
*
* @return DateTime|null The DateTime instance for method chaining, or null on failure.
*/
public function addMinute($minutes = 1) {
return $this->addMinutes($minutes);
}
/**
* Travel the specified number of minutes backward in time. A positive number of minutes will travel backward in time, while a negative number of minutes travels forward.
*
* @param int $minutes The number of minutes to travel backward in time.
*
* @return DateTime|null The DateTime instance for method chaining, or null on failure.
*/
public function subtractMinutes($minutes) {
return $this->addMinutes($minutes * -1);
}
/**
* Travel a minute, or the specified number of minutes backward in time. A positive number of minutes will travel backward in time, while a negative number of minutes will travel forward.
*
* @param int $minutes [optional] The number of minutes to travel backward in time.
*
* @return DateTime|null The DateTime instance for method chaining, or null on failure.
*/
public function subtractMinute($minutes = 1) {
return $this->subtractMinutes($minutes);
}
/**
* Travel the specified number of seconds forward in time. A positive number of seconds will travel forward in time, while a negative number of seconds travels backward.
*
* @param int $seconds The number of seconds to travel forward in time.
*
* @return DateTime|null The DateTime instance for method chaining, or null on failure.
*/
public function addSeconds($seconds) {
// Make sure the seconds value is an integer
if(!is_int($seconds))
return null;
// Travel the specified number of seconds in time
if($this->modify($seconds . ' second') === false)
return null;
// Return this for method chaining
return $this;
}
/**
* Travel a second, or the specified number of seconds forward in time. A positive number of seconds will travel forward in time, while a negative number of seconds travels backward.
*
* @param int $seconds [optional] The number of seconds to travel forward in time.
*
* @return DateTime|null The DateTime instance for method chaining, or null on failure.
*/
public function addSecond($seconds = 1) {
return $this->addSeconds($seconds);
}
/**
* Travel the specified number of seconds backward in time. A positive number of seconds will travel backward in time, while a negative number of seconds travels forward.
*
* @param int $seconds The number of seconds to travel backward in time.
*
* @return DateTime|null The DateTime instance for method chaining, or null on failure.
*/
public function subtractSeconds($seconds) {
return $this->addSeconds($seconds * -1);
}
/**
* Travel a second, or the specified number of seconds backward in time. A positive number of seconds will travel backward in time, while a negative number of seconds will travel forward.
*
* @param int $seconds [optional] The number of seconds to travel backward in time.
*
* @return DateTime|null The DateTime instance for method chaining, or null on failure.
*/
public function subtractSecond($seconds = 1) {
return $this->subtractSeconds($seconds);
}
/**
* Get the difference between this and another date and time object.
*
* @param DateTime|PHPDateTime|string|null $dateTime [optional] A DateTime or PHPDateTime instance, the date and time as a string or null to use the now() date and time.
* @param bool $absolute
*
* @return \DateInterval|null The difference as DateInterval or null on failure.
*/
// TODO: Return the CarbonCMS DateInterval here!
public function diff($dateTime = null, $absolute = true) {
// Parse the date and time, return null on failure
if(($dateTime = static::parse($dateTime, $this->getTimezone())) === null)
return null;
// TODO: Return a CarbonCMS DateInterval instance!
// Call the parent method and return the result, return null on failure
return ($diff = parent::diff($dateTime, $absolute)) === false ? null : $diff;
}
/**
* Get the difference by the given interval using a filter closure.
* The callback will be called for each period in the given time frame. If the callback returns true the period is included as difference, false should be returned otherwise.
*
* @param DateInterval $dateInterval An interval to traverse by.
* @param Closure $callback The callback function to call for each period as filter.
* @param DateTime|PHPDateTime|string|null $dateTime [optional] The DateTime or PHPDateTime instance, the date and time as a string or null to use the now() date and time.
* @param boolean $absolute [optional] True to get the absolute difference, false otherwise.
*
* @return int|null The difference of the date interval in the given time frame. Null will be returned on failure.
*/
public function diffFiltered($dateInterval, Closure $callback, $dateTime = null, $absolute = true) {
// TODO: Parse the date interval!
// Parse the date and time, return null on failure
if(($dateTime = static::parse($dateTime, $this->getTimezone())) === null)
return null;
// Define the start and end times, define whether the value should be inverted
$inverse = !$this->isLessThan($dateTime);
$start = $inverse ? $this : $dateTime;
$end = $inverse ? $dateTime : $start;
// Run the callback for all periods
$period = new DatePeriod($start, $dateInterval, $end);
$values = array_filter(iterator_to_array($period), function(DateTime $date) use($callback) {
return call_user_func($callback, self::instance($date));
});
// Get the difference result
$diff = count($values);
// Return the difference result, inverse the value if needed
return $inverse && !$absolute ? ($diff * -1) : $diff;
}
/**
* Get the difference between this and the specified date in years.
*
* @param DateTime|PHPDateTime|string|null $dateTime [optional] A DateTime or PHPDateTime instance, the date and time as a string or null to use the now() date and time.
* @param boolean $absolute [optional] Get the absolute of the difference in years.
*
* @return int|null The difference in years or null on failure.
*/
public function diffInYears($dateTime = null, $absolute = true) {
// Parse the date and time, return null on failure
if(($dateTime = static::parse($dateTime, $this->getTimezone())) === null)
return null;
// Get the difference and make sure it's valid
if(($difference = $this->diff($dateTime, $absolute)) === false)
return null;
// Get and return the difference in years
return (int) $difference->format('%r%y');
}
/**
* Get the difference between this and the specified date in months.
*
* @param DateTime|PHPDateTime|string|null $dateTime [optional] A DateTime or PHPDateTime instance, the date and time as a string or null to use the now() date and time.
* @param boolean $absolute [optional] Get the absolute of the difference in months.
*
* @return int|null The difference in months or null on failure.
*/
public function diffInMonths($dateTime = null, $absolute = true) {
// Parse the date and time, return null on failure
if(($dateTime = static::parse($dateTime, $this->getTimezone())) === null)
return null;
// Get the differences and make sure it's valid
if(($differenceYears = $this->diffInYears($dateTime, $absolute)) === null)
return null;
if(($difference = $this->diff($dateTime, $absolute)) === false)
return null;
// Get and return the difference in months
return $differenceYears * static::MONTHS_PER_YEAR + (int) $difference->format('%r%m');
}
/**
* Get the difference between this and the specified date in weeks.
*
* @param DateTime|PHPDateTime|string|null $dateTime [optional] A DateTime or PHPDateTime instance, the date and time as a string or null to use the now() date and time.
* @param boolean $absolute [optional] Get the absolute of the difference in weeks.
*
* @return int|null The difference in weeks or null on failure.
*/
public function diffInWeeks($dateTime = null, $absolute = true) {
// Get the difference in days, and make sure it's valid
if(($differenceDays = $this->diffInDays($dateTime, $absolute)) === null)
return null;
// Get and return the difference in weeks
return (int) ($differenceDays / static::DAYS_PER_WEEK);
}
/**
* Get the difference in weekdays.
*
* @param DateTime|PHPDateTime|string|null $dateTime [optional] A DateTime or PHPDateTime instance, the date and time as a string or null to use the now() date and time.
* @param boolean $absolute Get the absolute of the difference.
*
* @return int The difference in weekdays, or null on failure.
*/
public function diffInWeekdays($dateTime = null, $absolute = true) {
return $this->diffInDaysFiltered(function(DateTime $date) {
return $date->isWeekday();
}, $dateTime, $absolute);
}
/**
* Get the difference in weekend days.
*
* @param DateTime|PHPDateTime|string|null $dateTime [optional] A DateTime or PHPDateTime instance, the date and time as a string or null to use the now() date and time.
* @param boolean $absolute Get the absolute of the difference.
*
* @return int The difference in weekend days, or null on failure.
*/
public function diffInWeekendDays($dateTime = null, $absolute = true) {
return $this->diffInDaysFiltered(function(DateTime $date) {
return $date->isWeekend();
}, $dateTime, $absolute);
}
/**
* Get the difference between this and the specified date in days.
*
* @param DateTime|PHPDateTime|string|null $dateTime [optional] A DateTime or PHPDateTime instance, the date and time as a string or null to use the now() date and time.
* @param boolean $absolute [optional] Get the absolute of the difference in days.
*
* @return int|null The difference in days or null on failure.
*/
public function diffInDays($dateTime = null, $absolute = true) {
// Parse the date and time, return null on failure
if(($dateTime = static::parse($dateTime, $this->getTimezone())) === null)
return null;
// Get the difference and make sure it's valid
if(($difference = $this->diff($dateTime, $absolute)) === false)
return null;
// Get and return the difference in days
return (int) $difference->format('%r%a');
}
/**
* Get the difference in days using a filter closure
*
* @param Closure $callback The callback function to call for each day as filter.
* @param DateTime|PHPDateTime|string|null $dateTime [optional] A DateTime or PHPDateTime instance, the date and time as a string or null to use the now() date and time.
* @param boolean $absolute Get the absolute of the difference.
*
* @return int|null The difference in days. Null will be returned on failure.
*/
public function diffInDaysFiltered(Closure $callback, $dateTime = null, $absolute = true) {
return $this->diffFiltered(DateInterval::day(), $callback, $dateTime, $absolute);
}
/**
* Get the difference between this and the specified date in hours.
*
* @param DateTime|PHPDateTime|string|null $dateTime [optional] A DateTime or PHPDateTime instance, the date and time as a string or null to use the now() date and time.
* @param boolean $absolute [optional] Get the absolute of the difference in hours.
*
* @return int|null The difference in hours or null on failure.
*/
public function diffInHours($dateTime = null, $absolute = true) {
// Parse the date and time, return null on failure
if(($dateTime = static::parse($dateTime, $this->getTimezone())) === null)
return null;
// Get the difference in seconds and make sure it's valid
if(($differenceSeconds = $this->diffInSeconds($dateTime, $absolute)) === null)
return null;
// Get and return the difference in hours
return (int) ($differenceSeconds / static::SECONDS_PER_MINUTE / static::MINUTES_PER_HOUR);
}
/**
* Get the difference in hours using a filter closure
*
* @param Closure $callback The callback function to call for each hour as filter.
* @param DateTime|PHPDateTime|string|null $dateTime [optional] A DateTime or PHPDateTime instance, the date and time as a string or null to use the now() date and time.
* @param boolean $absolute Get the absolute of the difference.
*
* @return int|null The difference in hours. Null will be returned on failure.
*/
public function diffInHoursFiltered(Closure $callback, $dateTime = null, $absolute = true) {
return $this->diffFiltered(DateInterval::hour(), $callback, $dateTime, $absolute);
}
/**
* Get the difference between this and the specified date in minutes.
*
* @param DateTime|PHPDateTime|string|null $dateTime [optional] A DateTime or PHPDateTime instance, the date and time as a string or null to use the now() date and time.
* @param boolean $absolute [optional] Get the absolute of the difference in minutes.
*
* @return int|null The difference in minutes or null on failure.
*/
public function diffInMinutes($dateTime = null, $absolute = true) {
// Parse the date and time, return null on failure
if(($dateTime = static::parse($dateTime, $this->getTimezone())) === null)
return null;
// Get the difference in seconds, and make sure it's valid
if(($differenceSeconds = $this->diffInSeconds($dateTime, $absolute)) === null)
return null;
// Get and return the difference in minutes
return (int) ($differenceSeconds / static::SECONDS_PER_MINUTE);
}
/**
* Get the difference between this and the specified date in seconds.
*
* @param DateTime|PHPDateTime|string|null $dateTime [optional] A DateTime or PHPDateTime instance, the date and time as a string or null to use the now() date and time.
* @param boolean $absolute [optional] Get the absolute of the difference in seconds.
*
* @return int|null The difference in seconds or null on failure.
*/
public function diffInSeconds($dateTime = null, $absolute = true) {
// Parse the date and time, return null on failure
if(($dateTime = static::parse($dateTime, $this->getTimezone())) === null)
return null;
// Calculate the timestamp difference
$timestampDifference = $dateTime->getTimestamp() - $this->getTimestamp();
// Return the result in absolute or regular form
return $absolute ? abs($timestampDifference) : $timestampDifference;
}
/**
* Get the number of seconds since midnight.
*
* @return int The number of seconds.
*/
public function secondsSinceMidnight() {
return $this->diffInSeconds($this->copy()->startOfDay());
}
/**
* Get the number of seconds until the end of the day, which is 23:23:59.
*
* @return int The number of seconds.
*/
public function secondsUntilEndOfDay() {
return $this->diffInSeconds($this->copy()->endOfDay());
}
// TODO: Should we add the diffForHumans(); method from Carbon DateTime, and their related methods?
/**
* Set the time to the start of the day, which is 00:00:00.
*
* @return static The DateTime instance.
*/
public function startOfDay() {
return $this->setHour(0)->setMinute(0)->setSecond(0);
}
/**
* Set the time to the end of the day, which is 23:59:59.
*
* @return static The DateTime instance.
*/
public function endOfDay() {
return $this->setHour(23)->setMinute(59)->setSecond(59);
}
/**
* Reset the date to the first day of the month and the time to the beginning of that day, which is 00:00:00.
*
* @return static The DateTime instance.
*/
public function startOfMonth() {
return $this->setDay(1)->startOfDay();
}
/**
* Resets the date to the last day of the month and the time to the end of that day, which is 23:59:59.
*
* @return static The DateTime instance.
*/
public function endOfMonth() {
return $this->setDay($this->daysInMonth)->endOfDay();
}
/**
* Resets the date to the start of the year and the time to the beginning of that day, which is 00:00:00.
*
* @return static The DateTime instance.
*/
public function startOfYear() {
return $this->setMonth(1)->startOfMonth();
}
/**
* Resets the date to the end of t he year and the time to the end of that day, which is 23:59:59.
*
* @return static The DateTime instance.
*/
public function endOfYear() {
return $this->setMonth(static::MONTHS_PER_YEAR)->endOfMonth();
}
/**
* Resets the date to the start of the decade and the time to the beginning of that day, which is 00:00:00.
*
* @return static The DateTime instance.
*/
public function startOfDecade() {
return $this->startOfYear()->setYear($this->year - ($this->year % static::YEARS_PER_DECADE));
}
/**
* Resets the date to the end of the decade and the time to the end of that day, which is 23:59:59.
*
* @return static
*/
public function endOfDecade() {
return $this->endOfYear()->setYear($this->year - ($this->year % static::YEARS_PER_DECADE + static::YEARS_PER_DECADE - 1));
}
/**
* Resets the date to the start of the century and the time to the beginning of that day, which is 00:00:00.
*
* @return static The DateTime instance.
*/
public function startOfCentury() {
return $this->startOfYear()->setYear($this->year - ($this->year % static::YEARS_PER_CENTURY));
}
/**
* Resets the date to the end of the century and the time to the end of that day, which is 23:59:59.
*
* @return static The DateTime instance.
*/
public function endOfCentury() {
return $this->endOfYear()->setYear($this->year - ($this->year % static::YEARS_PER_CENTURY + static::YEARS_PER_CENTURY - 1));
}
/**
* Resets the date to the first day of the ISO-8601 week (Monday) and the time to the beginning of that day, which is 00:00:00.
*
* @return static The DateTime instance.
*/
public function startOfWeek() {
// Set the date to the first day of the week
if($this->dayOfWeek != static::MONDAY)
$this->previous(static::MONDAY);
// Set the time to the start of the day
return $this->startOfDay();
}
/**
* Resets the date to the end of the ISO-8601 week (Sunday) and time the end of that day, which is 23:59:59.
*
* @return static The DateTime instance.
*/
public function endOfWeek() {
// Set the date to the last day of the week
if($this->dayOfWeek != static::SUNDAY)
$this->next(static::SUNDAY);
// Set the time to the end of the day
return $this->endOfDay();
}
/**
* Modify to the next occurrence of a given day of the week. If no specific day is provided, the next occurrence of the current day of the week is used.
* This will also reset the time to the start of that day.
*
* @param int|null $dayOfWeek [optional] The day of the week, using the day constants such as static::SUNDAY. Or null to get the next occurrence of the current day.
*
* @return static The DateTime instance.
*/
public function next($dayOfWeek = null) {
// Use the current day of the week if none was provided
if($dayOfWeek === null)
$dayOfWeek = $this->dayOfWeek;
// Find the next occurrence of the day of the week, and return the result
return $this->modify('next ' . static::$DAY_NAMES[$dayOfWeek])->startOfDay();
}
/**
* Modify to the previous occurrence of a given day of the week. If no specific day is provided, the previous occurrence of the current day of the week is used.
* This will also reset the time to the start of that day.
*
* @param int|null $dayOfWeek [optional] The day of the week, using the day constants such as static::SUNDAY. Or null to get the previous occurrence of the current day.
*
* @return static The DateTime instance.
*/
public function previous($dayOfWeek = null) {
// Use the current day of the week if none was provided
if($dayOfWeek === null)
$dayOfWeek = $this->dayOfWeek;
// Find the previous occurrence of the day of the week, and return the result
return $this->modify('last ' . static::$DAY_NAMES[$dayOfWeek])->startOfDay();
}
/**
* Modify to the first occurrence of a given day of the week. If no specific day is provided, the first day of the month is used.
* This will also reset the time to the start of that day.
*
* @param int|null $dayOfWeek [optional] The day of the week, using the day constants such as static::SUNDAY. Or null to get the first day of the month.
*
* @return static|null The DateTime instance, or null on failure.
*/
public function firstOfMonth($dayOfWeek = null) {
// Use the first day of the week if none was provided
if($dayOfWeek === null)
return $this->setDay(1)->startOfDay();
// Get the first day occurrence in the month, and make sure it's valid
if(($dateTime = $this->modify('first ' . static::$DAY_NAMES[$dayOfWeek] . ' of ' . $this->format('F') . ' ' . $this->year)) === null)
return null;
// Parse the date and time
if(($dateTime = static::parse($dateTime)) === null)
return null;
// Set the time to the start of the day and return the result
return $dateTime->startOfDay();
}
/**
* Modify to the last occurrence of a given day of the week. If no specific day is provided, the last day of the month is used.
* This will also reset the time to the start of that day.
*
* @param int|null $dayOfWeek [optional] The day of the week, using the day constants such as static::SUNDAY. Or null to get the first day of the month.
*
* @return static The DateTime instance.
*/
public function lastOfMonth($dayOfWeek = null) {
// Use the last day of the month if none was provided
if($dayOfWeek === null)
return $this->setDay($this->daysInMonth);
// Get the last day occurrence in the month
$dateTime = $this->modify('last ' . static::$DAY_NAMES[$dayOfWeek] . ' of ' . $this->format('F') . ' ' . $this->year);
// Parse the date and time
if(($dateTime = static::parse($dateTime)) === null)
return null;
// Set the time to the start of the day and return the result
return $dateTime->startOfDay();
}
/**
* Modify to the given occurrence of a given day of the week in the current month.
* If the given day is outside the current month no modifications are made an null is returned.
* This will also reset the time to the beginning of the day.
*
* @param int $nth The occurrence of the day of the week.
* @param int $dayOfWeek The day of the week, using the day constants such as static::SUNDAY.
*
* @return static|null The DateTime instance, or null on failure.
*/
public function nthOfMonth($nth, $dayOfWeek) {
// Get a copy of the date and time set to the first day of the month
$dateTime = $this->copy()->firstOfMonth();
// Store the year and month, to use for checking later
$check = $dateTime->format('Y-m');
// Add the number of days to the date and time
if($dateTime->modify('+' . $nth . ' ' . static::$DAY_NAMES[$dayOfWeek]) === null)
return null;
// Make sure the year and month are still the same
if($dateTime->format('Y-m') !== $check)
return null;
// Modify and return the date and time
return $this->modify($dateTime);
}
/**
* Modify to the first occurrence of a given day of the week in the current quarter. If no day of the week if provided, modify to the first day of the current quarter.
* This will also reset the time to the beginning of that day.
*
* @param int|null $dayOfWeek [optional] The day of the week, using the day constants such as static::SUNDAY. Or null to get the first day of the current quarter.
*
* @return static|null The DateTime instance, or null on failure.
*/
public function firstOfQuarter($dayOfWeek = null) {
return $this->setDay(1)->setMonth($this->quarter * 3 - 2)->firstOfMonth($dayOfWeek);
}
/**
* Modify to the last occurrence of the given day of the week in the current quarter. If no day of the week is provided, modify to the first day of the current quarter.
* This will also reset the time to the beginning of that day.
*
* @param int|null $dayOfWeek [optional] The day of the week, using day constants such as static::SUNDAY. Or null to get the last day of the current quarter.
*
* @return static|null The DateTime instance, or null on failure.
*/
public function lastOfQuarter($dayOfWeek = null) {
return $this->setDay(1)->setMonth($this->quarter * 3)->lastOfMonth($dayOfWeek);
}
/**
* Modify to the given occurrence of a given day of the week in the current quarter.
* If the given day is outside the current quarter no modifications are made an null is returned.
* This will also reset the time to the beginning of that day.
*
* @param int $nth The occurrence of the day of the week.
* @param int $dayOfWeek The day of the week, using the day constants such as static::SUNDAY.
*
* @return static|null The DateTime instance, or null on failure.
*/
public function nthOfQuarter($nth, $dayOfWeek) {
// Get a copy of the date and time set to the first day of the month
$dateTime = $this->copy()->setDay(1)->setMonth($this->quarter * 3);
// Get the last month and the year of the quarter
$last_month = $dateTime->getMonth();
$year = $dateTime->getYear();
// Get the nth occurrence of the day of the week in this quarter
// TODO: Why is the modify method not recognized?
$dateTime->firstOfQuarter()->modify('+' . $nth . ' ' . static::$DAY_NAMES[$dayOfWeek]);
// Make sure the date is not outside the current quarter
if($last_month < $dateTime->getMonth() || $year !== $dateTime->getYear())
return null;
// Modify the date and time, return the result
return $this->modify($dateTime);
}
/**
* Modify to the first occurrence of a given day of the week in the current year. If no day of the week is provided the first day of the year is used.
* This will also reset the time to the beginning of that day.
*
* @param int|null $dayOfWeek [optional] The day of the week, using day constants such as static::SUNDAY. Or null to get the first day of the current year.
*
* @return static|null The DateTime instance, or null on failure.
*/
public function firstOfYear($dayOfWeek = null) {
return $this->setMonth(1)->firstOfMonth($dayOfWeek);
}
/**
* Modify to the last occurrence of a given day of the week in the current year. If no day of the week is provided the last day of the year is used.
* This will also reset the time to the beginning of that day.
*
* @param int|null $dayOfWeek [optional] The day of the week, using day constants such as static::SUNDAY. Or null to get the last day of the current year.
*
* @return static|null The DateTime instance, or null on failure.
*/
public function lastOfYear($dayOfWeek = null) {
return $this->setMonth(static::MONTHS_PER_YEAR)->lastOfMonth($dayOfWeek);
}
/**
* Modify to the given occurrence of a given day of the week in the current year.
* If the given day is outside the current year no modifications are made an null is returned.
* This will also reset the time to the beginning of that day.
*
* @param int $nth The occurrence of the day of the week.
* @param int $dayOfWeek The day of the week, using the day constants such as static::SUNDAY.
*
* @return static|null The DateTime instance, or null on failure.
*/
public function nthOfYear($nth, $dayOfWeek) {
// Create a copy of the date and time, and get the nth day of the week
$dateTime = $this->copy()->firstOfYear()->modify('+' . $nth . ' ' . static::$DAY_NAMES[$dayOfWeek]);
// Make sure the date isn't outside the current year
if($this->year != $dateTime->year)
return null;
// Modify and return the date and time
return $this->modify($dateTime);
}
/**
* Get the age of the date and time compared to the current date and time specified by the now() method.
*
* @return int The age of the date and time.
*/
public function getAge() {
return $this->diffInYears(null, false);
}
/**
* Check if it's the birthday. This check whether the month and day are equal to the specified date and time.
*
* @param DateTime|PHPDateTime|string|null $birthday [optional] The DateTime or PHPDateTime instance, the date and time as a string or null to use the now() date and time.
*
* @return boolean True if it's the birthday, false otherwise. False is also returned on failure.
*/
public function isBirthday($birthday) {
// Parse the date and time, return null on failure
if(($birthday = static::parse($birthday, $this->getTimezone())) === null)
return null;
// Check whether the month and day are equal, return the result
return StringUtils::equals($this->format('md'), $birthday->format('md'));
}
/**
* Modify the date and time to the average of the date and time and the specified date and time.
*
* @param DateTime|PHPDateTime|string|null $dateTime [optional] The DateTime or PHPDateTime instance, the date and time as a string or null to use the now() date and time.
*
* @return static|null The DateTime instance, or null on failure.
*/
public function average($dateTime = null) {
// Parse the date and time, return null on failure
if(($dateTime = static::parse($dateTime, $this->getTimezone())) === null)
return null;
// Calculate the difference in seconds and make sure it's valid
if(($differenceSeconds = $this->diffInSeconds($dateTime, false)) === null)
return null;
// Apply the average difference and return the result
return $this->addSeconds((int) ($differenceSeconds / 2));
}
/**
* Get the date and time as a string formatted according to given format.
*
* @param string|null $format [optional] The desired format for the date and time, or null to use the default format.
*
* @return string|null The date and time as a string, or null on failure.
*/
public function format($format = null) {
// Use the default format if the format parameter is null
if($format === null)
$format = self::DEFAULT_FORMAT;
// Get and return the date and time with the proper format, return null on failure
return ($result = parent::format($format)) === false ? null : $result;
}
/**
* Format the date and time as a string.
*
* @param string|null $format [optional] The format to return the date and time with as a string.
*
* @return string|null The date and time as a string, or null on failure.
*/
// TODO: Should we use some kind of human readable formatting, or should we create a different function for this?
public function toString($format = null) {
// Use the default format if it's set to null
if($format === null)
$format = static::DEFAULT_FORMAT;
// Get the date and time as a string with the proper format and return the result, return null on failure
return ($result = $this->format($format)) === false ? null : $result;
}
/**
* Format the date and time as a string.
*
* @return string The date and time as a string, with the default format.
*/
// TODO: To string for humans!
public function __toString() {
// Get the date and time as a string, return an empty string on failure
return ($result = $this->toString()) === null ? '' : $result;
}
/**
* Format the date as a string.
*
* @return string The date as a string.
*/
public function toDateString() {
return $this->format(static::DEFAULT_FORMAT_DATE);
}
/**
* Format the time as a string.
*
* @return string The time as a string.
*/
public function toTimeString() {
return $this->format(static::DEFAULT_FORMAT_TIME);
}
/**
* Convert the date and time into a string with complete formatting.
*
* @return string|null The date and time as a string, or null on failure.
*/
// TODO: Should we create a different method for this, or rename this method?
public function toCompleteString() {
return $this->toString(static::DEFAULT_FORMAT_COMPLETE);
}
}
<?php
/**
* DateTimeUtils.php
*
* A utilities class for the DateTime class.
*
* @author Tim Visee
* @website http://timvisee.com/
* @copyright Copyright (c) Carbon CMS 2015. All rights reserved.
*/
namespace carbon\core\datetime;
use carbon\core\datetime\interval\DateInterval;
use carbon\core\datetime\zone\DateTimeZone;
use Closure;
use DateTime as PHPDateTime;
use DateTimeZone as PHPDateTimeZone;
use InvalidArgumentException;
// Prevent direct requests to this set_file due to security reasons
defined('CARBON_CORE_INIT') or die('Access denied!');
/**
* A utilities class for the DateTime class.
*
* @package carbon\core\datetime
*/
class DateTimeUtils {
// TODO: Make sure all DateTime and PHPDateTime instances are correct!
/**
* Parse a date and time with an optional time zone. A new instance will be created if required.
*
* If the $dateTime parameter is a DateTime zone instance, the instance will be returned and the $timezone parameter is ignored.
* If the $dateTime parameter is anything other than a DateTime zone the date, time and the time zone is parsed through the constructor.
*
* This method allows better fluent syntax because it makes method chaining possible.
*
* @param DateTime|string|null $dateTime [optional] A DateTime or PHPDateTime instance, the time as a string, or null to use the now() time.
* @param DateTimeZone|PHPDateTimeZone|string|DateTime|PHPDateTime|null $timezone [optional] The time zone the specified time is in, or null to use the default time zone if the $time param isn't a DateTime instance. A DateTime or PHPDateTime instance to use it's timezone.
* @param mixed|null $default [optional] The default value returned on failure.
*
* @return DateTime|mixed The DateTime instance, or the default value on failure.
*
* @throws InvalidArgumentException Throws an exception if the date and time couldn't be parsed.
*/
// TODO: Don't use exception catching!
public static function parse($dateTime = null, $timezone = null, $default = null) {
// Return the object if it's already a DateTime instance
if($dateTime instanceof DateTime)
return $dateTime;
// Parse and return the date and time, return the default value on failure
try {
return new DateTime($dateTime, $timezone);
} catch(InvalidArgumentException $ex) {
return $default;
}
}
/**
* Check whether the date and time specified by a equals b.
*
* @param DateTime|PHPDateTime|string|null $a [optional] The DateTime or PHPDateTime instance, the date and time as a string or null to use the now() time.
* @param DateTime|PHPDateTime|string|null $b [optional] The DateTime or PHPDateTime instance, the date and time as a string or null to use the now() time.
* @param mixed|null $default [optional] The default value returned on failure.
*
* @return bool|mixed True if the date and time of a and b equals, false if not. The default value will be returned on failure.
*/
public static function equals($a = null, $b = null, $default = null) {
// Parse the date and time of a, return the default value on failure
if(($a = static::parse($a)) === null)
return $default;
// Compare a and b and return the result, return the default value on failure
return ($result = $a->equals($b)) === null ? $default : $result;
}
/**
* Check whether the date and time specified by a is greater than b.
*
* @param DateTime|PHPDateTime|string|null $a [optional] The DateTime or PHPDateTime instance, the date and time as a string or null to use the now() time.
* @param DateTime|PHPDateTime|string|null $b [optional] The DateTime or PHPDateTime instance, the date and time as a string or null to use the now() time.
* @param mixed|null $default [optional] The default value returned on failure.
*
* @return bool|mixed True if the date and time of a is greater than b, false if not. The default value will be returned on failure.
*/
// TODO: Does this work, or should we compare the timestamps?
public static function isGreaterThan($a = null, $b = null, $default = null) {
// Parse the date and time of a, return the default value on failure
if(($a = static::parse($a)) === null)
return $default;
// Compare a and b and return the result, return the default value on failure
return ($result = $a->isGreaterThan($b)) === null ? $default : $result;
}
/**
* Check whether the date and time specified by a is greater or equal to b.
*
* @param DateTime|PHPDateTime|string|null $a [optional] The DateTime or PHPDateTime instance, the date and time as a string or null to use the now() time.
* @param DateTime|PHPDateTime|string|null $b [optional] The DateTime or PHPDateTime instance, the date and time as a string or null to use the now() time.
* @param mixed|null $default [optional] The default value returned on failure.
*
* @return bool|mixed True if the date and time of a is greater or equal to b, false if not. The default value will be returned on failure.
*/
// TODO: Does this work, or should we compare the timestamps?
// TODO: Should we rename this to isGreaterThanOrEqualTo
public static function isGreaterOrEqualTo($a = null, $b = null, $default = null) {
// Parse the date and time of a, return the default value on failure
if(($a = static::parse($a)) === null)
return $default;
// Compare a and b and return the result, return the default value on failure
return ($result = $a->isGreaterOrEqualTo($b)) === null ? $default : $result;
}
/**
* Check whether the date and time specified by a is less than b.
*
* @param DateTime|PHPDateTime|string|null $a [optional] The DateTime or PHPDateTime instance, the date and time as a string or null to use the now() time.
* @param DateTime|PHPDateTime|string|null $b [optional] The DateTime or PHPDateTime instance, the date and time as a string or null to use the now() time.
* @param mixed|null $default [optional] The default value returned on failure.
*
* @return bool|mixed True if the date and time of a is less than b, false if not. The default value will be returned on failure.
*/
// TODO: Does this work, or should we compare the timestamps?
public static function isLessThan($a = null, $b = null, $default = null) {
// Parse the date and time of a, return the default value on failure
if(($a = static::parse($a)) === null)
return $default;
// Compare a and b and return the result, return the default value on failure
return ($result = $a->isLessThan($b)) === null ? $default : $result;
}
/**
* Check whether the date and time specified by a is less or equal to b.
*
* @param DateTime|PHPDateTime|string|null $a [optional] The DateTime or PHPDateTime instance, the date and time as a string or null to use the now() time.
* @param DateTime|PHPDateTime|string|null $b [optional] The DateTime or PHPDateTime instance, the date and time as a string or null to use the now() time.
* @param mixed|null $default [optional] The default value returned on failure.
*
* @return bool|mixed True if the date and time of a is less or equal b, false if not. The default value will be returned on failure.
*/
// TODO: Does this work, or should we compare the timestamps?
// TODO: Should we rename this to isLessThanOrEqualTo?
public static function isLessOrEqualTo($a = null, $b = null, $default = null) {
// Parse the date and time of a, return the default value on failure
if(($a = static::parse($a)) === null)
return $default;
// Compare a and b and return the result, return the default value on failure
return ($result = $a->isLessOrEqualTo($b)) === null ? $default : $result;
}
/**
* Check whether the specified date and time is between a and b.
* The $a and $b parameter may not be null at the same time or false will be returned.
*
* @param DateTime|PHPDateTime|string|null $dateTime The date and time that needs to be in between a and be as DateTime or PHPDateTime instance, the date and time as a string or null to use the now() value.444444
* @param DateTime|PHPDateTime|string|null $a The date and time as DateTime or PHPDateTime instance, the date and time as a string or null to use the now() time.
* @param DateTime|PHPDateTime|string|null $b The date and time as DateTime or PHPDateTime instance, the date and time as a string or null to use the now() time.
* @param bool $equals [optional] True to also return true if the date equals one of the specified date and times, false otherwise.
* @param mixed|null $default [optional] The default value returned on failure.
*
* @return bool|mixed True if the date is between the specified date and time, or if it equals one of the date and times while $equals is set to true, false if not. The default value will be returned on failure.
*/
public static function isBetween($dateTime = null, $a = null, $b = null, $equals = true, $default = null) {
// Parse the date and time, return the default value on failure
if(($dateTime = static::parse($dateTime)) === null)
return $default;
// Check whether the date and time is in between and return the result, return the default value on failure
return ($result = $dateTime->isBetween($a, $b, $equals)) === null ? $default : $result;
}
/**
* Get the greatest date and time of a and b. If both are equal, a will be returned.
*
* @param DateTime|PHPDateTime|string|null $a [optional] A DateTime or PHPDateTime instance, the date and time as a string or null to use the now() time.
* @param DateTime|PHPDateTime|string|null $b [optional] A DateTime or PHPDateTime instance, the date and time as a string or null to use the now() time.
* @param mixed|null $default [optional] The default value returned on failure.
*
* @return DateTime|mixed The greatest DateTime instance, or the default value on failure.
*/
public static function max($a = null, $b = null, $default = null) {
// Parse the date and time of a, return the default value on failure
if(($a = static::parse($a)) === null)
return $default;
// Compare a and b and return the greatest, return the default value on failure
return ($result = $a->max($b)) === null ? $default : $result;
}
/**
* Get the lowest date and time of a and b. If both are equal, a will be returned.
*
* @param DateTime|PHPDateTime|string|null $a [optional] A DateTime or PHPDateTime instance, the date and time as a string or null to use the now() time.
* @param DateTime|PHPDateTime|string|null $b [optional] A DateTime or PHPDateTime instance, the date and time as a string or null to use the now() time.
* @param mixed|null $default [optional] The default value returned on failure.
*
* @return DateTime|mixed The lowest DateTime instance, or the default value on failure.
*/
public static function min($a = null, $b = null, $default = null) {
// Parse the date and time of a, return the default value on failure
if(($a = static::parse($a)) === null)
return $default;
// Compare a and b and return the smallest, return the default value on failure
return ($result = $a->min($b)) === null ? $default : $result;
}
/**
* Check whether the specified date is a weekday (monday to friday).
*
* @param DateTime|PHPDateTime|string|null $dateTime [optional] A DateTime or PHPDateTime instance, the date and time as a string or null to use the now() time.
* @param mixed|null $default [optional] The default value returned on failure.
*
* @return bool|mixed True if this is a weekday, false if not. The default value will be returned on failure.
*/
public static function isWeekday($dateTime = null, $default = null) {
// Parse the date and time, return the default value on failure
if(($dateTime = static::parse($dateTime)) === null)
return $default;
// Check whether the specified date is a weekday, return the result
return $dateTime->isWeekday();
}
/**
* Check whether the specified date is a weekend day (saturday or sunday).
*
* @param DateTime|PHPDateTime|string|null $dateTime [optional] A DateTime or PHPDateTime instance, the date and time as a string or null to use the now() time.
* @param mixed|null $default [optional] The default value returned on failure.
*
* @return bool|mixed True if this is a weekend day, false if not. The default value on failure.
*/
public static function isWeekend($dateTime = null, $default = null) {
// Parse the date and time, return the default value on failure
if(($dateTime = static::parse($dateTime)) === null)
return $default;
// Check whether the specified date is in the weekend, return the result
return $dateTime->isWeekend();
}
/**
* Check whether the specified date is today.
*
* @param DateTime|PHPDateTime|string|null $dateTime [optional] A DateTime or PHPDateTime instance, the date and time as a string or null to use the now() time.
* @param mixed|null $default [optional] The default value returned on failure.
*
* @return bool|mixed True if this is today, false if not. The default value will be returned on failure.
*/
public static function isToday($dateTime = null, $default = null) {
// Parse the date and time, return the default value on failure
if(($dateTime = static::parse($dateTime)) === null)
return $default;
// Check whether the specified date is today, return the result
return $dateTime->isToday();
}
/**
* Check whether the specified date is tomorrow.
*
* @param DateTime|PHPDateTime|string|null $dateTime [optional] A DateTime or PHPDateTime instance, the date and time as a string or null to use the now() time.
* @param mixed|null $default [optional] The default value returned on failure.
*
* @return bool True if this is tomorrow, false if not. The default value will be returned on failure.
*/
public static function isTomorrow($dateTime = null, $default = null) {
// Parse the date and time, return the default value on failure
if(($dateTime = static::parse($dateTime)) === null)
return $default;
// Check whether the specified date is tomorrow, return the result
return $dateTime->isTomorrow();
}
/**
* Check whether the specified date is yesterday.
*
* @param DateTime|PHPDateTime|string|null $dateTime [optional] A DateTime or PHPDateTime instance, the date and time as a string or null to use the now() time.
* @param mixed|null $default [optional] The default value returned on failure.
*
* @return bool true if this is yesterday, false if not. The default value will be returned on failure.
*/
public static function isYesterday($dateTime = null, $default = null) {
// Parse the date and time, return the default value on failure
if(($dateTime = static::parse($dateTime)) === null)
return $default;
// Check whether the specified date is yesterday, return the result
return $dateTime->isYesterday();
}
/**
* Check whether the specified date and time is in the future. If the date and time equals the now() date and time false is returned.
*
* @param DateTime|PHPDateTime|string|null $dateTime [optional] A DateTime or PHPDateTime instance, the date and time as a string or null to use the now() time.
* @param mixed|null $default [optional] The default value returned on failure.
*
* @return bool True if this is in the future, false if not. The default value will be returned on failure.
*/
public static function isFuture($dateTime = null, $default = null) {
// Parse the date and time, return the default value on failure
if(($dateTime = static::parse($dateTime)) === null)
return $default;
// Check whether the specified date is in the future, return the result
return $dateTime->isFuture();
}
/**
* Check whether the specified date and time is in the past. If the date and time equals the now() date and time false is returned.
*
* @param DateTime|PHPDateTime|string|null $dateTime [optional] A DateTime or PHPDateTime instance, the date and time as a string or null to use the now() time.
* @param mixed|null $default [optional] The default value returned on failure.
*
* @return bool True if this is in the past, false if not. The default value will be returned on failure.
*/
public static function isPast($dateTime = null, $default = null) {
// Parse the date and time, return the default value on failure
if(($dateTime = static::parse($dateTime)) === null)
return $default;
// Check whether the specified date is in the past, return the result
return $dateTime->isPast();
}
/**
* Check whether the specified date is a leap year.
*
* @param DateTime|PHPDateTime|string|null $dateTime [optional] A DateTime or PHPDateTime instance, the date and time as a string or null to use the now() time.
* @param mixed|null $default [optional] The default value returned on failure.
*
* @return bool True if this is a leap year, false if not. The default value will be returned on failure.
*/
public static function isLeapYear($dateTime = null, $default = null) {
// Parse the date and time, return the default value on failure
if(($dateTime = static::parse($dateTime)) === null)
return $default;
// Check whether the specified date is a leap year, return the result
return $dateTime->isLeapYear();
}
/**
* Check whether the year of a and b is the same.
*
* @param DateTime|PHPDateTime|string|null $a [optional] A DateTime or PHPDateTime instance, the date and time as a string or null to use the now() time.
* @param DateTime|PHPDateTime|string|null $b [optional] A DateTime or PHPDateTime instance, the date and time as a string or null to use the now() time.
* @param mixed|null $default [optional] The default value returned on failure.
*
* @return bool True if year is the same as the specified date, false otherwise. False will also be returned on failure.
*/
public function isSameYear($a = null, $b = null, $default = null) {
// Parse the date and time of a and b, return the default value on failure
if(($a = static::parse($a)) === null || ($b = static::parse($b)) === null)
return $default;
// Check whether the time of a and b is the same and return the result
return $a->isSameYear($b);
}
/**
* Check whether the month of a and b is the same.
*
* @param DateTime|PHPDateTime|string|null $a [optional] A DateTime or PHPDateTime instance, the date and time as a string or null to use the now() time.
* @param DateTime|PHPDateTime|string|null $b [optional] A DateTime or PHPDateTime instance, the date and time as a string or null to use the now() time.
* @param mixed|null $default [optional] The default value returned on failure.
*
* @return bool True if month is the same as the specified date, false otherwise. False will also be returned on failure.
*/
public function isSameMonth($a = null, $b = null, $default = null) {
// Parse the date and time of a and b, return the default value on failure
if(($a = static::parse($a)) === null || ($b = static::parse($b)) === null)
return $default;
// Check whether the time of a and b is the same and return the result
return $a->isSameMonth($b);
}
/**
* Check whether the ISO-8601 week of a and b is the same.
*
* @param DateTime|PHPDateTime|string|null $a [optional] A DateTime or PHPDateTime instance, the date and time as a string or null to use the now() time.
* @param DateTime|PHPDateTime|string|null $b [optional] A DateTime or PHPDateTime instance, the date and time as a string or null to use the now() time.
* @param mixed|null $default [optional] The default value returned on failure.
*
* @return bool True if the ISO-8601 week is the same as the specified date, false otherwise. False will also be returned on failure.
*/
public function isSameWeek($a = null, $b = null, $default = null) {
// Parse the date and time of a and b, return the default value on failure
if(($a = static::parse($a)) === null || ($b = static::parse($b)) === null)
return $default;
// Check whether the time of a and b is the same and return the result
return $a->isSameWeek($b);
}
/**
* Check whether the day of a and b is the same.
*
* @param DateTime|PHPDateTime|string|null $a [optional] A DateTime or PHPDateTime instance, the date and time as a string or null to use the now() time.
* @param DateTime|PHPDateTime|string|null $b [optional] A DateTime or PHPDateTime instance, the date and time as a string or null to use the now() time.
* @param mixed|null $default [optional] The default value returned on failure.
*
* @return bool|mixed True if the date of a and b are the same, false if not. The default value will be returned on failure.
*/
public static function isSameDate($a = null, $b = null, $default = null) {
// Parse the date and time of a and b, return the default value on failure
if(($a = static::parse($a)) === null || ($b = static::parse($b)) === null)
return $default;
// Check whether the time of a and b is the same and return the result
return $a->isSameDate($b);
}
/**
* Check whether the hour of a and b is the same.
*
* @param DateTime|PHPDateTime|string|null $a [optional] A DateTime or PHPDateTime instance, the date and time as a string or null to use the now() time.
* @param DateTime|PHPDateTime|string|null $b [optional] A DateTime or PHPDateTime instance, the date and time as a string or null to use the now() time.
* @param bool $checkDate [optional] True to make sure the dates are equal, false to just compare the time.
* @param mixed|null $default [optional] The default value returned on failure.
*
* @return bool True if hour is the same as the specified date and time, false otherwise. False will also be returned on failure.
*/
public function isSameHour($a = null, $b = null, $checkDate = true, $default = null) {
// Parse the date and time of a and b, return the default value on failure
if(($a = static::parse($a)) === null || ($b = static::parse($b)) === null)
return $default;
// Check whether the time of a and b is the same and return the result
return $a->isSameHour($b, $checkDate);
}
/**
* Check whether the minute of a and b is the same.
*
* @param DateTime|PHPDateTime|string|null $a [optional] A DateTime or PHPDateTime instance, the date and time as a string or null to use the now() time.
* @param DateTime|PHPDateTime|string|null $b [optional] A DateTime or PHPDateTime instance, the date and time as a string or null to use the now() time.
* @param bool $checkDate [optional] True to make sure the dates are equal, false to just compare the time.
* @param mixed|null $default [optional] The default value returned on failure.
*
* @return bool True if minute is the same as the specified date and time, false otherwise. False will also be returned on failure.
*/
public function isSameMinute($a = null, $b = null, $checkDate = true, $default = null) {
// Parse the date and time of a and b, return the default value on failure
if(($a = static::parse($a)) === null || ($b = static::parse($b)) === null)
return $default;
// Check whether the time of a and b is the same and return the result
return $a->isSameMinute($b, $checkDate);
}
/**
* Check whether the time of a and b is the same.
*
* @param DateTime|PHPDateTime|string|null $a [optional] A DateTime or PHPDateTime instance, the date and time as a string or null to use the now() time.
* @param DateTime|PHPDateTime|string|null $b [optional] A DateTime or PHPDateTime instance, the date and time as a string or null to use the now() time.
* @param bool $checkDate [optional] True to make sure the dates are equal, false to just compare the time.
* @param mixed|null $default [optional] The default value returned on failure.
*
* @return bool True if time is the same as the specified date and time, false otherwise. False will also be returned on failure.
*/
public function isSameTime($a = null, $b = null, $checkDate = true, $default = null) {
// Parse the date and time of a and b, return the default value on failure
if(($a = static::parse($a)) === null || ($b = static::parse($b)) === null)
return $default;
// Check whether the time of a and b is the same and return the result
return $a->isSameTime($b, $checkDate);
}
/**
* Get the difference of a and b.
*
* @param DateTime|PHPDateTime|string|null $a [optional] A DateTime or PHPDateTime instance, the date and time as a string or null to use the now() date and time.
* @param DateTime|PHPDateTime|string|null $b [optional] A DateTime or PHPDateTime instance, the date and time as a string or null to use the now() date and time.
* @param boolean $absolute [optional] Get the absolute of the difference in years.
* @param mixed|null $default [optional] The default value returned on failure.
*
* @return \DateInterval|mixed The difference of a and b, or the default value on failure.
*/
public static function diff($a = null, $b = null, $absolute = true, $default = null) {
// Parse the date and time of a, return the default value on failure
if(($a = static::parse($a)) === null)
return $default;
// TODO: Return a Carbon CMS DateInterval instance!
// Get the difference of a and b and return the result, return the default value on failure
return ($result = $a->diff($b, $absolute)) === null ? $default : $result;
}
/**
* Get the difference of a and b by the given interval using a filter closure.
* The callback will be called for each period in the given time frame. If the callback returns true the period is included as difference, false should be returned otherwise.
*
* @param DateInterval $dateInterval An interval to traverse by.
* @param Closure $callback The callback function to call for each period as filter.
* @param DateTime|PHPDateTime|string|null $a [optional] The DateTime or PHPDateTime instance, the date and time as a string or null to use the now() date and time.
* @param DateTime|PHPDateTime|string|null $b [optional] The DateTime or PHPDateTime instance, the date and time as a string or null to use the now() date and time.
* @param boolean $absolute [optional] True to get the absolute difference, false otherwise.
* @param mixed|null $default [optional] The default value returned on failure.
*
* @return int|mixed The difference of the date interval in the given time frame. The default value will be returned on failure.
*/
public function diffFiltered($dateInterval, Closure $callback, $a = null, $b = null, $absolute = true, $default = null) {
// Parse the date and time of a, return the default value on failure
if(($a = static::parse($a)) === null)
return $default;
// Call the difference filtered method on a and return the result, return the default value on failure
return ($result = $a->diffFiltered($dateInterval, $callback, $b, $absolute)) === null ? $default : $result;
}
/**
* Get the difference in years of a and b.
*
* @param DateTime|PHPDateTime|string|null $a [optional] A DateTime or PHPDateTime instance, the date and time as a string or null to use the now() date and time.
* @param DateTime|PHPDateTime|string|null $b [optional] A DateTime or PHPDateTime instance, the date and time as a string or null to use the now() date and time.
* @param boolean $absolute [optional] Get the absolute of the difference in years.
* @param mixed|null $default [optional] The default value returned on failure.
*
* @return int|mixed The difference in years of a and b, or the default value on failure.
*/
public static function diffInYears($a = null, $b = null, $absolute = true, $default = null) {
// Parse the date and time of a, return the default value on failure
if(($a = static::parse($a)) === null)
return $default;
// Get the difference in years of a and b and return the result, return the default value on failure
return ($result = $a->diffInYears($b, $absolute)) === null ? $default : $result;
}
/**
* Get the difference in months of a and b.
*
* @param DateTime|PHPDateTime|string|null $a [optional] A DateTime or PHPDateTime instance, the date and time as a string or null to use the now() date and time.
* @param DateTime|PHPDateTime|string|null $b [optional] A DateTime or PHPDateTime instance, the date and time as a string or null to use the now() date and time.
* @param boolean $absolute [optional] Get the absolute of the difference in months.
* @param mixed|null $default [optional] The default value returned on failure.
*
* @return int|mixed The difference in years of a and b, or the default value on failure.
*/
public static function diffInMonths($a = null, $b = null, $absolute = true, $default = null) {
// Parse the date and time of a, return the default value on failure
if(($a = static::parse($a)) === null)
return $default;
// Get the difference in months of a and b and return the result, return the default value on failure
return ($result = $a->diffInMonths($b, $absolute)) === null ? $default : $result;
}
/**
* Get the difference in weeks of a and b.
*
* @param DateTime|PHPDateTime|string|null $a [optional] A DateTime or PHPDateTime instance, the date and time as a string or null to use the now() date and time.
* @param DateTime|PHPDateTime|string|null $b [optional] A DateTime or PHPDateTime instance, the date and time as a string or null to use the now() date and time.
* @param boolean $absolute [optional] Get the absolute of the difference in weeks.
* @param mixed|null $default [optional] The default value returned on failure.
*
* @return int|mixed The difference in years of a and b, or the default value on failure.
*/
public static function diffInWeeks($a = null, $b = null, $absolute = true, $default = null) {
// Parse the date and time of a, return the default value on failure
if(($a = static::parse($a)) === null)
return $default;
// Get the difference in weeks of a and b and return the result, return the default value on failure
return ($result = $a->diffInWeeks($b, $absolute)) === null ? $default : $result;
}
/**
* Get the difference in weekdays of a and b.
*
* @param DateTime|PHPDateTime|string|null $a [optional] A DateTime or PHPDateTime instance, the date and time as a string or null to use the now() date and time.
* @param DateTime|PHPDateTime|string|null $b [optional] A DateTime or PHPDateTime instance, the date and time as a string or null to use the now() date and time.
* @param boolean $absolute Get the absolute of the difference.
* @param mixed|null $default [optional] The default value returned on failure.
*
* @return int The difference in weekdays, or the default value returned on failure.
*/
public function diffInWeekdays($a = null, $b = null, $absolute = true, $default = null) {
// Parse the date and time of a, return the default value on failure
if(($a = static::parse($a)) === null)
return $default;
// Get the difference in weekdays of a and b and return the result, return the default value on failure
return ($result = $a->diffInWeekdays($b, $absolute)) === null ? $default : $result;
}
/**
* Get the difference in weekend days of a and b.
*
* @param DateTime|PHPDateTime|string|null $a [optional] A DateTime or PHPDateTime instance, the date and time as a string or null to use the now() date and time.
* @param DateTime|PHPDateTime|string|null $b [optional] A DateTime or PHPDateTime instance, the date and time as a string or null to use the now() date and time.
* @param boolean $absolute Get the absolute of the difference.
* @param mixed|null $default [optional] The default value returned on failure.
*
* @return int The difference in weekend days, or the default value returned on failure.
*/
public function diffInWeekendDays($a = null, $b = null, $absolute = true, $default = null) {
// Parse the date and time of a, return the default value on failure
if(($a = static::parse($a)) === null)
return $default;
// Get the difference in weekend days of a and b and return the result, return the default value on failure
return ($result = $a->diffInWeekendDays($b, $absolute)) === null ? $default : $result;
}
/**
* Get the difference in days of a and b.
*
* @param DateTime|PHPDateTime|string|null $a [optional] A DateTime or PHPDateTime instance, the date and time as a string or null to use the now() date and time.
* @param DateTime|PHPDateTime|string|null $b [optional] A DateTime or PHPDateTime instance, the date and time as a string or null to use the now() date and time.
* @param boolean $absolute [optional] Get the absolute of the difference in days.
* @param mixed|null $default [optional] The default value returned on failure.
*
* @return int|mixed The difference in years of a and b, or the default value on failure.
*/
public static function diffInDays($a = null, $b = null, $absolute = true, $default = null) {
// Parse the date and time of a, return the default value on failure
if(($a = static::parse($a)) === null)
return $default;
// Get the difference in days of a and b and return the result, return the default value on failure
return ($result = $a->diffInDays($b, $absolute)) === null ? $default : $result;
}
/**
* Get the difference in days of a and b using a filter closure.
*
* @param Closure $callback The callback function to call for each day as filter.
* @param DateTime|PHPDateTime|string|null $a [optional] A DateTime or PHPDateTime instance, the date and time as a string or null to use the now() date and time.
* @param DateTime|PHPDateTime|string|null $b [optional] A DateTime or PHPDateTime instance, the date and time as a string or null to use the now() date and time.
* @param boolean $absolute Get the absolute of the difference.
* @param mixed|null $default [optional] The default value returned on failure.
*
* @return int|null The difference in days. The default value will be returned on failure.
*/
public function diffInDaysFiltered(Closure $callback, $a = null, $b = null, $absolute = true, $default = null) {
// Parse the date and time of a, return the default value on failure
if(($a = static::parse($a)) === null)
return $default;
// Get the difference in days of a and b using a filter closure and return the result, return the default value on failure
return ($result = $a->diffInDaysFiltered($callback, $b, $absolute)) === null ? $default : $result;
}
/**
* Get the difference in hours of a and b.
*
* @param DateTime|PHPDateTime|string|null $a [optional] A DateTime or PHPDateTime instance, the date and time as a string or null to use the now() date and time.
* @param DateTime|PHPDateTime|string|null $b [optional] A DateTime or PHPDateTime instance, the date and time as a string or null to use the now() date and time.
* @param boolean $absolute [optional] Get the absolute of the difference in hours.
* @param mixed|null $default [optional] The default value returned on failure.
*
* @return int|mixed The difference in years of a and b, or the default value on failure.
*/
public static function diffInHours($a = null, $b = null, $absolute = true, $default = null) {
// Parse the date and time of a, return the default value on failure
if(($a = static::parse($a)) === null)
return $default;
// Get the difference in hours of a and b and return the result, return the default value on failure
return ($result = $a->diffInHours($b, $absolute)) === null ? $default : $result;
}
/**
* Get the difference in hours of a and b using a filter closure.
*
* @param Closure $callback The callback function to call for each hour as filter.
* @param DateTime|PHPDateTime|string|null $a [optional] A DateTime or PHPDateTime instance, the date and time as a string or null to use the now() date and time.
* @param DateTime|PHPDateTime|string|null $b [optional] A DateTime or PHPDateTime instance, the date and time as a string or null to use the now() date and time.
* @param boolean $absolute Get the absolute of the difference.
* @param mixed|null $default [optional] The default value returned on failure.
*
* @return int|null The difference in hours. The default value will be returned on failure.
*/
public function diffInHoursFiltered(Closure $callback, $a = null, $b = null, $absolute = true, $default = null) {
// Parse the date and time of a, return the default value on failure
if(($a = static::parse($a)) === null)
return $default;
// Get the difference in hours of a and b using a filter closure and return the result, return the default value on failure
return ($result = $a->diffInHoursFiltered($callback, $b, $absolute)) === null ? $default : $result;
}
/**
* Get the difference in minutes of a and b.
*
* @param DateTime|PHPDateTime|string|null $a [optional] A DateTime or PHPDateTime instance, the date and time as a string or null to use the now() date and time.
* @param DateTime|PHPDateTime|string|null $b [optional] A DateTime or PHPDateTime instance, the date and time as a string or null to use the now() date and time.
* @param boolean $absolute [optional] Get the absolute of the difference in minutes.
* @param mixed|null $default [optional] The default value returned on failure.
*
* @return int|mixed The difference in years of a and b, or the default value on failure.
*/
public static function diffInMinutes($a = null, $b = null, $absolute = true, $default = null) {
// Parse the date and time of a, return the default value on failure
if(($a = static::parse($a)) === null)
return $default;
// Get the difference in minutes of a and b and return the result, return the default value on failure
return ($result = $a->diffInMinutes($b, $absolute)) === null ? $default : $result;
}
/**
* Get the difference in seconds of a and b.
*
* @param DateTime|PHPDateTime|string|null $a [optional] A DateTime or PHPDateTime instance, the date and time as a string or null to use the now() date and time.
* @param DateTime|PHPDateTime|string|null $b [optional] A DateTime or PHPDateTime instance, the date and time as a string or null to use the now() date and time.
* @param boolean $absolute [optional] Get the absolute of the difference in seconds.
* @param mixed|null $default [optional] The default value returned on failure.
*
* @return int|mixed The difference in years of a and b, or the default value on failure.
*/
public static function diffInSeconds($a = null, $b = null, $absolute = true, $default = null) {
// Parse the date and time of a, return the default value on failure
if(($a = static::parse($a)) === null)
return $default;
// Get the difference in seconds of a and b and return the result, return the default value on failure
return ($result = $a->diffInSeconds($b, $absolute)) === null ? $default : $result;
}
/**
* Get the number of seconds since midnight of the specified date and time.
*
* @param DateTime|PHPDateTime|string|null $dateTime [optional] A DateTime or PHPDateTime instance, the date and time as string or null to use the now() date and time.
* @param mixed|null $default [optional] The default value returned on failure.
*
* @return int|mixed The number of seconds or the default value on failure.
*/
public static function secondsSinceMidnight($dateTime = null, $default = null) {
// Parse the date and time, return the default value on failure
if(($dateTime = static::parse($dateTime)) === null)
return $default;
// Get and return the number of seconds since midnight
return $dateTime->secondsSinceMidnight();
}
/**
* Get the number of seconds of the specified date and time until the end of the day, which is 23:23:59.
*
* @param DateTime|PHPDateTime|string|null $dateTime [optional] A DateTime or PHPDateTime instance, the date and time as string or null to use the now() date and time.
* @param mixed|null $default [optional] The default value returned on failure.
*
* @return int|mixed The number of seconds until the end of the day, or the default value on failure.
*/
public static function secondsUntilEndOfDay($dateTime = null, $default = null) {
// Parse the date and time, return the default value on failure
if(($dateTime = static::parse($dateTime)) === null)
return $default;
// Get and return the number of seconds since midnight
return $dateTime->secondsUntilEndOfDay();
}
/**
* Get the age of the specified date and time compared to the current date and time specified by the now() method.
*
* @param DateTime|PHPDateTime|string|null $dateTime [optional] The DateTime or PHPDateTime instance, the date and time as a string or null to use the now() date and time.
* @param mixed|null $default [optional] The default value returned on failure.
*
* @return int|mixed The age of the date and time, or the default value on failure.
*/
public function getAge($dateTime = null, $default = null) {
// Parse the date and time, return the default value on failure
if(($dateTime = static::parse($dateTime)) === null)
return $default;
// Get the age, return the default value on failure
if(($age = $dateTime->getAge()) === null)
return $default;
// Return the age
return $age;
}
/**
* Check whether it's the birthday of the specified date and time. This compares the month and day of both dates.
*
* @param DateTime|PHPDateTime|string|null $dateTime [optional] The DateTime or PHPDateTime instance, the date and time as a string or null to use the now() date and time.
* @param DateTime|PHPDateTime|string|null $birthday [optional] The DateTime or PHPDateTime instance, the date and time as a string or null to use the now() date and time.
* @param mixed|null $default [optional] The default value returned on failure.
*
* @return boolean True if it's the birthday, false if not. The default value will be returned on failure.
*/
public static function isBirthday($dateTime = null, $birthday = null, $default = null) {
// Parse the date and time, return the default value on failure
if(($dateTime = static::parse($dateTime)) === null)
return $default;
// Check whether it's the birthday of the specified date and time and return the result, return the default value on failure
return ($result = $dateTime->isBirthday($birthday)) === null ? $default : $result;
}
/**
* Get the average in date and time of a and b. A new DateTime instance is returned with the average date and time.
*
* @param DateTime|PHPDateTime|string|null $a [optional] The DateTime or PHPDateTime instance, the date and time as a string or null to use the now() date and time.
* @param DateTime|PHPDateTime|string|null $b [optional] The DateTime or PHPDateTime instance, the date and time as a string or null to use the now() date and time.
* @param mixed|null $default [optional] The default value returned on failure.
*
* @return DateTime|mixed The average as DateTime instance, or the default value on failure.
*/
public static function average($a = null, $b = null, $default = null) {
// Parse the date and time of a, return the default value on failure
if(($a = static::parse($a)) === null)
return $default;
// Get the average date and time of a and b and return the result, return the default value on failure
return ($result = $a->copy()->average($b)) === null ? $default : $result;
}
}
<?php
namespace carbon\core\datetime\zone;
use carbon\core\datetime\DateTime;
use carbon\core\datetime\DateTimeUtils;
use carbon\core\util\StringUtils;
use DateTime as PHPDateTime;
use DateTimeZone as PHPDateTimeZone;
// Prevent direct requests to this file due to security reasons
defined('CARBON_CORE_INIT') or die('Access denied!');
class DateTimeZone extends PHPDateTimeZone {
// TODO: Make sure all DateTimeZone and PHPDateTimeZone instances are correct!
/**
* Constructor.
*
* @param string|PHPDateTimeZone|PHPDateTimeZone|null $timezone [optional] The timezone as a string, or as DateTimeZone or PHPDateTimeZone instance. Null to use the default timezone.
*
* @throws \Exception Throws an exception on failure.
*/
// TODO: Does this constructor still throw an error on failure?
public function __construct($timezone) {
// Use the default timezone if the parameter is null
if($timezone === null)
$timezone = DateTimeZoneUtils::getDefaultTimezone();
// If the timezone is already a DateTimeZone instance, copy it
if($timezone instanceof PHPDateTimeZone) {
PHPDateTimeZone::__construct($timezone->getName());
return $this;
}
// Parse PHPDateTimeZone instances
if($timezone instanceof PHPDateTimeZone) {
PHPDateTimeZone::__construct($timezone->getName());
return $this;
}
// Try to construct the parent object
PHPDateTimeZone::__construct($timezone);
return $this;
}
/**
* Parse a timezone. A new instance will be created if required.
*
* @param PHPDateTimeZone|PHPDateTimeZone|string|DateTime|PHPDateTime|null $timezone The timezone to parse as DateTimeZone or PHPDateTimeZone instance or as a string. A DateTime or PHPDateTime instance to use it's timezone. Null to parse as the default timezone.
*
* @return PHPDateTimeZone|null The parsed timezone as DateTimeZone instance, or null on failure.
*/
public static function parse($timezone = null) {
return DateTimeZoneUtils::parse($timezone, null);
}
/**
* Check whether this timezone equals another timezone.
*
* @param PHPDateTimeZone|PHPDateTimeZone|string|DateTime|PHPDateTime $timezone The other timezone as DateTimeZone or PHPDateTimeZone instance, or the timezone ID as a string. A DateTime or PHPDateTime instance may be supplied to use it's timezone.
*
* @return bool True if the timezones equal, false if not. False will also be returned if an error occurred.
*/
public function equals($timezone) {
// Parse the timezone
if(($timezone = static::parse($timezone)) === null)
return false;
// Compare the timezone IDs of both instances, return the result
return StringUtils::equals($this->getName(), $timezone->getName(), false);
}
/**
* Check whether a timezone is local relative to this timezone. This compares the offset of both timezones at a specific point in time.
*
* @param PHPDateTimeZone|PHPDateTimeZone|string|DateTime|PHPDateTime|null $timezone [optional] A DateTimeZone or PHPDateTimeZone instance, the timezone ID as a string, a DateTime or PHPDateTime instance to use it's timezone or null to use the defualt timezone.
* @param DateTime|PHPDateTime|string|null $dateTime [optional] The specific point in date and time to compare the offsets at. A DateTime or PHPDateTime instance, the date and time as a string or null to use the now() value.
*
* @return bool True if the timezone is local, false if not. False will also be returned on failure.
*/
public function isLocal($timezone = null, $dateTime = null) {
// Parse the timezone, return false on failure
if(($timezone = static::parse($timezone)) === null)
return false;
// Parse the date and time, return false on failure
if(($dateTime = DateTimeUtils::parse($dateTime, $timezone, null)) === null)
return false;
// Compare the offsets of both timezones at the specific point in time, return the result
return $this->getOffset($dateTime) == $timezone->getOffset($dateTime);
}
}
<?php
namespace carbon\core\datetime\zone;
use carbon\core\datetime\DateTime;
use DateTime as PHPDateTime;
use DateTimeZone as PHPDateTimeZone;
// Prevent direct requests to this file due to security reasons
defined('CARBON_CORE_INIT') or die('Access denied!');
class DateTimeZoneUtils {
// TODO: Make sure all DateTimeZone and PHPDateTimeZone instances are correct!
// TODO: TimeZone or Timezone? Use only one of the two, not both!
/**
* Parse a timezone. A new instance will be created if required.
*
* @param DateTimeZone|PHPDateTimeZone|string|DateTime|PHPDateTime|null $timezone The timezone to parse as DateTimeZone or PHPDateTimeZone instance or as a string. A DateTime or PHPDateTime instance to use it's timezone. Null to parse as the default timezone.
* @param mixed|null $default [optional] The default value returned on failure.
*
* @return DateTimeZone|mixed The parsed timezone as DateTimeZone instance, or the default value on failure.
*/
public static function parse($timezone = null, $default = null) {
// Return the timezone if it's already a DateTimeZone instance
if($timezone instanceof DateTimeZone)
return $timezone;
// Get the timezone form a DateTime object
else if($timezone instanceof DateTime)
$timezone = $timezone->getTimezone();
// Get the timezone from a PHPDateTimeZone object, and make sure it's valid
else if($timezone instanceof PHPDateTime)
if(($timezone = static::parse($timezone->getTimezone())) === null)
return $default;
// If the timezone is a string, make sure the timezone ID is valid, return the default value if not
// TODO: Should we check this for everything, or just for strings?
if(is_string($timezone))
if(!static::isValidTimezoneId($timezone))
return $default;
// Try to parse and return the timezone
try {
return new DateTimeZone($timezone);
} catch(\Exception $ex) {
// Return the default value on failure
return $default;
}
}
// TODO: equals(...); method (also to the base class)!
/**
* Get the default timezone for all date and time functions.
*
* @return DateTimeZone The default timezone.
*/
public static function getDefaultTimezone() {
return static::parse(date_default_timezone_get());
}
/**
* Set the default timezone for all date and time functions.
*
* @param DateTimeZone|PHPDateTimeZone|string|null $timezone The timezone as DateTimeZone instance, the timezone ID as a string or null to use the default timezone configured in PHPs configuration file.
*
* @return bool True if succeed, false on failure.
*/
public static function setDefaultTimezone($timezone) {
// Check whether the default timezone should be restored
if($timezone === null)
// TODO: Read the real-default timezone from other sources if possible
$timezone = ini_get('date.timezone');
// Parse the timezone and make sure it's valid
if(($timezone = static::parse($timezone, null)) === null)
return false;
// Set the default timezone
date_default_timezone_set($timezone->getName());
}
/**
* Check whether a timezone ID is valid. A timezone ID is specified by a string, see PHPs list of supported timezones.
*
* @param string $timezone The timezone ID to validate.
*
* @return bool True if the timezone ID is valid, false otherwise.
*/
// TODO: Can we improve the speed and readability of this method?
public static function isValidTimezoneId($timezone) {
// Create a list of valid timezones
$valid = array();
// Get the list of supported PHP timezones
$timezoneList = timezone_abbreviations_list();
// Create a list of valid timezones
foreach($timezoneList as $zone)
foreach($zone as $item)
$valid[$item['timezone_id']] = true;
// Remove the invalid keys
unset($valid['']);
// Check weather the timezone ID exists as a key in the array, return the result
return !!$valid[$timezone];
}
/**
* Check whether the timezones a and b are equal to each other.
*
* @param DateTimeZone|PHPDateTimeZone|string|null $a [optional] The timezone as DateTimeZone or PHPDateTimeZone instance, the timezone ID as a string or null to use the default timezone.
* @param DateTimeZone|PHPDateTimeZone|string|null $b [optional] The timezone as DateTimeZone or PHPDateTimeZone instance, the timezone ID as a string or null to use the default timezone.
* @param null|mixed $default [optional] The default value returned on failure.
*
* @return bool|mixed True if the timezones are equal, false if not. The default value will be returned on failure.
*/
public static function equals($a = null, $b = null, $default = null) {
// Parse the timezone of a, return the default value on failure
if(($a = static::parse($a, null)) === null)
return $default;
// Check whether the timezones are equal, return the result
return $a->equals($b);
}
/**
* Check whether the timezone a and b are local. This compares the offset of both timezones at a specific point in time.
*
* @param DateTimeZone|PHPDateTimeZone|string|DateTime|PHPDateTime|null $a [optional] A DateTimeZone or PHPDateTimeZone instance, the timezone ID as a string, a DateTime or PHPDateTime instance to use it's timezone or null to use the defualt timezone.
* @param DateTimeZone|PHPDateTimeZone|string|DateTime|PHPDateTime|null $b [optional] A DateTimeZone or PHPDateTimeZone instance, the timezone ID as a string, a DateTime or PHPDateTime instance to use it's timezone or null to use the defualt timezone.
* @param DateTime|PHPDateTime|string|null $dateTime [optional] The specific point in date and time to compare the offsets at. A DateTime or PHPDateTime instance, the date and time as a string or null to use the now() value.
* @param mixed|null $default [optional] The default value returned on failure.
*
* @return bool True if the timezone is local, false if not. The default value will be returned on failure.
*/
public function isLocal($a = null, $b = null, $dateTime = null, $default = null) {
// Parse the timezone of a, return false on failure
if(($a = static::parse($a)) === null)
return $default;
// Check whether the timezone of a and b are local, return the result or return the default value on failure
return ($result = $a->isLocal($b, $dateTime)) === null ? $default : $result;
}
/**
* Creates a DateTimeZone from a string or a PHPDateTimeZone.
*
* @param PHPDateTimeZone|string|null $timeZone
*
* @return PHPDateTimeZone
*
* @throws \InvalidArgumentException
*/
// TODO: Should we keep this method?
public static function safeCreateDateTimeZone($timeZone) {
// Return the default time zone if nothing was supplied
if($timeZone === null)
// Don't return null to avoid the PHP bug #52063 (< v5.3.6)
return static::getDefaultTimezone();
// Immediately return the object if it's already a time zone instance
if($timeZone instanceof PHPDateTimeZone)
return $timeZone;
// Try to parse the timezone, throw an exception on failure
if(($timeZone = static::parse($timeZone, null)) === null)
// Failed to create a time zone object, thrown an exception
throw new \InvalidArgumentException('Unknown or bad timezone ('.$timeZone.')');
return $timeZone;
}
}
<?php
namespace carbon\core\datetime\period;
use DatePeriod as PHPDatePeriod;
// Prevent direct requests to this set_file due to security reasons
defined('CARBON_CORE_INIT') or die('Access denied!');
class DatePeriod extends PHPDatePeriod {
// TODO: Parse method!
}
<?php
namespace carbon\core\datetime\zone;
use carbon\core\datetime\DateTime;
use carbon\core\datetime\DateTimeUtils;
use carbon\core\util\StringUtils;
use DateTime as PHPDateTime;
use DateTimeZone as PHPDateTimeZone;
// Prevent direct requests to this file due to security reasons
defined('CARBON_CORE_INIT') or die('Access denied!');
class DateTimeZone extends PHPDateTimeZone {
// TODO: Make sure all DateTimeZone and PHPDateTimeZone instances are correct!
/**
* Constructor.
*
* @param string|PHPDateTimeZone|PHPDateTimeZone|null $timezone [optional] The timezone as a string, or as DateTimeZone or PHPDateTimeZone instance. Null to use the default timezone.
*
* @throws \Exception Throws an exception on failure.
*/
// TODO: Does this constructor still throw an error on failure?
public function __construct($timezone) {
// Use the default timezone if the parameter is null
if($timezone === null)
$timezone = DateTimeZoneUtils::getDefaultTimezone();
// If the timezone is already a DateTimeZone instance, copy it
if($timezone instanceof PHPDateTimeZone) {
PHPDateTimeZone::__construct($timezone->getName());
return $this;
}
// Parse PHPDateTimeZone instances
if($timezone instanceof PHPDateTimeZone) {
PHPDateTimeZone::__construct($timezone->getName());
return $this;
}
// Try to construct the parent object
PHPDateTimeZone::__construct($timezone);
return $this;
}
/**
* Parse a timezone. A new instance will be created if required.
*
* @param PHPDateTimeZone|PHPDateTimeZone|string|DateTime|PHPDateTime|null $timezone The timezone to parse as DateTimeZone or PHPDateTimeZone instance or as a string. A DateTime or PHPDateTime instance to use it's timezone. Null to parse as the default timezone.
*
* @return PHPDateTimeZone|null The parsed timezone as DateTimeZone instance, or null on failure.
*/
public static function parse($timezone = null) {
return DateTimeZoneUtils::parse($timezone, null);
}
/**
* Check whether this timezone equals another timezone.
*
* @param PHPDateTimeZone|PHPDateTimeZone|string|DateTime|PHPDateTime $timezone The other timezone as DateTimeZone or PHPDateTimeZone instance, or the timezone ID as a string. A DateTime or PHPDateTime instance may be supplied to use it's timezone.
*
* @return bool True if the timezones equal, false if not. False will also be returned if an error occurred.
*/
public function equals($timezone) {
// Parse the timezone
if(($timezone = static::parse($timezone)) === null)
return false;
// Compare the timezone IDs of both instances, return the result
return StringUtils::equals($this->getName(), $timezone->getName(), false);
}
/**
* Check whether a timezone is local relative to this timezone. This compares the offset of both timezones at a specific point in time.
*
* @param PHPDateTimeZone|PHPDateTimeZone|string|DateTime|PHPDateTime|null $timezone [optional] A DateTimeZone or PHPDateTimeZone instance, the timezone ID as a string, a DateTime or PHPDateTime instance to use it's timezone or null to use the defualt timezone.
* @param DateTime|PHPDateTime|string|null $dateTime [optional] The specific point in date and time to compare the offsets at. A DateTime or PHPDateTime instance, the date and time as a string or null to use the now() value.
*
* @return bool True if the timezone is local, false if not. False will also be returned on failure.
*/
public function isLocal($timezone = null, $dateTime = null) {
// Parse the timezone, return false on failure
if(($timezone = static::parse($timezone)) === null)
return false;
// Parse the date and time, return false on failure
if(($dateTime = DateTimeUtils::parse($dateTime, $timezone, null)) === null)
return false;
// Compare the offsets of both timezones at the specific point in time, return the result
return $this->getOffset($dateTime) == $timezone->getOffset($dateTime);
}
}
<?php
namespace carbon\core\datetime\zone;
use carbon\core\datetime\DateTime;
use DateTime as PHPDateTime;
use DateTimeZone as PHPDateTimeZone;
// Prevent direct requests to this file due to security reasons
defined('CARBON_CORE_INIT') or die('Access denied!');
class DateTimeZoneUtils {
// TODO: Make sure all DateTimeZone and PHPDateTimeZone instances are correct!
// TODO: TimeZone or Timezone? Use only one of the two, not both!
/**
* Parse a timezone. A new instance will be created if required.
*
* @param DateTimeZone|PHPDateTimeZone|string|DateTime|PHPDateTime|null $timezone The timezone to parse as DateTimeZone or PHPDateTimeZone instance or as a string. A DateTime or PHPDateTime instance to use it's timezone. Null to parse as the default timezone.
* @param mixed|null $default [optional] The default value returned on failure.
*
* @return DateTimeZone|mixed The parsed timezone as DateTimeZone instance, or the default value on failure.
*/
public static function parse($timezone = null, $default = null) {
// Return the timezone if it's already a DateTimeZone instance
if($timezone instanceof DateTimeZone)
return $timezone;
// Get the timezone form a DateTime object
else if($timezone instanceof DateTime)
$timezone = $timezone->getTimezone();
// Get the timezone from a PHPDateTimeZone object, and make sure it's valid
else if($timezone instanceof PHPDateTime)
if(($timezone = static::parse($timezone->getTimezone())) === null)
return $default;
// If the timezone is a string, make sure the timezone ID is valid, return the default value if not
// TODO: Should we check this for everything, or just for strings?
if(is_string($timezone))
if(!static::isValidTimezoneId($timezone))
return $default;
// Try to parse and return the timezone
try {
return new DateTimeZone($timezone);
} catch(\Exception $ex) {
// Return the default value on failure
return $default;
}
}
// TODO: equals(...); method (also to the base class)!
/**
* Get the default timezone for all date and time functions.
*
* @return DateTimeZone The default timezone.
*/
public static function getDefaultTimezone() {
return static::parse(date_default_timezone_get());
}
/**
* Set the default timezone for all date and time functions.
*
* @param DateTimeZone|PHPDateTimeZone|string|null $timezone The timezone as DateTimeZone instance, the timezone ID as a string or null to use the default timezone configured in PHPs configuration file.
*
* @return bool True if succeed, false on failure.
*/
public static function setDefaultTimezone($timezone) {
// Check whether the default timezone should be restored
if($timezone === null)
// TODO: Read the real-default timezone from other sources if possible
$timezone = ini_get('date.timezone');
// Parse the timezone and make sure it's valid
if(($timezone = static::parse($timezone, null)) === null)
return false;
// Set the default timezone
date_default_timezone_set($timezone->getName());
}
/**
* Check whether a timezone ID is valid. A timezone ID is specified by a string, see PHPs list of supported timezones.
*
* @param string $timezone The timezone ID to validate.
*
* @return bool True if the timezone ID is valid, false otherwise.
*/
// TODO: Can we improve the speed and readability of this method?
public static function isValidTimezoneId($timezone) {
// Create a list of valid timezones
$valid = array();
// Get the list of supported PHP timezones
$timezoneList = timezone_abbreviations_list();
// Create a list of valid timezones
foreach($timezoneList as $zone)
foreach($zone as $item)
$valid[$item['timezone_id']] = true;
// Remove the invalid keys
unset($valid['']);
// Check weather the timezone ID exists as a key in the array, return the result
return !!$valid[$timezone];
}
/**
* Check whether the timezones a and b are equal to each other.
*
* @param DateTimeZone|PHPDateTimeZone|string|null $a [optional] The timezone as DateTimeZone or PHPDateTimeZone instance, the timezone ID as a string or null to use the default timezone.
* @param DateTimeZone|PHPDateTimeZone|string|null $b [optional] The timezone as DateTimeZone or PHPDateTimeZone instance, the timezone ID as a string or null to use the default timezone.
* @param null|mixed $default [optional] The default value returned on failure.
*
* @return bool|mixed True if the timezones are equal, false if not. The default value will be returned on failure.
*/
public static function equals($a = null, $b = null, $default = null) {
// Parse the timezone of a, return the default value on failure
if(($a = static::parse($a, null)) === null)
return $default;
// Check whether the timezones are equal, return the result
return $a->equals($b);
}
/**
* Check whether the timezone a and b are local. This compares the offset of both timezones at a specific point in time.
*
* @param DateTimeZone|PHPDateTimeZone|string|DateTime|PHPDateTime|null $a [optional] A DateTimeZone or PHPDateTimeZone instance, the timezone ID as a string, a DateTime or PHPDateTime instance to use it's timezone or null to use the defualt timezone.
* @param DateTimeZone|PHPDateTimeZone|string|DateTime|PHPDateTime|null $b [optional] A DateTimeZone or PHPDateTimeZone instance, the timezone ID as a string, a DateTime or PHPDateTime instance to use it's timezone or null to use the defualt timezone.
* @param DateTime|PHPDateTime|string|null $dateTime [optional] The specific point in date and time to compare the offsets at. A DateTime or PHPDateTime instance, the date and time as a string or null to use the now() value.
* @param mixed|null $default [optional] The default value returned on failure.
*
* @return bool True if the timezone is local, false if not. The default value will be returned on failure.
*/
public function isLocal($a = null, $b = null, $dateTime = null, $default = null) {
// Parse the timezone of a, return false on failure
if(($a = static::parse($a)) === null)
return $default;
// Check whether the timezone of a and b are local, return the result or return the default value on failure
return ($result = $a->isLocal($b, $dateTime)) === null ? $default : $result;
}
/**
* Creates a DateTimeZone from a string or a PHPDateTimeZone.
*
* @param PHPDateTimeZone|string|null $timeZone
*
* @return PHPDateTimeZone
*
* @throws \InvalidArgumentException
*/
// TODO: Should we keep this method?
public static function safeCreateDateTimeZone($timeZone) {
// Return the default time zone if nothing was supplied
if($timeZone === null)
// Don't return null to avoid the PHP bug #52063 (< v5.3.6)
return static::getDefaultTimezone();
// Immediately return the object if it's already a time zone instance
if($timeZone instanceof PHPDateTimeZone)
return $timeZone;
// Try to parse the timezone, throw an exception on failure
if(($timeZone = static::parse($timeZone, null)) === null)
// Failed to create a time zone object, thrown an exception
throw new \InvalidArgumentException('Unknown or bad timezone ('.$timeZone.')');
return $timeZone;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment