Temporal framework for Java

Tutorial - 1 - Basic Structures

The foundations of JTemporal are Instants and Periods.

Instant represents a time point. In the context of your application it could be a date, a millisecond or anything else. It is just an interface, you are supposed to implement it. If you are happy with java.util.Date or java.sql.Date, you can easily adapt it.

Many companies have their own date framework, because java.util.Date is more "time" oriented than "date" oriented. For example, when you want to define a contractual date, like the starting day of a new employee, you do not want this date to be interpreted differently when the client application is in a different timezone.

The object implementing Instant is expected to be immutable, like for example java.util.Integer. This means that once that object has been created, any of its fields cannot be modified, including recursively the referenced objects. The advantage of immutable objects is that they are inherently thread-safe and that the objects which are referencing them, especially collections, do not need to make defensive copies (cloning). Immutable objects can be used safely as keys of Map collections.

As a simple example, in the JTemporal unit tests you can find the class IntInstant, adapting a simple int to be an Instant. Basically an Instant is just a java.lang.Comparable.

Once you have defined your Instants, you can use the Period class. A period is defined by two distinct instants and defines a time segment. It should not be confused with an interval which just defines a duration and not when this duration happens. Periods are immutable. By convention, the period is defined as "half-open", meaning that the start limit instant is part of the defined period, but the end limit instant is not : period = [start,end[
There is a particular case, when "end" is the positive infinity: given that infinity-1 = infinity, infinity is always part of the period.

The Period class offers some comfortable operations, like intersects(Period), overlaps(Period), contains(Instant), contains(Period), union(Period), etc.


Tutorial - 2 - Modeling temporal associations with unary cardinality

Suppose the following classic scenario. You have an object Employee which is associated to an object Salary. You have a salary for a given period, then another salary for another period. For your employee, at a given instant, there is at most one salary, the salary cardinality is 0..1 (unary).

To conceptually represent our scenario, I like the language proposed by Carlson, Estepp and Fowler :

The <<temporal>> stereotype indicates that the given cardinality applies at any given instant.


For the implementation, JTemporal provides the TemporalAttribute which is a collection acting as a mediator, managing the temporal aspects. You just put it in between like this:


TreeTemporalAttribute is currently the only implementation of TemporalAttribute. To define a salary, you just call put(period, salary). To know what the salary is at a given instant you call get(instant).

When you call put(period, salary), if there is already definition for a period overlapping this period, then the intersecting period will be overwritten, without throwing exception. This behavior can surprise, but it is the same as when you write i=3. That will work in the same way, whether or not i previously contains a value.

Internally, the storage is based on a java.util.TreeMap.


Tutorial - 3 - Modeling temporal associations with non-unary cardinality

Suppose now another classic scenario. You have an Employee and many Skill(s).

Conceptually, it looks like this:


The only difference with the previous scenario is in the cardinality. The cardinality of [0,n] (called here "multi") applying to Skill requires a different mediator :

Currently, TreeTemporalSet is the only implementation of TemporalSet. Here, you still define a skill by calling put(period, skill), but now you get the set of skills active at a given instant by calling valueSet(instant).

Internally, TreeTemporalSet organizes the information in two main collections:
- a TreeTemporalAttribute (per value) to allow quick access to information related to a given value
- a HashMap (per endInstant) to allow quick access to information related to a given instant
Here you can see the TreeTemporalSet internal structure, but you do not need to know it unless you want to modify the source code.


Tutorial - 4 - Code sample

Suppose we have our employee again, with name, e-mail and skills that can change over the time.
Below you can see how this Employee class can look like.
A little working demo is included in the distribution zip file.

public class Employee {

    private TemporalAttribute name   = new TreeTemporalAttribute();
    private TemporalAttribute email  = new TreeTemporalAttribute();
    private TemporalSet       skills = new TreeTemporalSet();

    public String getName(FinalDate d) {
        return (String) name.get(d);

    public void setName(Period p, String s) {
        this.name.put(p, s);
    public String getEmail(FinalDate d) {
        return (String) email.get(d);

    public void setEmail(Period p, String s) {
        this.email.put(p, s);
    public Set getSkills(FinalDate d) {
        return (Set) this.skills.valueSet(d); 
    public void addSkill(Period p, Skill s) {
        this.skills.put(p, s);
    public void removeSkill(Period p, Skill s) {
        this.skills.remove(p, s);
    public boolean hasSkill(FinalDate d, Skill s) {
        return this.skills.contains(d, s); 

    public String toString(FinalDate d) {
        String ret = "Employee as of " + d + ":"
            + "\n\tName  : " + this.getName(d)
            + "\n\te-mail: " + this.getEmail(d)
            + "\n\tskills: " + this.getSkills(d);
        return ret;
welcome tutorial coming features javadoc project page download thomas' home page
SourceForge.net Logo