Recurring

A Java implementation of the ideas in Martin Fowler's "Recurring Events for Calendars".

License

License

Categories

Categories

Net
GroupId

GroupId

net.logicsquad
ArtifactId

ArtifactId

recurring
Last Version

Last Version

0.1
Release Date

Release Date

Type

Type

jar
Description

Description

Recurring
A Java implementation of the ideas in Martin Fowler's "Recurring Events for Calendars".
Project URL

Project URL

https://github.com/paulhoadley/recurring
Project Organization

Project Organization

Logic Squad
Source Code Management

Source Code Management

https://github.com/paulhoadley/recurring/tree/master

Download recurring

How to add to project

<!-- https://jarcasting.com/artifacts/net.logicsquad/recurring/ -->
<dependency>
    <groupId>net.logicsquad</groupId>
    <artifactId>recurring</artifactId>
    <version>0.1</version>
</dependency>
// https://jarcasting.com/artifacts/net.logicsquad/recurring/
implementation 'net.logicsquad:recurring:0.1'
// https://jarcasting.com/artifacts/net.logicsquad/recurring/
implementation ("net.logicsquad:recurring:0.1")
'net.logicsquad:recurring:jar:0.1'
<dependency org="net.logicsquad" name="recurring" rev="0.1">
  <artifact name="recurring" type="jar" />
</dependency>
@Grapes(
@Grab(group='net.logicsquad', module='recurring', version='0.1')
)
libraryDependencies += "net.logicsquad" % "recurring" % "0.1"
[net.logicsquad/recurring "0.1"]

Dependencies

test (1)

Group / Artifact Type Version
junit : junit jar 4.12

Project Modules

There are no modules declared in this project.

Build Status License

Recurring

What is this?

This project provides some interfaces and classes to represent recurring events in Java. It is able to represent some simple "temporal expressions", such as:

  • First Thursday of the month
  • Last Wednesday of the month
  • Every day in June
  • Every day from 17 May through 19 August
  • 1 September

The expressions are agnostic to the year.

It also supports some simple ways of combining these expressions: union, intersection and difference. These can be combined in arbitrarily complex ways. For example:

  • First Thursday and last Wednesday of every month from 17 May through 19 August, except the month of June
  • Second Monday of January through March

Getting started

ScheduleElements (which link a TemporalExpression to a String token representing an event) can be combined into a Schedule, which can then answer queries about the elements it contains. For example, construct a TemporalExpression representing an event that occurs on the first Thursday and last Wednesday of every month, and then put a ScheduleElement into a Schedule:

TemporalExpression firstThursday = DayInMonth.of(DayOfWeek.THURSDAY, 1);
TemporalExpression lastWednesday = DayInMonth.of(DayOfWeek.WEDNESDAY, -1);
ScheduleElement element = ScheduleElement.of("Meeting", Union.of(firstThursday, lastWednesday));
Schedule schedule = Schedule.of(element);

Among other things, the Schedule can now tell us if the meeting is on today:

boolean today = schedule.isOccurring("Meeting", LocalDate.now());

when the meeting last occurred:

LocalDate last = schedule.previousOccurrence("Meeting", LocalDate.now());

and all future dates of the meeting:

Stream<LocalDate> future = schedule.futureDates("Meeting", LocalDate.now());

Using Recurring

The current release is 0.1, and you can use Recurring in your projects by including it as a dependency:

<dependency>
  <groupId>net.logicsquad</groupId>
  <artifactId>recurring</artifactId>
  <version>0.1</version>
</dependency>

Note that the API may change prior to a 1.0 release, at which time it will remain stable, consistent with semantic versioning.

Contributing

By all means, open issue tickets and pull requests if you have something to contribute.

References

This project implements the ideas in Martin Fowler's "Recurring Events for Calendars" (1997). Where appropriate, we have made some changes to the code and ideas presented in the original article.

  • We will make use of interfaces where appropriate. The original article hinted at interfaces, but mostly gave examples of concrete classes.
  • We will use java.time.LocalDate instead of java.util.Date.
  • We will make some minor changes to suggested class names.

Most of this just reflects more modern Java idioms and changes in the language and libraries.

Versions

Version
0.1