---
title: "Months"
description: "Month, an immutable calendar month that is written as AAAA-MM or as the number AAAAMM"
type: "docs"
category: "doc"
tags: []
authors: [Anonymous]
date: "2026-11-05"
last_update: "2026-11-05"
time_minutes: 2
draft: false
unlisted: false
url: "https://www.derafu.dev/docs/core/date/months"
---

# Months

```php
use Derafu\Date\ValueObject\Month;
```

A `Month` is a year and a month of that year. It does not change: moving it gives another month. It is written as text (`2025-11`) and, for what keeps months as numbers, as an integer (`202511`).

## Create

| Method | What it does |
| --- | --- |
| `Month::of($year, $month)` | From a year (1 to 9999) and a number (1 to 12). |
| `Month::fromString('2025-11')` | From a text written as `AAAA-MM`. |
| `Month::fromInt(202511)` | From a number written as `AAAAMM`. |
| `Month::tryFromInt(202511)` | The same, and `null` if it is not a month. |
| `Month::fromDate($date)` | The month of a date. |
| `Month::current($clock = null)` | The current month, from a [clock](clocks). |

Anything that is not a month is an `InvalidMonthException`: month 13, a year out of 1 to 9999, a text with a day (`2025-11-01`), a number that is not six digits.

## Ask

| Method | What it gives |
| --- | --- |
| `getYear()`, `getMonth()` | The parts. |
| `getFirstDay()`, `getLastDay()` | The first and the last day, at the start of the day (`DateTimeImmutable`). |
| `getDays()` | The number of days of the month (28 to 31). |
| `contains($date)` | Whether a date is in the month. |
| `toString()`, `toInt()` | `2025-11` and `202511`. A month is also `Stringable` and serializes to JSON as its text. |
| `toPeriod()` | The [period](periods) of the month. |

## Move and compare

```php
$month = Month::of(2025, 11);

$month->next();        // 2025-12
$month->next(3);       // 2026-02
$month->previous(11);  // 2024-12
$month->monthsUntil(Month::of(2026, 3));   // 4

$month->isBefore($other);
$month->isAfter($other);
$month->equals($other);
$month->compareTo($other);   // negative, zero or positive
```

`next()` and `previous()` take any number of steps (a negative number goes the other way). A result out of the years 1 to 9999 is an `InvalidMonthException`.



---
Last updated on 05/11/2026

