[[moments]]
= Moments -- a Passage of Time Events API

`spring-modulith-moments` is a Passage of Time Events implementation heavily inspired by Matthias Verraes https://verraes.net/2019/05/patterns-for-decoupling-distsys-passage-of-time-event/[blog post].
It's an event-based approach to time to trigger actions that are tied to a particular period of time having passed.

To use the abstraction, include the following dependency in your project:

[tabs]
======
Maven::
+
[source, xml, role="primary"]
----
<dependency>
  <groupId>org.springframework.modulith</groupId>
  <artifactId>spring-modulith-moments</artifactId>
</dependency>
----

Gradle::
+
[source, role="secondary"]
----
dependencies {
  implementation 'org.springframework.modulith:spring-modulith-moments'
}
----
======

The dependency added to the project's classpath causes the following things in your application:

* Application code can refer to `HourHasPassed`, `DayHasPassed`, `WeekHasPassed`, `MonthHasPassed`, `QuarterHasPassed`, `YearHasPassed` types in Spring event listeners to get notified if a certain amount of time has passed.
* A bean of type `org.springframework.modulith.Moments` is available in the `ApplicationContext` that contains the logic to trigger these events.
* If `spring.modulith.moments.enable-time-machine` is set to `true`, that instance will be a `org.springframework.modulith.TimeMachine` which allows to "shift" time and by that triggers all intermediate events, which is useful to integration test functionality that is triggered by the events.

By default, Moments uses a `Clock.systemUTC()` instance. To customize this, declare a bean of type `Clock`.

[tabs]
======
Java::
+
[source, java, role="primary"]
----
@Configuration
class MyConfiguration {

  @Bean
  Clock myCustomClock() {
    // Create a custom Clock here
  }
}
----
Kotlin::
+
[source, kotlin, role="secondary"]
----
@Configuration
class MyConfiguration {

  @Bean
  fun myCustomClock(): Clock {
    // Create a custom Clock here
  }
}
----
======

Moments exposes the following application properties for advanced customization:

.Available application properties
[%header, cols="3,1,2"]
|===
|Property|Default value|Description
|`spring.modulith.moments.enable-time-machine`|false|If set to `true`, the `Moments` instance will be a `TimeMachine`, that exposes API to shift time forward. Useful for integration tests that expect functionality triggered by the Passage of Time Events.
|`spring.modulith.moments.granularity`|hours|The minimum granularity of events to be fired. Alternative value `days` to avoid hourly events.
|`spring.modulith.moments.locale`|`Locale.getDefault()`|The `Locale` to use when determining week boundaries.
|`spring.modulith.moments.quarter-start-month`|`Months.JANUARY`|The month at which quarters start.
|`spring.modulith.moments.zone-id`|`ZoneOffset#UTC`|The `ZoneId` to determine times which are attached to the events published.
|===

