[Canonical page](<https://docs.dhtmlx.com/planning-engine/java/how-to/load-all-task-dates/>)
[Full documentation index](<https://docs.dhtmlx.com/planning-engine/llms.txt>)


# Load all task dates

Get the start, end and duration of every scheduled task from one solve, for example to fill your UI when a project first opens.

By default, `updates` in a [`ScheduleResult`](<https://docs.dhtmlx.com/planning-engine/java/api/results/schedule-result.md>) is sparse: it lists only the tasks that moved. Set [`SolveOptions.includeUnchanged`](<https://docs.dhtmlx.com/planning-engine/java/api/project/solve-options.md#includeunchanged>) and the same solve also reports the tasks that didn't move. You don't need a separate call.

## Steps

1. Build the solve options with `includeUnchanged` set to `true`:

   ```java
   var options = new SolveOptions().withIncludeUnchanged(true);
   ```

2. Pass the options to the solve that loads the data. Use [`Project#solve`](<https://docs.dhtmlx.com/planning-engine/java/api/project-solve.md>) with the data for a long-lived project, or [`Engine.schedule`](<https://docs.dhtmlx.com/planning-engine/java/api/engine-schedule.md>) for a one-shot job.

3. Read every entry of `result.updates`. Each [`Mutation`](<https://docs.dhtmlx.com/planning-engine/java/api/results/mutation.md>) has `startDate`, `endDate` and `duration` set.

The full example below schedules three tasks. `review` doesn't move, but it's still reported:

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

public class LoadAllTaskDates {
  static TaskData task(String id, Moment start, double duration) {
    return new TaskData(Id.str(id)).withStartDate(start).withDuration(duration);
  }

  public static void main(String[] args) throws Exception {
    var jan1 = Moment.fromYmdHm(2026, 1, 1, 0, 0);
    var jan5 = Moment.fromYmdHm(2026, 1, 5, 0, 0);

    var data = new ProjectData()
        .withTasks(List.of(
            task("design", jan1, 2.0),
            task("build", jan1, 1.0),
            task("review", jan5, 1.0)))
        .withLinks(List.of(
            new LinkData()
                .withId(Id.str("design-build"))
                .withSource(Id.str("design"))
                .withTarget(Id.str("build"))
                .withLinkType(LinkType.FS)));
    // 24/7 time keeps the example dates easy to check.
    data.config.useCalendars = false;

    var options = new SolveOptions().withIncludeUnchanged(true);

    var project = new Project();
    var result = project.solve(data, options);

    for (var m : result.updates) {
      System.out.println(m.id + " " + m.startDate + ".." + m.endDate + " " + m.duration);
    }
  }
}
```

## Get the full list from an already solved project

To reload every date later, call [`solve(null, ...)`](<https://docs.dhtmlx.com/planning-engine/java/api/project-solve.md>) with the same options. On a solved project with no pending edits, the call doesn't replan or change the accepted state, and `baselineId` stays the same:

```java
var allDates = project.solve(null, options);
```

Switch back to sparse results for the edits that follow. `new SolveOptions()` returns only what changed:

```java
var next = project.solve(null, new SolveOptions());
```

The result cache uses the whole [`SolveOptions`](<https://docs.dhtmlx.com/planning-engine/java/api/project/solve-options.md>) as its key, compared by value. An `includeUnchanged` call never gets a cached sparse result, and a sparse call never gets a cached full one.

## What is and isn't reported

- The result includes every scheduled task: leaf tasks, summaries and milestones. Check [`Mutation.kind`](<https://docs.dhtmlx.com/planning-engine/java/api/results/mutation.md#mutationkind>) (`MutationKind.TASK`, `SUMMARY`, `MILESTONE`) to tell them apart.
- Tasks with `unscheduled = true` are never reported.
- `levelingDelay` and `pauses` are always `null`, because a solve doesn't change them.
- `baselineId` follows real changes only. Asking for unchanged tasks doesn't create a new baseline.
- With [`subtree`](<https://docs.dhtmlx.com/planning-engine/java/how-to/reschedule-a-branch.md>), the result holds every task in the subtree, including the subtree tasks' ancestors. Tasks outside the subtree appear only when a sparse subtree solve would report them too, because they changed or were edited.
- On a project with a dependency cycle, nothing is scheduled. The result still lists every scheduled task, in model order, with its dates and duration as stored. `subtree` is ignored, and no entry has a `reason`, even with `reasons = true`.
- [`Project#preview`](<https://docs.dhtmlx.com/planning-engine/java/api/project-preview.md>) and [`Project#level`](<https://docs.dhtmlx.com/planning-engine/java/api/project-level.md>) always return sparse updates.

## Result

The example prints one line per task, including `review`, which didn't move (the lines may come in a different order):

```text
design 2026-01-01 00:00..2026-01-03 00:00 2.0
build 2026-01-03 00:00..2026-01-04 00:00 1.0
review 2026-01-05 00:00..2026-01-06 00:00 1.0
```

Without `includeUnchanged`, the same solve reports only `build`.

See [Reading results](<https://docs.dhtmlx.com/planning-engine/java/scheduling/reading-results.md>) for how to write the dates back into your model.
