{"id":20741129,"url":"https://github.com/robtimus/date-time-validation","last_synced_at":"2025-09-27T18:31:15.221Z","repository":{"id":57722442,"uuid":"430106140","full_name":"robtimus/date-time-validation","owner":"robtimus","description":"Contains validation constraints for date/time objects","archived":false,"fork":false,"pushed_at":"2024-10-14T13:00:31.000Z","size":1937,"stargazers_count":0,"open_issues_count":0,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-11-17T06:41:51.665Z","etag":null,"topics":["date-time","java","jsr-310","validation"],"latest_commit_sha":null,"homepage":"https://robtimus.github.io/date-time-validation/","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/robtimus.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-11-20T13:09:29.000Z","updated_at":"2024-10-14T12:58:47.000Z","dependencies_parsed_at":"2023-02-15T18:16:14.515Z","dependency_job_id":"5d93770f-7c26-48f3-af55-000cc35fbe1b","html_url":"https://github.com/robtimus/date-time-validation","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robtimus%2Fdate-time-validation","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robtimus%2Fdate-time-validation/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robtimus%2Fdate-time-validation/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robtimus%2Fdate-time-validation/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/robtimus","download_url":"https://codeload.github.com/robtimus/date-time-validation/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":234452031,"owners_count":18834739,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["date-time","java","jsr-310","validation"],"created_at":"2024-11-17T06:34:01.426Z","updated_at":"2025-09-27T18:31:15.215Z","avatar_url":"https://github.com/robtimus.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# date-time-validation\n[![Maven Central](https://img.shields.io/maven-central/v/com.github.robtimus/date-time-validation-parent)](https://search.maven.org/artifact/com.github.robtimus/date-time-validation-parent)\n[![Build Status](https://github.com/robtimus/date-time-validation/actions/workflows/build.yml/badge.svg)](https://github.com/robtimus/date-time-validation/actions/workflows/build.yml)\n[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=com.github.robtimus%3Adate-time-validation-parent\u0026metric=alert_status)](https://sonarcloud.io/summary/overall?id=com.github.robtimus%3Adate-time-validation-parent)\n[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=com.github.robtimus%3Adate-time-validation-parent\u0026metric=coverage)](https://sonarcloud.io/summary/overall?id=com.github.robtimus%3Adate-time-validation-parent)\n\nValidation constraints for date/time objects.\n\n## Modules\n\nBecause this repository contains a lot of constraints, and each applies to several date/time object types, it is split into several modules. This allows you to only use those modules you need without getting a single, large dependency.\n\nThe following sections each describe a module. Most of these modules validate only a part of the value. Because the exact date and time depends on the time zone, each annotation in these modules has an optional `zoneId` parameter. This can have the following values:\n\n* `system` (default): the system time zone, as returned by `ZoneId.systemDefault()`, should be used.\n* `provided`: the time zone or offset information from the actual value should be used.\n* A value that is valid according to `ZoneId.of` for an explicit time zone.\n\n### date-time-validation\n[![Maven Central](https://img.shields.io/maven-central/v/com.github.robtimus/date-time-validation)](https://search.maven.org/artifact/com.github.robtimus/date-time-validation)\n[![Known Vulnerabilities](https://snyk.io/test/github/robtimus/date-time-validation/badge.svg?targetFile=date-time-validation/pom.xml)](https://snyk.io/test/github/robtimus/date-time-validation?targetFile=date-time-validation/pom.xml)\n\nValidation constraints for date/time objects that validate entire values. These validate the following, where `object` is the object to be validated, `moment` is the value specified in the constraint, and `duration` is a [ISO 8601 duration](https://en.wikipedia.org/wiki/ISO_8601):\n\n| Constraint | Meaning                     |\n|------------|-----------------------------|\n| After      | object \u003e moment             |\n| NotAfter   | object \u003c= moment            |\n| MinAfter   | object \u003e= moment + duration |\n| MaxAfter   | object \u003c= moment + duration |\n| Before     | object \u003c moment             |\n| NotBefore  | object \u003e= moment            |\n| MinBefore  | object \u003c= moment - duration |\n| MaxBefore  | object \u003e= moment - duration |\n\nThe format of `moment` and `duration` depends on the type to validate:\n\n* For classes from the `java.time` package, `moment` must be valid according to the class' `parse` method.\n* For `Date`, `moment` must be valid according to `Instant.parse`.\n* For `Calendar`, `moment` must be valid according to `ZonedDateTime.parse`.\n* `duration` may not contain parts that are not present in the type. For instance, for `LocalDate` `duration` may not contain any time elements, for `LocalTime` it may not contain any date elements, for `YearMonth` it may only contain year and/or month elements, etc.\n\nIn addition, for all annotations the `moment` can be defined as literal value `now` to indicate the current date/time must be used.\n\nThese annotations apply to the following types:\n\n| Type                | After | NotAfter | MinAfter | MaxAfter | Before | NotBefore | MinBefore | MaxBefore |\n|---------------------|:-----:|:--------:|:--------:|:--------:|:------:|:---------:|:---------:|:---------:|\n| Date                |✅     |✅        |✅        |✅        |✅      |✅         |✅         |✅         |\n| Calendar            |✅     |✅        |✅        |✅        |✅      |✅         |✅         |✅         |\n| DayOfWeek           |❌     |❌        |❌        |❌        |❌      |❌         |❌         |❌         |\n| Instant             |✅     |✅        |✅        |✅        |✅      |✅         |✅         |✅         |\n| LocalDate           |✅     |✅        |✅        |✅        |✅      |✅         |✅         |✅         |\n| LocalDateTime       |✅     |✅        |✅        |✅        |✅      |✅         |✅         |✅         |\n| LocalTime           |✅     |✅        |✅        |✅        |✅      |✅         |✅         |✅         |\n| Month               |❌     |❌        |❌        |❌        |❌      |❌         |❌         |❌         |\n| MonthDay\u003csup\u003e1\u003c/sup\u003e|✅     |✅        |❌        |❌        |✅      |✅         |❌         |❌         |\n| OffsetDateTime      |✅     |✅        |✅        |✅        |✅      |✅         |✅         |✅         |\n| OffsetTime          |✅     |✅        |✅        |✅        |✅      |✅         |✅         |✅         |\n| Year                |✅     |✅        |✅        |✅        |✅      |✅         |✅         |✅         |\n| YearMonth           |✅     |✅        |✅        |✅        |✅      |✅         |✅         |✅         |\n| ZonedDateTime       |✅     |✅        |✅        |✅        |✅      |✅         |✅         |✅         |\n\n\u003csup\u003e1\u003c/sup\u003e: `MinAfter`, `MaxAfter`, `MinBefore` and `MaxBefore` cannot be applied to [MonthDay](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/MonthDay.html) because \"it is not possible to define whether February 29th is valid or not without external information\". This makes it impossible to apply durations to `MonthDay` moments.\n\n### date-validation\n[![Maven Central](https://img.shields.io/maven-central/v/com.github.robtimus/date-validation)](https://search.maven.org/artifact/com.github.robtimus/date-validation)\n[![Known Vulnerabilities](https://snyk.io/test/github/robtimus/date-time-validation/badge.svg?targetFile=date-validation/pom.xml)](https://snyk.io/test/github/robtimus/date-time-validation?targetFile=date-validation/pom.xml)\n\nValidation constraints for date/time objects that validate only the date part. These work just like the constraints of the `date-time-validation` module, except they ignore any time part. The `moment` must be `now` or valid according to `LocalDate.parse`, and the `duration` may not contain any time elements.\n\nThese annotations apply to the following types:\n\n| Type                     | DateAfter | DateNotAfter | DateMinAfter | DateMaxAfter | DateBefore | DateNotBefore | DateMinBefore | DateMaxBefore |\n|--------------------------|:---------:|:------------:|:------------:|:------------:|:----------:|:-------------:|:-------------:|:-------------:|\n| Date\u003csup\u003e1\u003c/sup\u003e         |✅         |✅            |✅            |✅            |✅          |✅             |✅             |✅             |\n| Calendar                 |✅         |✅            |✅            |✅            |✅          |✅             |✅             |✅             |\n| DayOfWeek                |❌         |❌            |❌            |❌            |❌          |❌             |❌             |❌             |\n| Instant\u003csup\u003e1\u003c/sup\u003e      |✅         |✅            |✅            |✅            |✅          |✅             |✅             |✅             |\n| LocalDate\u003csup\u003e2\u003c/sup\u003e    |❌         |❌            |❌            |❌            |❌          |❌             |❌             |❌             |\n| LocalDateTime\u003csup\u003e3\u003c/sup\u003e|✅         |✅            |✅            |✅            |✅          |✅             |✅             |✅             |\n| LocalTime                |❌         |❌            |❌            |❌            |❌          |❌             |❌             |❌             |\n| Month                    |❌         |❌            |❌            |❌            |❌          |❌             |❌             |❌             |\n| MonthDay                 |❌         |❌            |❌            |❌            |❌          |❌             |❌             |❌             |\n| OffsetDateTime           |✅         |✅            |✅            |✅            |✅          |✅             |✅             |✅             |\n| OffsetTime               |❌         |❌            |❌            |❌            |❌          |❌             |❌             |❌             |\n| Year                     |❌         |❌            |❌            |❌            |❌          |❌             |❌             |❌             |\n| YearMonth                |❌         |❌            |❌            |❌            |❌          |❌             |❌             |❌             |\n| ZonedDateTime            |✅         |✅            |✅            |✅            |✅          |✅             |✅             |✅             |\n\n\u003csup\u003e1\u003c/sup\u003e: because the type has no time zone information, the `zoneId` may not be defined as `provided`.\\\n\u003csup\u003e2\u003c/sup\u003e: can be validated with annotations from `date-time-validation`.\\\n\u003csup\u003e3\u003c/sup\u003e: because no time zone is applicable for the type, the `zoneId` must be defined as `system`. Since this is the default, the `zoneId` parameter can simply be omitted.\n\n### time-validation\n[![Maven Central](https://img.shields.io/maven-central/v/com.github.robtimus/time-validation)](https://search.maven.org/artifact/com.github.robtimus/time-validation)\n[![Known Vulnerabilities](https://snyk.io/test/github/robtimus/date-time-validation/badge.svg?targetFile=time-validation/pom.xml)](https://snyk.io/test/github/robtimus/date-time-validation?targetFile=time-validation/pom.xml)\n\nValidation constraints for date/time objects that validate only the time part. These work just like the constraints of `date-time-validation` module, except they ignore any date part. The `moment` must be `now` or valid according to `LocalTime.parse`, and the `duration` may not contain any date elements.\n\nThese annotations apply to the following types:\n\n| Type                     | TimeAfter | TimeNotAfter | TimeMinAfter | TimeMaxAfter | TimeBefore | TimeNotBefore | TimeMinBefore | TimeMaxBefore |\n|--------------------------|:---------:|:------------:|:------------:|:------------:|:----------:|:-------------:|:-------------:|:-------------:|\n| Date\u003csup\u003e1\u003c/sup\u003e         |✅         |✅            |✅            |✅            |✅          |✅             |✅             |✅             |\n| Calendar                 |✅         |✅            |✅            |✅            |✅          |✅             |✅             |✅             |\n| DayOfWeek                |❌         |❌            |❌            |❌            |❌          |❌             |❌             |❌             |\n| Instant\u003csup\u003e1\u003c/sup\u003e      |✅         |✅            |✅            |✅            |✅          |✅             |✅             |✅             |\n| LocalDate                |❌         |❌            |❌            |❌            |❌          |❌             |❌             |❌             |\n| LocalDateTime\u003csup\u003e2\u003c/sup\u003e|✅         |✅            |✅            |✅            |✅          |✅             |✅             |✅             |\n| LocalTime\u003csup\u003e3\u003c/sup\u003e    |❌         |❌            |❌            |❌            |❌          |❌             |❌             |❌             |\n| Month                    |❌         |❌            |❌            |❌            |❌          |❌             |❌             |❌             |\n| MonthDay                 |❌         |❌            |❌            |❌            |❌          |❌             |❌             |❌             |\n| OffsetDateTime           |✅         |✅            |✅            |✅            |✅          |✅             |✅             |✅             |\n| OffsetTime\u003csup\u003e3\u003c/sup\u003e   |❌         |❌            |❌            |❌            |❌          |❌             |❌             |❌             |\n| Year                     |❌         |❌            |❌            |❌            |❌          |❌             |❌             |❌             |\n| YearMonth                |❌         |❌            |❌            |❌            |❌          |❌             |❌             |❌             |\n| ZonedDateTime            |✅         |✅            |✅            |✅            |✅          |✅             |✅             |✅             |\n\n\u003csup\u003e1\u003c/sup\u003e: because the type has no time zone information, the `zoneId` may not be defined as `provided`.\\\n\u003csup\u003e2\u003c/sup\u003e: because no time zone is applicable for the type, the `zoneId` must be defined as `system`. Since this is the default, the `zoneId` parameter can simply be omitted.\\\n\u003csup\u003e3\u003c/sup\u003e: can be validated with annotations from `date-time-validation`.\n\n### year-month-validation\n[![Maven Central](https://img.shields.io/maven-central/v/com.github.robtimus/year-month-validation)](https://search.maven.org/artifact/com.github.robtimus/year-month-validation)\n[![Known Vulnerabilities](https://snyk.io/test/github/robtimus/date-time-validation/badge.svg?targetFile=year-month-validation/pom.xml)](https://snyk.io/test/github/robtimus/date-time-validation?targetFile=year-month-validation/pom.xml)\n\nValidation constraints for date/time objects that validate only the year and month. These work just like the constraints of the `date-time-validation` module, except they ignore the day of the month and any time part. The `moment` must be `now` or valid according to `YearMonth.parse`, and the `duration` may only contain year and month elements.\n\nThese annotations apply to the following types:\n\n| Type                     | YearMonthAfter | YearMonthNotAfter | YearMonthMinAfter | YearMonthMaxAfter | YearMonthBefore | YearMonthNotBefore | YearMonthMinBefore | YearMonthMaxBefore |\n|--------------------------|:--------------:|:-----------------:|:-----------------:|:-----------------:|:---------------:|:------------------:|:------------------:|:------------------:|\n| Date\u003csup\u003e1\u003c/sup\u003e         |✅              |✅                 |✅                 |✅                 |✅               |✅                  |✅                  |✅                  |\n| Calendar                 |✅              |✅                 |✅                 |✅                 |✅               |✅                  |✅                  |✅                  |\n| DayOfWeek                |❌              |❌                 |❌                 |❌                 |❌               |❌                  |❌                  |❌                  |\n| Instant\u003csup\u003e1\u003c/sup\u003e      |✅              |✅                 |✅                 |✅                 |✅               |✅                  |✅                  |✅                  |\n| LocalDate\u003csup\u003e2\u003c/sup\u003e    |✅              |✅                 |✅                 |✅                 |✅               |✅                  |✅                  |✅                  |\n| LocalDateTime\u003csup\u003e2\u003c/sup\u003e|✅              |✅                 |✅                 |✅                 |✅               |✅                  |✅                  |✅                  |\n| LocalTime                |❌              |❌                 |❌                 |❌                 |❌               |❌                  |❌                  |❌                  |\n| Month                    |❌              |❌                 |❌                 |❌                 |❌               |❌                  |❌                  |❌                  |\n| MonthDay                 |❌              |❌                 |❌                 |❌                 |❌               |❌                  |❌                  |❌                  |\n| OffsetDateTime           |✅              |✅                 |✅                 |✅                 |✅               |✅                  |✅                  |✅                  |\n| OffsetTime               |❌              |❌                 |❌                 |❌                 |❌               |❌                  |❌                  |❌                  |\n| Year                     |❌              |❌                 |❌                 |❌                 |❌               |❌                  |❌                  |❌                  |\n| YearMonth\u003csup\u003e3\u003c/sup\u003e    |❌              |❌                 |❌                 |❌                 |❌               |❌                  |❌                  |❌                  |\n| ZonedDateTime            |✅              |✅                 |✅                 |✅                 |✅               |✅                  |✅                  |✅                  |\n\n\u003csup\u003e1\u003c/sup\u003e: because the type has no time zone information, the `zoneId` may not be defined as `provided`.\\\n\u003csup\u003e2\u003c/sup\u003e: because no time zone is applicable for the type, the `zoneId` must be defined as `system`. Since this is the default, the `zoneId` parameter can simply be omitted.\\\n\u003csup\u003e3\u003c/sup\u003e: can be validated with annotations from `date-time-validation`.\n\n### year-validation\n[![Maven Central](https://img.shields.io/maven-central/v/com.github.robtimus/year-validation)](https://search.maven.org/artifact/com.github.robtimus/year-validation)\n[![Known Vulnerabilities](https://snyk.io/test/github/robtimus/date-time-validation/badge.svg?targetFile=year-validation/pom.xml)](https://snyk.io/test/github/robtimus/date-time-validation?targetFile=year-validation/pom.xml)\n\nValidation constraints for date/time objects that validate only the year. These work just like the constraints of the `date-time-validation` module, except they ignore the month, the day of the month and any time part. The `moment` must be `now` or valid according to `Year.parse`, and the `duration` (renamed to `years`) must be specified as a number of years only. The latter prevents having to write `\"P1Y\"` instead of just `1`.\n\nThese annotations apply to the following types:\n\n| Type                     | YearAfter | YearNotAfter | YearMinAfter | YearMaxAfter | YearBefore | YearNotBefore | YearMinBefore | YearMaxBefore |\n|--------------------------|:---------:|:------------:|:------------:|:------------:|:----------:|:-------------:|:-------------:|:-------------:|\n| Date\u003csup\u003e1\u003c/sup\u003e         |✅         |✅            |✅            |✅            |✅          |✅             |✅             |✅             |\n| Calendar                 |✅         |✅            |✅            |✅            |✅          |✅             |✅             |✅             |\n| DayOfWeek                |❌         |❌            |❌            |❌            |❌          |❌             |❌             |❌             |\n| Instant\u003csup\u003e1\u003c/sup\u003e      |✅         |✅            |✅            |✅            |✅          |✅             |✅             |✅             |\n| LocalDate\u003csup\u003e2\u003c/sup\u003e    |✅         |✅            |✅            |✅            |✅          |✅             |✅             |✅             |\n| LocalDateTime\u003csup\u003e2\u003c/sup\u003e|✅         |✅            |✅            |✅            |✅          |✅             |✅             |✅             |\n| LocalTime                |❌         |❌            |❌            |❌            |❌          |❌             |❌             |❌             |\n| Month                    |❌         |❌            |❌            |❌            |❌          |❌             |❌             |❌             |\n| MonthDay                 |❌         |❌            |❌            |❌            |❌          |❌             |❌             |❌             |\n| OffsetDateTime           |✅         |✅            |✅            |✅            |✅          |✅             |✅             |✅             |\n| OffsetTime               |❌         |❌            |❌            |❌            |❌          |❌             |❌             |❌             |\n| Year\u003csup\u003e3\u003c/sup\u003e         |❌         |❌            |❌            |❌            |❌          |❌             |❌             |❌             |\n| YearMonth\u003csup\u003e2\u003c/sup\u003e    |✅         |✅            |✅            |✅            |✅          |✅             |✅             |✅             |\n| ZonedDateTime            |✅         |✅            |✅            |✅            |✅          |✅             |✅             |✅             |\n\n\u003csup\u003e1\u003c/sup\u003e: because the type has no time zone information, the `zoneId` may not be defined as `provided`.\\\n\u003csup\u003e2\u003c/sup\u003e: because no time zone is applicable for the type, the `zoneId` must be defined as `system`. Since this is the default, the `zoneId` parameter can simply be omitted.\\\n\u003csup\u003e3\u003c/sup\u003e: can be validated with annotations from `date-time-validation`.\n\n### month-validation\n[![Maven Central](https://img.shields.io/maven-central/v/com.github.robtimus/month-validation)](https://search.maven.org/artifact/com.github.robtimus/month-validation)\n[![Known Vulnerabilities](https://snyk.io/test/github/robtimus/date-time-validation/badge.svg?targetFile=month-validation/pom.xml)](https://snyk.io/test/github/robtimus/date-time-validation?targetFile=month-validation/pom.xml)\n\nValidation constraints for date/time objects that validate only the month. These validate the following, where `object` is the object to be validated, and `value` is the value specified in the constraint:\n\n| Constraint | Meaning                       |\n|------------|-------------------------------|\n| MonthIs    | object.month == value         |\n| MonthIn    | value.contains(object.month)  |\n| MonthNotIn | !value.contains(object.month) |\n\nThese annotations apply to the following types:\n\n| Type                     | MonthIs | MonthIn | MonthNotIn |\n|--------------------------|:-------:|:-------:|:----------:|\n| Date\u003csup\u003e1\u003c/sup\u003e         |✅       |✅       |✅          |\n| Calendar                 |✅       |✅       |✅          |\n| DayOfWeek                |❌       |❌       |❌          |\n| Instant\u003csup\u003e1\u003c/sup\u003e      |✅       |✅       |✅          |\n| LocalDate\u003csup\u003e2\u003c/sup\u003e    |✅       |✅       |✅          |\n| LocalDateTime\u003csup\u003e2\u003c/sup\u003e|✅       |✅       |✅          |\n| LocalTime                |❌       |❌       |❌          |\n| Month\u003csup\u003e2\u003c/sup\u003e        |✅       |✅       |✅          |\n| MonthDay\u003csup\u003e2\u003c/sup\u003e     |✅       |✅       |✅          |\n| OffsetDateTime           |✅       |✅       |✅          |\n| OffsetTime               |❌       |❌       |❌          |\n| Year                     |❌       |❌       |❌          |\n| YearMonth\u003csup\u003e2\u003c/sup\u003e    |✅       |✅       |✅          |\n| ZonedDateTime            |✅       |✅       |✅          |\n\n\u003csup\u003e1\u003c/sup\u003e: because the type has no time zone information, the `zoneId` may not be defined as `provided`.\\\n\u003csup\u003e2\u003c/sup\u003e: because no time zone is applicable for the type, the `zoneId` must be defined as `system`. Since this is the default, the `zoneId` parameter can simply be omitted.\n\n#### year-month-validation vs month-validation\n\n`year-month-validation` validates the combination of the year and the month. This allows it to be used for cases like credit card validation. `month-validation` on the other hand ignores the year.\n\n### day-of-week-validation\n[![Maven Central](https://img.shields.io/maven-central/v/com.github.robtimus/day-of-week-validation)](https://search.maven.org/artifact/com.github.robtimus/day-of-week-validation)\n[![Known Vulnerabilities](https://snyk.io/test/github/robtimus/date-time-validation/badge.svg?targetFile=day-of-week-validation/pom.xml)](https://snyk.io/test/github/robtimus/date-time-validation?targetFile=day-of-week-validation/pom.xml)\n\nValidation constraints for date/time objects that validate only the day of the week. These validate the following, where `object` is the object to be validated, and `value` is the value specified in the constraint:\n\n| Constraint     | Meaning                           |\n|----------------|-----------------------------------|\n| DayOfWeekIs    | object.dayOfWeek == value         |\n| DayOfWeekIn    | value.contains(object.dayOfWeek)  |\n| DayOfWeekNotIn | !value.contains(object.dayOfWeek) |\n\nNote that days of the week are ordered from Monday until Sunday.\n\nThese annotations apply to the following types:\n\n| Type                     | DayOfWeekIs | DayOfWeekIn | DayOfWeekNotIn |\n|--------------------------|:-----------:|:-----------:|:--------------:|\n| Date\u003csup\u003e1\u003c/sup\u003e         |✅           |✅           |✅              |\n| Calendar                 |✅           |✅           |✅              |\n| Instant\u003csup\u003e1\u003c/sup\u003e      |✅           |✅           |✅              |\n| LocalDate\u003csup\u003e2\u003c/sup\u003e    |✅           |✅           |✅              |\n| DayOfWeek\u003csup\u003e2\u003c/sup\u003e    |✅           |✅           |✅              |\n| LocalDateTime\u003csup\u003e2\u003c/sup\u003e|✅           |✅           |✅              |\n| LocalTime                |❌           |❌           |❌              |\n| Month                    |❌           |❌           |❌              |\n| MonthDay                 |❌           |❌           |❌              |\n| OffsetDateTime           |✅           |✅           |✅              |\n| OffsetTime               |❌           |❌           |❌              |\n| Year                     |❌           |❌           |❌              |\n| YearMonth                |❌           |❌           |❌              |\n| ZonedDateTime            |✅           |✅           |✅              |\n\n\u003csup\u003e1\u003c/sup\u003e: because the type has no time zone information, the `zoneId` may not be defined as `provided`.\\\n\u003csup\u003e2\u003c/sup\u003e: because no time zone is applicable for the type, the `zoneId` must be defined as `system`. Since this is the default, the `zoneId` parameter can simply be omitted.\n\n### day-of-month-validation\n[![Maven Central](https://img.shields.io/maven-central/v/com.github.robtimus/day-of-month-validation)](https://search.maven.org/artifact/com.github.robtimus/day-of-month-validation)\n[![Known Vulnerabilities](https://snyk.io/test/github/robtimus/date-time-validation/badge.svg?targetFile=day-of-month-validation/pom.xml)](https://snyk.io/test/github/robtimus/date-time-validation?targetFile=day-of-month-validation/pom.xml)\n\nValidation constraints for date/time objects that validate only the day of the month. These validate the following, where `object` is the object to be validated, and `value` is the value specified in the constraint:\n\n| Constraint       | Meaning                                   |\n|------------------|-------------------------------------------|\n| DayOfMonthIs     | object.dayOfMonth == value                |\n| DayOfMonthIn     | value.contains(object.dayOfMonth)         |\n| DayOfMonthNotIn  | !value.contains(object.dayOfMonth)        |\n| LastDayOfMonth   | object.dayOfMonth == object.month.lastDay |\n\nThese annotations apply to the following types:\n\n| Type                      | DayOfMonthIs | DayOfMonthIn | DayOfMonthNotIn | LastDayOfMonth |\n|---------------------------|:------------:|:------------:|:---------------:|:--------------:|\n| Date\u003csup\u003e1\u003c/sup\u003e          |✅            |✅            |✅               |✅              |\n| Calendar                  |✅            |✅            |✅               |✅              |\n| DayOfWeek                 |❌            |❌            |❌               |❌              |\n| Instant\u003csup\u003e1\u003c/sup\u003e       |✅            |✅            |✅               |✅              |\n| LocalDate\u003csup\u003e2\u003c/sup\u003e     |✅            |✅            |✅               |✅              |\n| LocalDateTime\u003csup\u003e2\u003c/sup\u003e |✅            |✅            |✅               |✅              |\n| LocalTime                 |❌            |❌            |❌               |❌              |\n| Month                     |❌            |❌            |❌               |❌              |\n| MonthDay\u003csup\u003e3\u003c/sup\u003e      |✅            |✅            |✅               |❌              |\n| OffsetDateTime            |✅            |✅            |✅               |✅              |\n| OffsetTime                |❌            |❌            |❌               |❌              |\n| Year                      |❌            |❌            |❌               |❌              |\n| YearMonth                 |❌            |❌            |❌               |❌              |\n| ZonedDateTime             |✅            |✅            |✅               |✅              |\n\n\u003csup\u003e1\u003c/sup\u003e: because the type has no time zone information, the `zoneId` may not be defined as `provided`.\\\n\u003csup\u003e2\u003c/sup\u003e: because no time zone is applicable for the type, the `zoneId` must be defined as `system`. Since this is the default, the `zoneId` parameter can simply be omitted.\\\n\u003csup\u003e3\u003c/sup\u003e: `LastDayOfMonth` cannot be applied to [MonthDay](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/MonthDay.html) because \"it is not possible to define whether February 29th is valid or not without external information\". This makes it impossible to determine whether or not February 28th is the last day of the month or not.\n\n### hour-validation\n[![Maven Central](https://img.shields.io/maven-central/v/com.github.robtimus/hour-validation)](https://search.maven.org/artifact/com.github.robtimus/hour-validation)\n[![Known Vulnerabilities](https://snyk.io/test/github/robtimus/date-time-validation/badge.svg?targetFile=hour-validation/pom.xml)](https://snyk.io/test/github/robtimus/date-time-validation?targetFile=hour-validation/pom.xml)\n\nValidation constraints for date/time objects that validate only the hour. These validate the following, where `object` is the object to be validated, and `value` is the value specified in the constraint:\n\n| Constraint | Meaning                      |\n|------------|------------------------------|\n| HourIs     | object.hour == value         |\n| HourIn     | value.contains(object.hour)  |\n| HourNotIn  | !value.contains(object.hour) |\n\nThese annotations apply to the following types:\n\n| Type                      | HourIs | HourIn | HourNotIn |\n|---------------------------|:------:|:------:|:---------:|\n| Date\u003csup\u003e1\u003c/sup\u003e          |✅      |✅      |✅         |\n| Calendar                  |✅      |✅      |✅         |\n| DayOfWeek                 |❌      |❌      |❌         |\n| Instant\u003csup\u003e1\u003c/sup\u003e       |✅      |✅      |✅         |\n| LocalDate                 |❌      |❌      |❌         |\n| LocalDateTime\u003csup\u003e2\u003c/sup\u003e |✅      |✅      |✅         |\n| LocalTime\u003csup\u003e2\u003c/sup\u003e     |✅      |✅      |✅         |\n| Month                     |❌      |❌      |❌         |\n| MonthDay                  |❌      |❌      |❌         |\n| OffsetDateTime            |✅      |✅      |✅         |\n| OffsetTime                |✅      |✅      |✅         |\n| Year                      |❌      |❌      |❌         |\n| YearMonth                 |❌      |❌      |❌         |\n| ZonedDateTime             |✅      |✅      |✅         |\n\n\u003csup\u003e1\u003c/sup\u003e: because the type has no time zone information, the `zoneId` may not be defined as `provided`.\\\n\u003csup\u003e2\u003c/sup\u003e: because no time zone is applicable for the type, the `zoneId` must be defined as `system`. Since this is the default, the `zoneId` parameter can simply be omitted.\n\n### minute-validation\n[![Maven Central](https://img.shields.io/maven-central/v/com.github.robtimus/minute-validation)](https://search.maven.org/artifact/com.github.robtimus/minute-validation)\n[![Known Vulnerabilities](https://snyk.io/test/github/robtimus/date-time-validation/badge.svg?targetFile=minute-validation/pom.xml)](https://snyk.io/test/github/robtimus/date-time-validation?targetFile=minute-validation/pom.xml)\n\nValidation constraints for date/time objects that validate only the minute. These validate the following, where `object` is the object to be validated, and `value` is the value specified in the constraint:\n\n| Constraint  | Meaning                        |\n|-------------|--------------------------------|\n| MinuteIs    | object.minute == value         |\n| MinuteIn    | value.contains(object.minute)  |\n| MinuteNotIn | !value.contains(object.minute) |\n\nThese annotations apply to the following types:\n\n| Type                      | MinuteIs | MinuteIn | MinuteNotIn |\n|---------------------------|:--------:|:--------:|:-----------:|\n| Date\u003csup\u003e1\u003c/sup\u003e          |✅        |✅        |✅           |\n| Calendar                  |✅        |✅        |✅           |\n| DayOfWeek                 |❌        |❌        |❌           |\n| Instant\u003csup\u003e1\u003c/sup\u003e       |✅        |✅        |✅           |\n| LocalDate                 |❌        |❌        |❌           |\n| LocalDateTime\u003csup\u003e2\u003c/sup\u003e |✅        |✅        |✅           |\n| LocalTime\u003csup\u003e2\u003c/sup\u003e     |✅        |✅        |✅           |\n| Month                     |❌        |❌        |❌           |\n| MonthDay                  |❌        |❌        |❌           |\n| OffsetDateTime            |✅        |✅        |✅           |\n| OffsetTime                |✅        |✅        |✅           |\n| Year                      |❌        |❌        |❌           |\n| YearMonth                 |❌        |❌        |❌           |\n| ZonedDateTime             |✅        |✅        |✅           |\n\n\u003csup\u003e1\u003c/sup\u003e: because the type has no time zone information, the `zoneId` may not be defined as `provided`.\\\n\u003csup\u003e2\u003c/sup\u003e: because no time zone is applicable for the type, the `zoneId` must be defined as `system`. Since this is the default, the `zoneId` parameter can simply be omitted.\n\n### time-precision-validation\n[![Maven Central](https://img.shields.io/maven-central/v/com.github.robtimus/time-precision-validation)](https://search.maven.org/artifact/com.github.robtimus/time-precision-validation)\n[![Known Vulnerabilities](https://snyk.io/test/github/robtimus/date-time-validation/badge.svg?targetFile=time-precision-validation/pom.xml)](https://snyk.io/test/github/robtimus/date-time-validation?targetFile=time-precision-validation/pom.xml)\n\nValidation constraints for date/time objects that validate only the precision of the time part. These validate the following, where `object` is the object to be validated, and `value` is the value specified in the constraint:\n\n| Constraint           | Meaning                                      |\n|----------------------|----------------------------------------------|\n| MinutePrecision      | object.second == 0 \u0026\u0026 object.nanosecond == 0 |\n| SecondPrecision      | object.nanosecond == 0                       |\n| MillisecondPrecision | object.nanosecond % 1000_000 == 0            |\n| MicrosecondPrecision | object.nanosecond % 1000 == 0                |\n\nThese annotations apply to the following types:\n\n| Type                | MinutePrecision | SecondPrecision | MillisecondPrecision | MicrosecondPrecision |\n|---------------------|:---------------:|:---------------:|:--------------------:|:--------------------:|\n| Date\u003csup\u003e1\u003c/sup\u003e    |✅               |✅               |❌                    |❌                    |\n| Calendar            |✅               |✅               |❌                    |❌                    |\n| DayOfWeek           |❌               |❌               |❌                    |❌                    |\n| Instant\u003csup\u003e1\u003c/sup\u003e |✅               |✅               |✅                    |✅                    |\n| LocalDate           |❌               |❌               |❌                    |❌                    |\n| LocalDateTime       |✅               |✅               |✅                    |✅                    |\n| LocalTime           |✅               |✅               |✅                    |✅                    |\n| Month               |❌               |❌               |❌                    |❌                    |\n| MonthDay            |❌               |❌               |❌                    |❌                    |\n| OffsetDateTime      |✅               |✅               |✅                    |✅                    |\n| OffsetTime          |✅               |✅               |✅                    |✅                    |\n| Year                |❌               |❌               |❌                    |❌                    |\n| YearMonth           |❌               |❌               |❌                    |❌                    |\n| ZonedDateTime       |✅               |✅               |✅                    |✅                    |\n\n\u003csup\u003e1\u003c/sup\u003e: to be able to determine the second, the UTC zone is applied.\n\n## Examples\n\nTo specify that a date of birth must be at least 18 years in the past:\n```java\n@MinBefore(moment = \"now\", duration = \"P18Y\")\nLocalDate dateOfBirth;\n```\n\nTo specify that a credit card must not have expired:\n```java\n@NotBefore(moment = \"now\")\nYearMonth expiryDate;\n```\n\nTo specify that a credit card must not expire within the next 6 months:\n```java\n@MinAfter(duration = \"P6M\", moment = \"now\")\nYearMonth expiryDate;\n```\n\nTo specify that a date must be next month or later, where the day of the month is irrelevant:\n```java\n@YearMonthMinAfter(duration = \"P1M\", moment = \"now\")\nLocalDate date;\n```\n\nTo specify that a date must be next year or later, where the actual date is irrelevant:\n```java\n@YearMinAfter(years = 1, moment = \"now\")\n// or @YearAfter(moment = \"now\")\nLocalDate date;\n```\n\nTo specify that a date/time object like `ZonedDateTime` must be on a weekday between 9:00 and 18:00 (exclusive), at 15 minute intervals, and not between 12:00 and 13:00 (exclusive):\n```java\n@DayOfWeekIn({ MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY })\n@TimeNotBefore(moment = \"09:00:00\")\n@TimeBefore(moment = \"18:00:00\")\n@MinuteIn({ 0, 15, 30, 45 })\n@HourNotIn(12)\n@MinutePrecision\nZonedDateTime appointmentDateTime;\n```\nor alternatively:\n```java\n@DayOfWeekIn({ MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY })\n@HourIn({ 9, 10, 11, 13, 14, 15, 16, 17 })\n@MinuteIn({ 0, 15, 30, 45 })\n@MinutePrecision\nZonedDateTime appointmentDateTime;\n```\n\n## Custom constraint annotations\n\n### Combining provided constraint annotations\n\nThe provided constraint annotations provide enough functionality for most cases. However, when several constraints are combined, like the last example, that may become unreadable. In cases like that it's easy to create a new constraint annotation and annotate that with the provided constraint annotations:\n```java\n@Documented\n// annotations required for constraint annotations; the target can be simplified\n@Constraint(validatedBy = {})\n@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })\n@Retention(RUNTIME)\n// date/time annotations\n@DayOfWeekIn({ MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY })\n@HourIn({ 9, 10, 11, 13, 14, 15, 16, 17 })\n@MinuteIn({ 0, 15, 30, 45 })\n@MinutePrecision\n// don't report violations for the above annotations separately\n@ReportAsSingleViolation\npublic @interface AppointmentSlot {\n\n    String message() default \"must be a valid appointment slot\";\n\n    Class\u003c?\u003e[] groups() default { };\n\n    Class\u003c? extends Payload\u003e[] payload() default { };\n}\n```\n\n### Custom validators\n\nIn case the provided constraint annotations cannot be combined to achieve the desired result, module `date-time-base-validators` provides some base classes that can be used to write custom constraint validators. These all use functional interfaces to define custom behaviour; most of them can be supplied using method references. See package [com.github.robtimus.validation.datetime.base](https://robtimus.github.io/date-time-validation/apidocs/com/github/robtimus/validation/datetime/base/package-summary.html) for an overview.\n\n## Bean Validation API support\n\nVersion 2.x of this library has been written for [Jakarta Bean Validation 3.0](https://beanvalidation.org/3.0/), as part of Jakarta EE 9.\n\nVersion 1.x of this library has been written for [Jakarta Bean Validation 2.0](https://beanvalidation.org/2.0/), as part of Jakarta EE 8. However, it should also work with Bean Valdation 2.0 (non-Jakarta) and [Bean Validation 1.1](https://beanvalidation.org/1.1/).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frobtimus%2Fdate-time-validation","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frobtimus%2Fdate-time-validation","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frobtimus%2Fdate-time-validation/lists"}