Pause#

A gap in a task's work. at is the elapsed time from the task start to the start of the gap, and length is how long the gap lasts. Pauses go in TaskData.pauses and in TaskUpdate.pauses. Project#level writes them when it splits a task. Create one with new Pause(at, length) or Pause.leveling(at, length).

Declaration#

package org.dhtmlx.plen;

public class Pause extends ValueRecord implements DeepCloneable<Pause>

Every field is public and mutable, and has a withX(value) setter that assigns it and returns this. equals, hashCode and toString come from ValueRecord and compare at, length and by.

Constructors#

Pause(double, double)#

public Pause(double at, double length)

Creates a pause with by = null.

Name Type Description
at double Elapsed time from the task start to the pause start.
length double Elapsed length of the pause.

Fields#

Field Type Default Description
at double constructor argument Elapsed time from the task start to the pause start. Finite and >= 0.
length double constructor argument Elapsed length of the pause. Finite and > 0.
by PauseSource null Who wrote the pause. The leveler always sets PauseSource.LEVELING.

at, length#

public double at;
public double length;

public Pause withAt(double value)
public Pause withLength(double value)

Both values are elapsed (wall-clock) time in the task's durationUnit: a minute, an hour of 60 minutes, or a day of 24 hours. Fractions are allowed. When the task is scheduled, the pause occupies the whole minutes [round(at), round(at + length)). The two ends are rounded, not at and length on their own, so adjacent pauses never overlap after rounding. A pause that rounds to zero length is ignored.

A pause counts only while the task has work left after it. For how pauses shape a task's dates, see Leveling resources.

by#

public PauseSource by;

public Pause withBy(PauseSource value)

Optional on input. Every pause in a project counts as leveling-owned, whatever by holds. See LevelingOptions for how the leveler clears and extends pauses.

Static methods#

leveling#

public static Pause leveling(double at, double length)

Returns a pause with by = PauseSource.LEVELING, the same value the leveler writes.

Methods#

deepClone#

public Pause deepClone()

Returns a new pause with the same at, length and by.

copy#

public Pause copy()

Returns a shallow copy. A pause holds only a double pair and an enum, so the result equals deepClone().

PauseSource#

Who created a pause.

package org.dhtmlx.plen;

public enum PauseSource { LEVELING }
Value Description
LEVELING Created by resource leveling. The only value.

Errors#

A task's pause list is validated when the snapshot is passed to Engine.schedule or Project#solve(data, …). The call throws InputException with kind = InputErrorKind.VALIDATION and path = "tasks[i].pauses[j]" when pause j:

  • has an at that's negative, NaN or infinite
  • has a length that's <= 0, NaN or infinite
  • starts before the previous pause ends, so the list isn't sorted by at or two pauses overlap

at = 0 and adjacent pauses (one ends exactly where the next starts) are valid. The overlap check forgives floating-point error up to 1e-9 × max(1, end), where end is the previous pause's at + length. Minute-exact fractions such as 1.0/60 + 31.0/60 against 32.0/60 pass.

The list is validated on every task kind, but pauses have no effect on summaries, milestones and unscheduled tasks.

Validation.REPAIR clears an invalid list instead of throwing and records a Note.Repaired at tasks[i].pauses. Pause lists changed after the first solve go through TaskUpdate, which runs the same checks.

Example#

A three-day task that stops for a day, one day after it starts:

import java.util.List;
import org.dhtmlx.plen.*;

public class PauseExample {
    public static void main(String[] args) throws Exception {
        Moment start = Moment.fromYmdHm(2026, 4, 6, 8, 0);

        ProjectData data = new ProjectData()
                .withTasks(List.of(
                        new TaskData(Id.num(1))
                                .withStartDate(start)
                                .withDuration(3.0)
                                .withDurationUnit(TimeUnit.DAY)
                                .withPauses(List.of(Pause.leveling(1.0, 1.0)))));

        ScheduleResult result = Engine.schedule(data, new SolveOptions());
        for (Mutation update : result.updates) {
            System.out.println(update);
        }
    }
}