Skip to content

Add LastDayOfMonth database function #38

Open
@nobilebeniamino

Description

@nobilebeniamino

Code of Conduct

  • I agree to follow Django's Code of Conduct

Feature Description

Add a built-in LastDayOfMonth database function that returns the last calendar day of the month for a given DateField or DateTimeField expression.

Problem

Today developers must hand-roll backend-specific Func subclasses (or wrap raw SQL) to calculate “last day of month”. That works but it’s verbose, copied across code-bases and easy to get subtly wrong (leap years, Oracle quirks, new DB versions). A small built-in helper removes that friction and raises the quality bar.

Why a core helper is better than ad-hoc Func / FuncWrapper:

  • One-liner, zero boiler-plateLastDayOfMonth("start").
  • Cross-backend guarantee – ORM ships the right SQL for PostgreSQL, MySQL/MariaDB, SQLite and Oracle, covered by the test-suite.
  • Official docs & IDE discoverability – lives next to TruncMonth, ExtractDay, etc.
  • Clearer code reviews – intent obvious without opening a helper file; no naming drift (MonthEnd, EndOfMonth, …).
  • Safer upgrades – Django can warn if backend syntax changes, while custom SQL might silently break.
  • Negligible maintenance cost – MySQL/MariaDB and Oracle expose native LAST_DAY(), and the Postgres/SQLite expression is a single date-math line.

Request or proposal

proposal

Additional Details

Use-cases

  • Payroll or invoice cut-off dates
  • Month-end KPI / reporting roll-ups
  • Any query that needs “<= last day of the month”

Proposed API

from django.db.models.functions import LastDayOfMonth
qs.annotate(period_end=LastDayOfMonth("issued_at"))

Backend SQL mapping (illustrative)

Backend SQL emitted
PostgreSQL date_trunc('month', exp + interval '1 month') - interval '1 day'
MySQL/MariaDB LAST_DAY(exp)
SQLite date(exp, '+1 month', 'start of month', '-1 day')
Oracle LAST_DAY(exp) (pure-date via TRUNC/NUMTODSINTERVAL)

Implementation Suggestions

  • class LastDayOfMonth(Func) in django/db/models/functions/datetime.py
    • arity = 1
    • output_field = models.DateField()
    • backend methods: as_postgresql(), as_mysql(), as_sqlite(), as_oracle()
  • Tests: tests/db_functions/datetime/test_last_day_of_month.py using a simple model with a DateField.
  • Docs: add to “Database Functions” reference and to the upcoming 5.2 release notes under “Minor features”.
  • I’m happy to open the PR and iterate on review feedback.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Models/ORMThird Party PackageThis idea is suitable for the third party package ecosystem

    Type

    No type

    Projects

    Status

    Idea

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions