Incorrect duration calculation with unit='hour' and step=12

Hello everyone,

I’m using dhtmlxGantt configured with unit: "hour" and step: 12 , so task durations are effectively calculated in half-day units .

I’ve noticed that calculateDuration sometimes returns incorrect values, which then affects task behavior (especially during drag & drop).

Examples

With the following configuration (unit: "hour" , step: 12 ):

  • start_date: 01/01/2026 08:00:00
    end_date: 02/01/2026 08:00:00
    returned duration: 3 :x: (expected: 2)

  • start_date: 01/01/2026 08:00:00
    end_date: 01/01/2026 20:00:00
    returned duration: 1 :white_check_mark: (correct)

  • start_date: 01/01/2026 08:00:00
    end_date: 04/01/2026 08:00:00
    returned duration: 7 :x: (expected: 6)

Impact

This incorrect duration calculation affects internal gantt logic.
For example, during task drag operations, onTaskDrag appears to rely on calculateDuration . When the returned value is incorrect, the task duration unexpectedly changes after dragging.

Workaround

As a workaround, when I manually calculate durations, I normalize the dates by rounding the time to either 00:00:00 or 12:00:00 before calling calculateDuration .
This produces coherent results in my custom logic.

However, this doesn’t solve cases where calculateDuration is used internally by dhtmlxGantt, and the incorrect values still affect built-in behavior.

Question

Is this a known limitation or expected behavior when using unit: "hour" with step: 12 ?
Is there a recommended way to avoid or override this internal duration calculation to ensure consistent half-day results?

Thanks in advance for your help.

Hello Zaki,

Thank you for the provided details. I’ve investigated your issue and tested the configuration with unit: "hour" and step: 12.

I was able to implement half-day duration calculations successfully using two different approaches. Both work correctly, including during drag-and-drop operations.

So, perhaps, this issue is related to your configuration. Without more details, it’s difficult to say exactly what is going wrong in your case. It would be helpful if you could send me a simplified code snippet along with all the necessary instructions for running it, so that I can try to reproduce the issue and research a possible solution. Please make sure that the issue is reproduced here: DHTMLX - Gantt. Initialization.

Then, click on the Save button. After receiving the link, open it in another tab and check that everything is saved, and then send me this link. Alternatively, you can copy the code from the snippet and send it in a text file.

In any case, here are two approaches to how I implemented half-day duration calculations:

  1. Using Duration Formatter

With this approach, the durationFormatter extension allows you to manage how duration is stored and display it in units you need.
We initialize the Duration Formatter and connect it to the lightbox.:

const durationFormatter = gantt.ext.formatters.durationFormatter({
    enter: "day",
    store: "hour",
    format: "day",
    hoursPerDay: 12
});

gantt.config.lightbox.sections = [
    { name: "description", height: 70, map_to: "text", type: "textarea", focus: true },
    { name: "time", type: "duration", map_to: "auto", formatter: durationFormatter, time_format: ["%d", "%m", "%Y", "%H:%i"] }
];

gantt.config.columns = [
    // ... other columns
    {
        name: "duration", label: "Duration", resize: true, align: "center", template: function (task) {
            return durationFormatter.format(task.duration);
        }, width: 100,
    }
];

gantt.config.duration_unit = 'hour';
gantt.config.date_grid = "%d-%m-%Y %H:%i:%s";
gantt.config.round_dnd_dates = false;
  • hoursPerDay: 12 - defines that one “day” equals 12 hours
  • store: "hour" - tasks are stored internally in hours
  • enter/format: "day" - users see and enter durations as “days” (which are actually 12-hour periods)
  • duration_unit: 'hour' - base unit for calculations

Here’s a complete example: DHTMLX Snippet Tool.

  1. This approach directly uses the duration_step config with work time settings:
gantt.config.work_time = true;
gantt.config.correct_work_time = true;
gantt.setWorkTime({ hours: ["00:00-23:00"], days: [0, 1, 1, 1, 1, 1, 0] });

gantt.config.duration_unit = 'hour';
gantt.config.duration_step = 12;
gantt.config.round_dnd_dates = false;
  • duration_unit: 'hour' and duration_step: 12 - defines 12-hour calculation steps
  • work_time: true - enables work time calculations
  • setWorkTime() - configures working hours (0-23 to allow all hours) (Work Time Calculation | DHTMLX Gantt Docs)

You can not to enable work time if you don’t need it. It also works correctly without work time enabled.

Please check a full example: DHTMLX Snippet Tool.

1 Like

Hello Valeria,

Thank you very much for the detailed response.

I’ve finally found the source of the problem — I upgraded my dhtmlxGantt library version, and this resolved the issue for me.

I understand that I should always use the latest version, but this is a bit difficult in my case because I have different versions of my application to maintain. I still need to support older stable versions where an older dhtmlxGantt component is used, and migrating them would have a significant impact on the codebase.

I think the best long-term solution would be to drop the old application versions and focus on migrating everything to newer versions.

Thank you again for your help.
Have a nice day.

Best regards

1 Like

Hello Zaki,

Thank you for your feedback!

Yes, it’s recommended to migrate to the latest versions if possible as they include new features, bug fixes, performance improvements, etc.

If you do decide to plan a migration in the future, our documentation includes migration guides that can help you:
Migration from Older Versions | DHTMLX Gantt Docs.

In the meantime, if you encounter any other issues with either your current or newer versions, please feel free to reach out.

Have a good day!

Best regards,
Valeria Ivashkevich
DHTMLX Support Engineer