Oihana PHP

date

Table of Contents

Classes

DateFormat
Defines the canonical date/time format patterns of the library.
DurationUnit
Defines the canonical single-letter suffixes of a duration unit.

Functions

addDays()  : DateTimeImmutable
Returns a copy of a date shifted by a number of days.
addHours()  : DateTimeImmutable
Returns a copy of a date shifted by a number of hours.
addMinutes()  : DateTimeImmutable
Returns a copy of a date shifted by a number of minutes.
addMonths()  : DateTimeImmutable
Returns a copy of a date shifted by a number of months, clamping day overflow.
addSeconds()  : DateTimeImmutable
Returns a copy of a date shifted by a number of seconds.
addWeeks()  : DateTimeImmutable
Returns a copy of a date shifted by a number of weeks.
addYears()  : DateTimeImmutable
Returns a copy of a date shifted by a number of years, clamping day overflow.
diffInDays()  : int
Returns the signed number of calendar days between two instants.
diffInHours()  : int
Returns the signed number of complete elapsed hours between two instants.
durationToSeconds()  : float
Normalizes a duration expressed in any supported form into a number of seconds.
endOfDay()  : DateTimeImmutable
Returns the last representable instant of the day containing a date.
endOfMonth()  : DateTimeImmutable
Returns the last representable instant of the month containing a date.
endOfWeek()  : DateTimeImmutable
Returns the last representable instant of the week containing a date.
endOfYear()  : DateTimeImmutable
Returns the last representable instant of the year containing a date.
formatDateTime()  : string
Formats a given date/time string into a specified format and timezone.
hasLiteralZulu()  : bool
Tells whether a date format pattern carries a **literal** `Z`, the ISO-8601 designator for UTC.
humanizeDuration()  : string
Returns a human-readable representation of a duration, e.g. `"1d 2h 3m 4s"`.
isDate()  : bool
Indicates if the passed-in expression is a valid date with a specific format (default 'Y-m-d').
isFuture()  : bool
Tells whether a date is strictly in the future.
isLeapYear()  : bool
Tells whether a year is a leap year, in the proleptic Gregorian calendar.
isPast()  : bool
Tells whether a date is strictly in the past.
isSameDay()  : bool
Tells whether two instants fall on the same calendar day.
isToday()  : bool
Tells whether a date falls on the current calendar day.
isValidTimezone()  : bool
Indicates if the passed-in expression is a valid timezone.
isWeekend()  : bool
Tells whether a date falls on a weekend (Saturday or Sunday).
now()  : string
Returns the current date/time as a formatted string.
startOfDay()  : DateTimeImmutable
Returns the first representable instant of the day containing a date.
startOfMonth()  : DateTimeImmutable
Returns the first representable instant of the month containing a date.
startOfWeek()  : DateTimeImmutable
Returns the first representable instant of the week containing a date.
startOfYear()  : DateTimeImmutable
Returns the first representable instant of the year containing a date.
subHours()  : DateTimeImmutable
Returns a copy of a date shifted backwards by a number of hours.
subMinutes()  : DateTimeImmutable
Returns a copy of a date shifted backwards by a number of minutes.
subMonths()  : DateTimeImmutable
Returns a copy of a date shifted backwards by a number of months, clamping day overflow.
subSeconds()  : DateTimeImmutable
Returns a copy of a date shifted backwards by a number of seconds.
subWeeks()  : DateTimeImmutable
Returns a copy of a date shifted backwards by a number of weeks.
subYears()  : DateTimeImmutable
Returns a copy of a date shifted backwards by a number of years, clamping day overflow.
tomorrow()  : DateTimeImmutable
Returns the start of the day following a reference date.
yesterday()  : DateTimeImmutable
Returns the start of the day preceding a reference date.

Functions

addDays()

Returns a copy of a date shifted by a number of days.

addDays(DateTimeInterface $date, int $days) : DateTimeImmutable

A new DateTimeImmutable is returned ; the source date is never modified. A negative $days shifts the date backwards.

Parameters
$date : DateTimeInterface

The source date.

$days : int

The number of days to add (negative to subtract).

Tags
throws
DateMalformedStringException

Never thrown in practice (the modifier is always well-formed).

example
use function oihana\core\date\addDays;

addDays( new DateTimeImmutable( '2026-01-01' ) , 5 )  ; // 2026-01-06
addDays( new DateTimeImmutable( '2026-01-01' ) , -1 ) ; // 2025-12-31
author

Marc Alcaraz (ekameleon)

since
1.0.9
Return values
DateTimeImmutable

A new immutable date shifted by $days days.

addHours()

Returns a copy of a date shifted by a number of hours.

addHours(DateTimeInterface $date, int $hours) : DateTimeImmutable

A new DateTimeImmutable is returned ; the source date is never modified. This is absolute-duration (elapsed-time) arithmetic : across a DST transition, addHours() shifts by exactly that many real hours, which can land on a different wall-clock time than a calendar shift of the same nominal span. For example, from 2026-03-29 01:30:00 Europe/Paris (just before the spring-forward gap), addHours( $d , 1 ) lands on 03:30:00 +02:00 — a two-hour wall-clock jump for one real hour elapsed — where addDays( $d , 1 ) keeps the same wall-clock time on the next day. A negative $hours shifts the date backwards.

Parameters
$date : DateTimeInterface

The source date.

$hours : int

The number of hours to add (negative to subtract).

Tags
throws
DateMalformedStringException

Never thrown in practice (the modifier is always well-formed).

example
use function oihana\core\date\addHours;

addHours( new DateTimeImmutable( '2026-01-01 00:00:00' ) , 5 )  ; // 2026-01-01 05:00:00
addHours( new DateTimeImmutable( '2026-01-01 00:00:00' ) , -1 ) ; // 2025-12-31 23:00:00
author

Marc Alcaraz (ekameleon)

since
1.2.0
Return values
DateTimeImmutable

A new immutable date shifted by $hours hours.

addMinutes()

Returns a copy of a date shifted by a number of minutes.

addMinutes(DateTimeInterface $date, int $minutes) : DateTimeImmutable

A new DateTimeImmutable is returned ; the source date is never modified. This is absolute-duration (elapsed-time) arithmetic : across a DST transition, addMinutes() shifts by exactly that many real minutes, which can land on a different wall-clock time than a calendar shift of the same nominal span (see addDays()). A negative $minutes shifts the date backwards.

Parameters
$date : DateTimeInterface

The source date.

$minutes : int

The number of minutes to add (negative to subtract).

Tags
throws
DateMalformedStringException

Never thrown in practice (the modifier is always well-formed).

example
use function oihana\core\date\addMinutes;

addMinutes( new DateTimeImmutable( '2026-01-01 00:00:00' ) , 90 ) ; // 2026-01-01 01:30:00
addMinutes( new DateTimeImmutable( '2026-01-01 00:00:00' ) , -1 ) ; // 2025-12-31 23:59:00
author

Marc Alcaraz (ekameleon)

since
1.2.0
Return values
DateTimeImmutable

A new immutable date shifted by $minutes minutes.

addMonths()

Returns a copy of a date shifted by a number of months, clamping day overflow.

addMonths(DateTimeInterface $date, int $months) : DateTimeImmutable

A new DateTimeImmutable is returned ; the source date is never modified. The wall-clock time of day is preserved.

Unlike DateTimeImmutable::modify( '+1 month' ), which overflows into the following month when the source day does not exist in the target month (2026-01-31 + 1 month natively lands on 2026-03-03, February having only 28 days), this function clamps the day to the last day of the target month (2026-02-28). This is the behaviour of every mainstream date library ; the raw, overflowing behaviour stays one ->modify( '+1 month' ) call away when it is genuinely what is wanted.

Parameters
$date : DateTimeInterface

The source date.

$months : int

The number of months to add (negative to subtract).

Tags
example
use function oihana\core\date\addMonths;

addMonths( new DateTimeImmutable( '2026-01-15' ) , 1 )  ; // 2026-02-15
addMonths( new DateTimeImmutable( '2026-01-31' ) , 1 )  ; // 2026-02-28 (clamped, not 2026-03-03)
addMonths( new DateTimeImmutable( '2024-01-31' ) , 1 )  ; // 2024-02-29 (leap year)
addMonths( new DateTimeImmutable( '2026-03-31' ) , -1 ) ; // 2026-02-28 (clamped)
author

Marc Alcaraz (ekameleon)

since
1.2.0
Return values
DateTimeImmutable

A new immutable date shifted by $months months, day-clamped.

addSeconds()

Returns a copy of a date shifted by a number of seconds.

addSeconds(DateTimeInterface $date, int $seconds) : DateTimeImmutable

A new DateTimeImmutable is returned ; the source date is never modified. This is absolute-duration (elapsed-time) arithmetic : across a DST transition, addSeconds() shifts by exactly that many real seconds, which can land on a different wall-clock time than a calendar shift of the same nominal span (see addDays()). A negative $seconds shifts the date backwards.

Parameters
$date : DateTimeInterface

The source date.

$seconds : int

The number of seconds to add (negative to subtract).

Tags
throws
DateMalformedStringException

Never thrown in practice (the modifier is always well-formed).

example
use function oihana\core\date\addSeconds;

addSeconds( new DateTimeImmutable( '2026-01-01 00:00:00' ) , 90 ) ; // 2026-01-01 00:01:30
addSeconds( new DateTimeImmutable( '2026-01-01 00:00:00' ) , -1 ) ; // 2025-12-31 23:59:59
author

Marc Alcaraz (ekameleon)

since
1.2.0
Return values
DateTimeImmutable

A new immutable date shifted by $seconds seconds.

addWeeks()

Returns a copy of a date shifted by a number of weeks.

addWeeks(DateTimeInterface $date, int $weeks) : DateTimeImmutable

A new DateTimeImmutable is returned ; the source date is never modified. This is calendar arithmetic, equivalent to addDays( $date , $weeks * 7 ) : the wall-clock time of day is preserved, so across a DST transition the shift can differ from the same span expressed in hours (see addHours()). A negative $weeks shifts the date backwards.

Parameters
$date : DateTimeInterface

The source date.

$weeks : int

The number of weeks to add (negative to subtract).

Tags
throws
DateMalformedStringException

Never thrown in practice (the modifier is always well-formed).

example
use function oihana\core\date\addWeeks;

addWeeks( new DateTimeImmutable( '2026-01-01' ) , 2 )  ; // 2026-01-15
addWeeks( new DateTimeImmutable( '2026-01-01' ) , -1 ) ; // 2025-12-25
author

Marc Alcaraz (ekameleon)

since
1.2.0
Return values
DateTimeImmutable

A new immutable date shifted by $weeks weeks.

addYears()

Returns a copy of a date shifted by a number of years, clamping day overflow.

addYears(DateTimeInterface $date, int $years) : DateTimeImmutable

A new DateTimeImmutable is returned ; the source date is never modified. Delegates to addMonths( $date , $years * 12 ), so a leap day clamps the same way : 2028-02-29

  • 1 year lands on 2029-02-28, 2029 not being a leap year, rather than overflowing to 2029-03-01.
Parameters
$date : DateTimeInterface

The source date.

$years : int

The number of years to add (negative to subtract).

Tags
example
use function oihana\core\date\addYears;

addYears( new DateTimeImmutable( '2026-01-15' ) , 1 )  ; // 2027-01-15
addYears( new DateTimeImmutable( '2028-02-29' ) , 1 )  ; // 2029-02-28 (clamped, 2029 is not a leap year)
addYears( new DateTimeImmutable( '2026-01-15' ) , -1 ) ; // 2025-01-15
author

Marc Alcaraz (ekameleon)

since
1.2.0
Return values
DateTimeImmutable

A new immutable date shifted by $years years, day-clamped.

diffInDays()

Returns the signed number of calendar days between two instants.

diffInDays(DateTimeInterface $a, DateTimeInterface $b) : int

DateTimeInterface::diff() is a trap for this : its DateInterval::$d is only the day-of-month component of a y/m/d/h/i/s breakdown, which resets every month — over a 34-day gap it reads 3, not 34. This function reads the interval's $days instead (the true total, calendar-aware — a day that has 23 or 25 hours across a DST transition still counts as one day) and applies $invert as the sign, so the result is positive when $b is later than $a, negative when it is earlier.

Parameters
$a : DateTimeInterface

The starting instant.

$b : DateTimeInterface

The ending instant.

Tags
example
use function oihana\core\date\diffInDays;

diffInDays( new DateTimeImmutable( '2026-01-01' ) , new DateTimeImmutable( '2026-02-04' ) ) ; // 34
diffInDays( new DateTimeImmutable( '2026-02-04' ) , new DateTimeImmutable( '2026-01-01' ) ) ; // -34
diffInDays( new DateTimeImmutable( '2026-01-01' ) , new DateTimeImmutable( '2026-01-01' ) ) ; // 0
author

Marc Alcaraz (ekameleon)

since
1.2.0
Return values
int

The number of calendar days from $a to $b ; negative if $b is before $a.

diffInHours()

Returns the signed number of complete elapsed hours between two instants.

diffInHours(DateTimeInterface $a, DateTimeInterface $b) : int

Absolute-duration (elapsed-time) arithmetic, computed straight from the Unix timestamps — unlike diffInDays(), which is calendar-aware, this counts real hours. Across a DST transition the two can disagree on what looks like the same nominal span : from 2026-03-28 00:00 to 2026-03-30 00:00 Europe/Paris is 2 calendar days (diffInDays()) but only 47 real hours (diffInHours()), the spring-forward gap on 2026-03-29 having shortened that day by one hour. The result is positive when $b is later than $a, negative when it is earlier, truncated toward zero.

Parameters
$a : DateTimeInterface

The starting instant.

$b : DateTimeInterface

The ending instant.

Tags
example
use function oihana\core\date\diffInHours;

diffInHours( new DateTimeImmutable( '2026-01-01 10:00:00' ) , new DateTimeImmutable( '2026-01-01 15:30:00' ) ) ; // 5
diffInHours( new DateTimeImmutable( '2026-01-01 15:30:00' ) , new DateTimeImmutable( '2026-01-01 10:00:00' ) ) ; // -5
author

Marc Alcaraz (ekameleon)

since
1.2.0
Return values
int

The number of complete hours from $a to $b ; negative if $b is before $a.

durationToSeconds()

Normalizes a duration expressed in any supported form into a number of seconds.

durationToSeconds([int|float|string|null $duration = null ][, int $hoursPerDay = 24 ]) : float

The $duration may be:

  • an int|float number of seconds (e.g. 3725), returned as-is (cast to float),
  • a colon string "MM:SS" or "HH:MM:SS",
  • a unit string "1.5d 3h 15m 12.5s" (any subset, any order, decimals allowed),
  • or null (treated as a zero duration → 0.0).

A day is worth $hoursPerDay hours, so the d unit of a unit string is converted accordingly (a colon string never carries a day component).

Parameters
$duration : int|float|string|null = null

The duration to convert.

$hoursPerDay : int = 24

Hours in a day for the d unit (default 24).

Tags
example
use function oihana\core\date\durationToSeconds ;

durationToSeconds( 3725 ) ;        // 3725.0
durationToSeconds( '90:00' ) ;     // 5400.0
durationToSeconds( '1h 30m' ) ;    // 5400.0
durationToSeconds( '1.5d' , 8 ) ;  // 43200.0  (1.5 × 8h)
durationToSeconds( null ) ;        // 0.0
author

Marc Alcaraz (ekameleon)

since
1.1.0
Return values
float

The total number of seconds (0.0 for an empty duration).

endOfDay()

Returns the last representable instant of the day containing a date.

endOfDay(DateTimeInterface $date) : DateTimeImmutable

A new DateTimeImmutable is returned, its date unchanged and its time set to 23:59:59.999999 (microseconds included) ; the source date is never modified. The timezone of the returned value is the one carried by $date.

Parameters
$date : DateTimeInterface

The source date.

Tags
example
use function oihana\core\date\endOfDay;

endOfDay( new DateTimeImmutable( '2026-03-15 14:30:45' ) ) ; // 2026-03-15 23:59:59.999999
author

Marc Alcaraz (ekameleon)

since
1.2.0
Return values
DateTimeImmutable

A new immutable date, at the end of the same day.

endOfMonth()

Returns the last representable instant of the month containing a date.

endOfMonth(DateTimeInterface $date) : DateTimeImmutable

A new DateTimeImmutable is returned, set to the last day of the month at 23:59:59.999999 (microseconds included) ; the source date is never modified. The timezone of the returned value is the one carried by $date. The last day of the month is computed with daysInGregorianMonth(), so leap years are handled correctly.

Parameters
$date : DateTimeInterface

The source date.

Tags
example
use function oihana\core\date\endOfMonth;

endOfMonth( new DateTimeImmutable( '2026-02-05' ) ) ; // 2026-02-28 23:59:59.999999
endOfMonth( new DateTimeImmutable( '2024-02-05' ) ) ; // 2024-02-29 23:59:59.999999 (leap year)
author

Marc Alcaraz (ekameleon)

since
1.2.0
Return values
DateTimeImmutable

A new immutable date, at the end of the same month.

endOfWeek()

Returns the last representable instant of the week containing a date.

endOfWeek(DateTimeInterface $date[, int $firstDayOfWeek = 1 ]) : DateTimeImmutable

A new DateTimeImmutable is returned, set to 23:59:59.999999 (microseconds included) on the last day of the week ; the source date is never modified. The timezone of the returned value is the one carried by $date.

$firstDayOfWeek follows the same ISO-8601 numbering as startOfWeek() — see there for details. The last day of the week is $firstDayOfWeek + 6 (mod 7).

Parameters
$date : DateTimeInterface

The source date.

$firstDayOfWeek : int = 1

The first day of the week, 1 (Monday) to 7 (Sunday). Default 1.

Tags
throws
InvalidArgumentException

If $firstDayOfWeek is outside [1, 7].

DateMalformedStringException

Never thrown in practice (the modifier is always well-formed).

example
use function oihana\core\date\endOfWeek;

// 2026-03-18 is a Wednesday.
endOfWeek( new DateTimeImmutable( '2026-03-18 14:30:45' ) )    ; // 2026-03-22 23:59:59.999999 (Sunday)
endOfWeek( new DateTimeImmutable( '2026-03-18 14:30:45' ) , 7 ); // 2026-03-21 23:59:59.999999 (Saturday)
author

Marc Alcaraz (ekameleon)

since
1.2.0
Return values
DateTimeImmutable

A new immutable date, at the end of the week containing $date.

endOfYear()

Returns the last representable instant of the year containing a date.

endOfYear(DateTimeInterface $date) : DateTimeImmutable

A new DateTimeImmutable is returned, set to December 31st at 23:59:59.999999 (microseconds included) ; the source date is never modified. The timezone of the returned value is the one carried by $date.

Parameters
$date : DateTimeInterface

The source date.

Tags
example
use function oihana\core\date\endOfYear;

endOfYear( new DateTimeImmutable( '2026-03-15 14:30:45' ) ) ; // 2026-12-31 23:59:59.999999
author

Marc Alcaraz (ekameleon)

since
1.2.0
Return values
DateTimeImmutable

A new immutable date, at the end of the same year.

formatDateTime()

Formats a given date/time string into a specified format and timezone.

formatDateTime([string|null $date = null ][, string $timezone = 'UTC' ][, string|null $format = DateFormat::DEFAULT ]) : string

The $timezone parameter is used only to interpret the input date string, and only when that string does not carry an offset of its own — 2025-07-20T09:30:00+02:00 says which moment it is, so PHP's own parser ignores $timezone for it.

The moment is then rendered in the timezone it was parsed in, except when $format asks for a literal Z (an escaped \Z, as in the default format) : Z is the ISO-8601 designator for UTC, so the moment is converted to UTC first and the suffix tells the truth. A format carrying a real offset token (P, O, T) is left in its own timezone, that token already saying which one it is.

Parameters
$date : string|null = null

The input date/time string to format. If null, "now" is used.

$timezone : string = 'UTC'

The timezone identifier (e.g., 'Europe/Paris'). Defaults to 'UTC'.

$format : string|null = DateFormat::DEFAULT

The date format string compatible with DateTime::format(). If null, DateFormat::DEFAULT is used (ISO 8601 UTC with milliseconds).

Tags
throws
DateInvalidTimeZoneException

If the provided timezone string is invalid.

DateMalformedStringException

If the input date string is malformed or cannot be parsed.

example
echo formatDateTime( '2025-07-20 15:30' , 'Europe/Paris' , 'Y-m-d H:i' ) ;
// Output: '2025-07-20 15:30' — no literal Z, rendered in Paris as parsed.

echo formatDateTime( '2025-07-20T09:30:00+02:00' ) ;
// Output: '2025-07-20T07:30:00.000Z' — the default format ends on a literal Z, so UTC.

echo formatDateTime() ;
// Output: current date/time in UTC, e.g., '2025-07-20T13:30:20.676Z'
author

Marc Alcaraz (ekameleon)

since
1.0.0
Return values
string

The formatted date/time string.

hasLiteralZulu()

Tells whether a date format pattern carries a **literal** `Z`, the ISO-8601 designator for UTC.

hasLiteralZulu(string $format) : bool

A pattern ending on an escaped Z'Y-m-d\TH:i:s.v\Z', the default of formatDateTime() — asserts that the moment it renders is expressed in UTC. That is what lets formatDateTime() convert the moment before formatting it, rather than stamping a wall clock with a suffix that lies about it.

The distinction the naive str_contains( $format , '\Z' ) misses is the escaped backslash : in '\\\\Z' the backslash escapes a backslash, leaving Z as the native token for the timezone offset in seconds — not a Zulu designator. Walking the pattern and stepping over whatever follows an escape tells the two apart.

Parameters
$format : string

A format string compatible with DateTime::format().

Tags
example
use function oihana\core\date\hasLiteralZulu;

var_dump( hasLiteralZulu( 'Y-m-d\TH:i:s.v\Z' ) ) ; // true  — Zulu designator
var_dump( hasLiteralZulu( 'Y-m-d\TH:i:sP'    ) ) ; // false — a real offset token
var_dump( hasLiteralZulu( 'Y-m-d\TH:i:s'     ) ) ; // false — no timezone at all
var_dump( hasLiteralZulu( 'Z'                ) ) ; // false — the native offset token
var_dump( hasLiteralZulu( '\\\\Z'            ) ) ; // false — escaped backslash, then the token
author

Marc Alcaraz (ekameleon)

since
1.2.0
Return values
bool

True when the pattern contains an escaped Z, false otherwise.

humanizeDuration()

Returns a human-readable representation of a duration, e.g. `"1d 2h 3m 4s"`.

humanizeDuration([int|float|string|null $duration = null ][, int $hoursPerDay = 24 ]) : string

The $duration may be:

  • an int|float number of seconds (e.g. 3725),
  • a colon string "MM:SS" or "HH:MM:SS",
  • a unit string "1.5d 3h 15m 12.5s" (any subset, any order),
  • or null (treated as a zero duration → "0s").

Whatever the input form, the duration is first normalized into a number of seconds and then broken down so that every component stays within its natural range (seconds < 60, minutes < 60, hours < $hoursPerDay). Fractional input therefore rolls up correctly: "90:00" and "1.5h" both yield "1h 30m". Only the seconds component may carry a fractional part (e.g. "5.5s").

Parameters
$duration : int|float|string|null = null

The duration to format.

$hoursPerDay : int = 24

Hours in a day for day↔hour conversion (default 24).

Tags
example
use function oihana\core\date\humanizeDuration ;

echo humanizeDuration( 3725 ) ;        // "1h 2m 5s"
echo humanizeDuration( '1h 30m' ) ;    // "1h 30m"
echo humanizeDuration( '90:00' ) ;     // "1h 30m"
echo humanizeDuration( null ) ;        // "0s"
author

Marc Alcaraz (ekameleon)

since
1.1.0
Return values
string

The human-readable duration (e.g. "1h 42m"), "0s" for an empty duration.

isDate()

Indicates if the passed-in expression is a valid date with a specific format (default 'Y-m-d').

isDate(string|null $date[, string $format = 'Y-m-d' ]) : bool
Parameters
$date : string|null

The expression to evaluate.

$format : string = 'Y-m-d'

The date format (default 'Y-m-d').

Tags
example
var_dump(isDate('2025-07-20'));           // true
var_dump(isDate('20/07/2025', 'd/m/Y'));  // true
var_dump(isDate('invalid-date'));         // false
var_dump(isDate(null));                   // false
author

Marc Alcaraz (ekameleon)

since
1.0.0
Return values
bool

Indicates if the passed-in expression is a valid timezone.

isFuture()

Tells whether a date is strictly in the future.

isFuture(DateTimeInterface $date[, DateTimeInterface|null $now = null ]) : bool
Parameters
$date : DateTimeInterface

The date to test.

$now : DateTimeInterface|null = null

The reference "now". Defaults to the current date/time.

Tags
example
use function oihana\core\date\isFuture;

isFuture( new DateTimeImmutable( '2999-01-01' ) ) ; // true
isFuture( new DateTimeImmutable( '2000-01-01' ) ) ; // false
author

Marc Alcaraz (ekameleon)

since
1.0.9
Return values
bool

true if $date is strictly after $now, false otherwise.

isLeapYear()

Tells whether a year is a leap year, in the proleptic Gregorian calendar.

isLeapYear(int $year) : bool

Pure arithmetic — divisible by 4, except centuries, which must be divisible by 400 — defined for any integer year, including zero and negative ones.

Parameters
$year : int

Any integer year.

Tags
example
use function oihana\core\date\isLeapYear;

isLeapYear( 2024 ) ; // true  (divisible by 4)
isLeapYear( 2026 ) ; // false
isLeapYear( 1900 ) ; // false (divisible by 100, not 400)
isLeapYear( 2000 ) ; // true  (divisible by 400)
author

Marc Alcaraz (ekameleon)

since
1.2.0
Return values
bool

true if $year is a leap year, false otherwise.

isPast()

Tells whether a date is strictly in the past.

isPast(DateTimeInterface $date[, DateTimeInterface|null $now = null ]) : bool
Parameters
$date : DateTimeInterface

The date to test.

$now : DateTimeInterface|null = null

The reference "now". Defaults to the current date/time.

Tags
example
use function oihana\core\date\isPast;

isPast( new DateTimeImmutable( '2000-01-01' ) ) ; // true
isPast( new DateTimeImmutable( '2999-01-01' ) ) ; // false
author

Marc Alcaraz (ekameleon)

since
1.0.9
Return values
bool

true if $date is strictly before $now, false otherwise.

isSameDay()

Tells whether two instants fall on the same calendar day.

isSameDay(DateTimeInterface $a, DateTimeInterface $b[, DateTimeZone|null $timezone = null ]) : bool

The same physical instant can be a different calendar date depending on the timezone it is read in — 2026-01-01 00:30:00 UTC is still 2025-12-31 in America/Los_Angeles. Both dates are converted to $timezone before their calendar date is compared ; it defaults to the timezone carried by $a, so the common, no-argument call answers "is $b the same day as $a, as seen from $a's own timezone". Pass $timezone explicitly to compare from a third, unrelated timezone instead.

Parameters
$a : DateTimeInterface

The first instant.

$b : DateTimeInterface

The second instant.

$timezone : DateTimeZone|null = null

The timezone the comparison is made in. Defaults to $a's own timezone.

Tags
example
use function oihana\core\date\isSameDay;

$a = new DateTimeImmutable( '2026-01-01 01:00:00' , new DateTimeZone( 'UTC' ) );
$b = new DateTimeImmutable( '2026-01-01 20:00:00' , new DateTimeZone( 'UTC' ) );

isSameDay( $a , $b ) ; // true — both January 1st in UTC, $a's own timezone (the default)

// Compared from Tokyo (UTC+9) instead, $a is still Jan 1st (10:00) but $b has
// already rolled over to Jan 2nd (05:00) : same two instants, different verdict.
isSameDay( $a , $b , new DateTimeZone( 'Asia/Tokyo' ) ) ; // false
author

Marc Alcaraz (ekameleon)

since
1.2.0
Return values
bool

true if $a and $b fall on the same calendar day in $timezone, false otherwise.

isToday()

Tells whether a date falls on the current calendar day.

isToday(DateTimeInterface $date[, DateTimeInterface|null $now = null ][, DateTimeZone|null $timezone = null ]) : bool

A special case of isSameDay( $date , $now ) — see there for the timezone rule : the comparison is made in $timezone, defaulting to the timezone carried by $date.

Parameters
$date : DateTimeInterface

The date to test.

$now : DateTimeInterface|null = null

The reference "now". Defaults to the current date/time.

$timezone : DateTimeZone|null = null

The timezone the comparison is made in. Defaults to $date's own timezone.

Tags
example
use function oihana\core\date\isToday;

isToday( new DateTimeImmutable() ) ; // true
isToday( new DateTimeImmutable( '2000-01-01' ) ) ; // false
author

Marc Alcaraz (ekameleon)

since
1.2.0
Return values
bool

true if $date falls on the same calendar day as $now, false otherwise.

isValidTimezone()

Indicates if the passed-in expression is a valid timezone.

isValidTimezone([string|null $timezone = null ]) : bool

Note: timezone_identifiers_list() requires PHP >= 5.2

Parameters
$timezone : string|null = null

The timezone expression to evaluates.

Tags
example
var_dump(isValidTimezone('Europe/Paris')); // true
var_dump(isValidTimezone('Invalid/Timezone')); // false
var_dum(isValidTimezone(null)); // false
author

Marc Alcaraz (ekameleon)

since
1.0.0
Return values
bool

Indicates if the passed-in expression is a valid timezone.

isWeekend()

Tells whether a date falls on a weekend (Saturday or Sunday).

isWeekend(DateTimeInterface $date) : bool
Parameters
$date : DateTimeInterface

The date to test.

Tags
example
use function oihana\core\date\isWeekend;

isWeekend( new DateTimeImmutable( '2024-01-06' ) ) ; // true  (Saturday)
isWeekend( new DateTimeImmutable( '2024-01-08' ) ) ; // false (Monday)
author

Marc Alcaraz (ekameleon)

since
1.0.9
Return values
bool

true if the date is a Saturday or a Sunday, false otherwise.

now()

Returns the current date/time as a formatted string.

now([string $timezone = 'UTC' ][, string|null $format = DateFormat::DEFAULT ]) : string

The $timezone parameter is used only to interpret the "now" value. Since the default format ends on a literal Z, the ISO-8601 designator for UTC, the result is converted to UTC whichever timezone is asked for — see formatDateTime() for the full rule.

Parameters
$timezone : string = 'UTC'

The timezone identifier (e.g., 'Europe/Paris'). Defaults to 'UTC'.

$format : string|null = DateFormat::DEFAULT

The date format string compatible with DateTime::format(). Defaults to DateFormat::DEFAULT (ISO 8601 UTC with milliseconds).

Tags
throws
DateInvalidTimeZoneException

If the provided timezone string is invalid.

DateMalformedStringException

If the date creation fails (should not occur with 'now').

example
echo now() ;
// Output: '2025-07-20T13:30:20.676Z'

echo now( 'Europe/Paris' ) ;
// Output: '2025-07-20T13:30:20.676Z' (the same moment — the default format is UTC)

echo now( 'Europe/Paris' , 'H:i' ) ;
// Output: '15:30' (no literal Z, so the Paris wall clock)
author

Marc Alcaraz (ekameleon)

since
1.0.0
Return values
string

The formatted current date/time string.

startOfDay()

Returns the first representable instant of the day containing a date.

startOfDay(DateTimeInterface $date) : DateTimeImmutable

A new DateTimeImmutable is returned, its date unchanged and its time set to 00:00:00.000000 ; the source date is never modified. The timezone of the returned value is the one carried by $date.

Parameters
$date : DateTimeInterface

The source date.

Tags
example
use function oihana\core\date\startOfDay;

startOfDay( new DateTimeImmutable( '2026-03-15 14:30:45' ) ) ; // 2026-03-15 00:00:00.000000
author

Marc Alcaraz (ekameleon)

since
1.2.0
Return values
DateTimeImmutable

A new immutable date, at the start of the same day.

startOfMonth()

Returns the first representable instant of the month containing a date.

startOfMonth(DateTimeInterface $date) : DateTimeImmutable

A new DateTimeImmutable is returned, set to the 1st of the month at 00:00:00.000000 ; the source date is never modified. The timezone of the returned value is the one carried by $date.

Parameters
$date : DateTimeInterface

The source date.

Tags
example
use function oihana\core\date\startOfMonth;

startOfMonth( new DateTimeImmutable( '2026-03-15 14:30:45' ) ) ; // 2026-03-01 00:00:00.000000
author

Marc Alcaraz (ekameleon)

since
1.2.0
Return values
DateTimeImmutable

A new immutable date, at the start of the same month.

startOfWeek()

Returns the first representable instant of the week containing a date.

startOfWeek(DateTimeInterface $date[, int $firstDayOfWeek = 1 ]) : DateTimeImmutable

A new DateTimeImmutable is returned, set to 00:00:00.000000 on the first day of the week ; the source date is never modified. The timezone of the returned value is the one carried by $date.

$firstDayOfWeek uses the ISO-8601 numbering also returned by DateTime::format( 'N' ) : 1 for Monday through 7 for Sunday. It defaults to 1 (ISO-8601 / most of the world) ; pass 7 for the US/Canada convention (week starts on Sunday).

Parameters
$date : DateTimeInterface

The source date.

$firstDayOfWeek : int = 1

The first day of the week, 1 (Monday) to 7 (Sunday). Default 1.

Tags
throws
InvalidArgumentException

If $firstDayOfWeek is outside [1, 7].

DateMalformedStringException

Never thrown in practice (the modifier is always well-formed).

example
use function oihana\core\date\startOfWeek;

// 2026-03-18 is a Wednesday.
startOfWeek( new DateTimeImmutable( '2026-03-18 14:30:45' ) )    ; // 2026-03-16 00:00:00.000000 (Monday)
startOfWeek( new DateTimeImmutable( '2026-03-18 14:30:45' ) , 7 ); // 2026-03-15 00:00:00.000000 (Sunday)
author

Marc Alcaraz (ekameleon)

since
1.2.0
Return values
DateTimeImmutable

A new immutable date, at the start of the week containing $date.

startOfYear()

Returns the first representable instant of the year containing a date.

startOfYear(DateTimeInterface $date) : DateTimeImmutable

A new DateTimeImmutable is returned, set to January 1st at 00:00:00.000000 ; the source date is never modified. The timezone of the returned value is the one carried by $date.

Parameters
$date : DateTimeInterface

The source date.

Tags
example
use function oihana\core\date\startOfYear;

startOfYear( new DateTimeImmutable( '2026-03-15 14:30:45' ) ) ; // 2026-01-01 00:00:00.000000
author

Marc Alcaraz (ekameleon)

since
1.2.0
Return values
DateTimeImmutable

A new immutable date, at the start of the same year.

subHours()

Returns a copy of a date shifted backwards by a number of hours.

subHours(DateTimeInterface $date, int $hours) : DateTimeImmutable

A new DateTimeImmutable is returned ; the source date is never modified. Equivalent to addHours( $date , -$hours ) — see addHours() for the elapsed-time semantics across a DST transition.

Parameters
$date : DateTimeInterface

The source date.

$hours : int

The number of hours to subtract.

Tags
throws
DateMalformedStringException

Never thrown in practice (the modifier is always well-formed).

example
use function oihana\core\date\subHours;

subHours( new DateTimeImmutable( '2026-01-01 05:00:00' ) , 5 ) ; // 2026-01-01 00:00:00
author

Marc Alcaraz (ekameleon)

since
1.2.0
Return values
DateTimeImmutable

A new immutable date shifted backwards by $hours hours.

subMinutes()

Returns a copy of a date shifted backwards by a number of minutes.

subMinutes(DateTimeInterface $date, int $minutes) : DateTimeImmutable

A new DateTimeImmutable is returned ; the source date is never modified. Equivalent to addMinutes( $date , -$minutes ) — see addMinutes() for the elapsed-time semantics across a DST transition.

Parameters
$date : DateTimeInterface

The source date.

$minutes : int

The number of minutes to subtract.

Tags
throws
DateMalformedStringException

Never thrown in practice (the modifier is always well-formed).

example
use function oihana\core\date\subMinutes;

subMinutes( new DateTimeImmutable( '2026-01-01 01:30:00' ) , 90 ) ; // 2026-01-01 00:00:00
author

Marc Alcaraz (ekameleon)

since
1.2.0
Return values
DateTimeImmutable

A new immutable date shifted backwards by $minutes minutes.

subMonths()

Returns a copy of a date shifted backwards by a number of months, clamping day overflow.

subMonths(DateTimeInterface $date, int $months) : DateTimeImmutable

A new DateTimeImmutable is returned ; the source date is never modified. Equivalent to addMonths( $date , -$months ) — see addMonths() for the day-clamping semantics.

Parameters
$date : DateTimeInterface

The source date.

$months : int

The number of months to subtract.

Tags
example
use function oihana\core\date\subMonths;

subMonths( new DateTimeImmutable( '2026-03-15' ) , 1 ) ; // 2026-02-15
subMonths( new DateTimeImmutable( '2026-03-31' ) , 1 ) ; // 2026-02-28 (clamped)
author

Marc Alcaraz (ekameleon)

since
1.2.0
Return values
DateTimeImmutable

A new immutable date shifted backwards by $months months, day-clamped.

subSeconds()

Returns a copy of a date shifted backwards by a number of seconds.

subSeconds(DateTimeInterface $date, int $seconds) : DateTimeImmutable

A new DateTimeImmutable is returned ; the source date is never modified. Equivalent to addSeconds( $date , -$seconds ) — see addSeconds() for the elapsed-time semantics across a DST transition.

Parameters
$date : DateTimeInterface

The source date.

$seconds : int

The number of seconds to subtract.

Tags
throws
DateMalformedStringException

Never thrown in practice (the modifier is always well-formed).

example
use function oihana\core\date\subSeconds;

subSeconds( new DateTimeImmutable( '2026-01-01 00:01:30' ) , 90 ) ; // 2026-01-01 00:00:00
author

Marc Alcaraz (ekameleon)

since
1.2.0
Return values
DateTimeImmutable

A new immutable date shifted backwards by $seconds seconds.

subWeeks()

Returns a copy of a date shifted backwards by a number of weeks.

subWeeks(DateTimeInterface $date, int $weeks) : DateTimeImmutable

A new DateTimeImmutable is returned ; the source date is never modified. Equivalent to addWeeks( $date , -$weeks ) — see addWeeks() for the calendar-arithmetic semantics.

Parameters
$date : DateTimeInterface

The source date.

$weeks : int

The number of weeks to subtract.

Tags
throws
DateMalformedStringException

Never thrown in practice (the modifier is always well-formed).

example
use function oihana\core\date\subWeeks;

subWeeks( new DateTimeImmutable( '2026-01-15' ) , 2 ) ; // 2026-01-01
author

Marc Alcaraz (ekameleon)

since
1.2.0
Return values
DateTimeImmutable

A new immutable date shifted backwards by $weeks weeks.

subYears()

Returns a copy of a date shifted backwards by a number of years, clamping day overflow.

subYears(DateTimeInterface $date, int $years) : DateTimeImmutable

A new DateTimeImmutable is returned ; the source date is never modified. Equivalent to addYears( $date , -$years ) — see addYears() for the day-clamping semantics.

Parameters
$date : DateTimeInterface

The source date.

$years : int

The number of years to subtract.

Tags
example
use function oihana\core\date\subYears;

subYears( new DateTimeImmutable( '2026-01-15' ) , 1 ) ; // 2025-01-15
subYears( new DateTimeImmutable( '2028-02-29' ) , 1 ) ; // 2027-02-28 (clamped, 2027 is not a leap year)
author

Marc Alcaraz (ekameleon)

since
1.2.0
Return values
DateTimeImmutable

A new immutable date shifted backwards by $years years, day-clamped.

tomorrow()

Returns the start of the day following a reference date.

tomorrow([DateTimeInterface|null $now = null ]) : DateTimeImmutable

startOfDay( addDays( $now , 1 ) ) — always 00:00:00.000000 on the next calendar day, regardless of the time of day $now carries. The timezone of the returned value is the one carried by $now.

Parameters
$now : DateTimeInterface|null = null

The reference date. Defaults to the current date/time.

Tags
throws
DateMalformedStringException

Never thrown in practice (the modifier is always well-formed).

example
use function oihana\core\date\tomorrow;

tomorrow( new DateTimeImmutable( '2026-03-15 14:30:45' ) ) ; // 2026-03-16 00:00:00.000000
author

Marc Alcaraz (ekameleon)

since
1.2.0
Return values
DateTimeImmutable

The start of the day after $now.

yesterday()

Returns the start of the day preceding a reference date.

yesterday([DateTimeInterface|null $now = null ]) : DateTimeImmutable

startOfDay( addDays( $now , -1 ) ) — always 00:00:00.000000 on the previous calendar day, regardless of the time of day $now carries. The timezone of the returned value is the one carried by $now.

Parameters
$now : DateTimeInterface|null = null

The reference date. Defaults to the current date/time.

Tags
throws
DateMalformedStringException

Never thrown in practice (the modifier is always well-formed).

example
use function oihana\core\date\yesterday;

yesterday( new DateTimeImmutable( '2026-03-15 14:30:45' ) ) ; // 2026-03-14 00:00:00.000000
author

Marc Alcaraz (ekameleon)

since
1.2.0
Return values
DateTimeImmutable

The start of the day before $now.

On this page

Search results