Duration Units and Conversion
Gantt stores duration, remainingDuration, and task workHours in one canonical unit: hours. durationUnit controls Duration, Remaining Duration, and Duration Variance; workUnit independently controls Work. These unit fields affect display and editing, not storage. Different tasks can therefore retain different display units in the same column:
grid.source = [ { id: 'review', name: 'Review', startDate: '2026-04-06T09:00:00Z', duration: 5, durationUnit: 'hour', workHours: 16, workUnit: 'day' }, // 5 hours, 2 days Work { id: 'build', name: 'Build', startDate: '2026-04-07', duration: 16, durationUnit: 'day', workHours: '40h' }, // 2 days, 40 hours Work { id: 'release', name: 'Release train', startDate: '2026-04-09', duration: 120, durationUnit: 'week' }, // renders 3 weeks { id: 'handoff', name: 'Handoff', startDate: '2026-04-30T16:00:00Z', duration: 0.5, durationUnit: 'minute' }, // renders 30 minutes];The managed Duration, Remaining Duration, Duration Variance, Work, tooltip, task editor, and Excel export surfaces include the unit label, with singular/plural output such as 1 hour, 5 hours, 1 day, and 2 days.
DurationUnit
Section titled “DurationUnit”type DurationUnit = | 'minute' | 'hour' | 'day' | 'week' | 'month' | 'quarter' | 'year';Minutes are supported. Persist new numeric data as canonical hours and include durationUnit when a particular display unit must be retained. At source hydration only, legacy unitless numeric values remain supported as day-based values (or the configured fixed default); hydrated task-store data is converted to hours.
When durationUnit is omitted and defaultUnit is auto (the default), the table chooses a readable display unit: values below one working hour use minutes, values below one working day use hours, and longer values use days. Work follows the same rule through workUnit and defaultWorkUnit. A unit entered by the user is retained, so 5 hrs and 2 days can coexist.
Flexible input
Section titled “Flexible input”The inline grid editor and Task Information editor accept a number followed by a short or long unit:
| Input | Meaning |
|---|---|
| 30m, 30 min, 30 mins | 30 working minutes |
| 5h, 5 hr, 5 hrs | 5 working hours |
| 2d, 2 days | 2 working days |
| 3w, 3 wk, 3 wks | 3 working weeks |
| 2mo, 2 months | 2 working months |
| 1q, 1 quarter | 1 working quarter |
| 1y, 1 year | 1 working year |
A bare Duration or Remaining Duration edit uses the task's retained durationUnit, then defaultUnit, then days. A bare Work edit uses workUnit, then defaultWorkUnit, then hours. Every accepted edit is converted to hours before the task store is updated. Invalid or negative text is rejected. Work is person-time, so elapsed forms such as 2ed are rejected for Work even though they are valid for task Duration.
Conversion settings
Section titled “Conversion settings”Set project-wide conversion values with gantt.durationSettings:
grid.gantt = { ...project, durationSettings: { defaultUnit: 'auto', // or fix: 'minute' | 'hour' | 'day' | ... defaultWorkUnit: 'auto', // independent fixed/automatic Work unit hoursPerDay: 8, hoursPerWeek: 40, daysPerMonth: 20, maximumFractionDigits: 1, // default MSP-style compact precision },};With these settings:
1 day = 8 hours1 week = 40 hours = 5 working days1 month = 20 working days1 quarter = 3 working months1 year = 12 working months
defaultUnit and defaultWorkUnit can be fixed independently, matching the distinction between task span and person-work. Both default to auto. hoursPerDay defaults to the effective task calendar's hoursPerDay, then 8. hoursPerWeek defaults to hoursPerDay × workingDays.length, commonly 40. daysPerMonth defaults to 20.
maximumFractionDigits controls rendered precision for Duration, Remaining Duration, Duration Variance, and Work. It defaults to 1, trims trailing zeroes, and only affects presentation: 56.625 days renders as 56.6 days, while canonical stored hours are unchanged. Set it to 0 for whole units or a larger integer when a project needs more visible precision.
Changing hoursPerDay or hoursPerWeek changes conversion at edit, render, and scheduling boundaries. It does not rewrite stored hours and does not redefine the calendar's workingDays, holidays, or workingHours; configure those separately on CalendarEntity.
Working time and elapsed time
Section titled “Working time and elapsed time”Normal units consume working time. With an 8-hour day, 2d is normally 16 working hours. When scheduling.excludeHolidaysFromDuration is enabled, the scheduler also skips closed weekdays, holidays, and configured intraday working-hour gaps.
Elapsed input uses an e prefix and runs continuously, ignoring the working calendar:
{ duration: 48, durationUnit: 'day', durationIsElapsed: true } // renders 2 elapsed daysThe same value can be entered as 2ed or 2 elapsed days. 2d means two working days; 2ed means 48 continuous hours and can cross nights, weekends, and holidays. Elapsed aliases are supported for every DurationUnit, such as 30em, 4eh, and 1ew.
Summary tasks
Section titled “Summary tasks”Summary duration is derived from the earliest scheduled child start to the latest scheduled child finish. It is a span, not the sum of child durations. Summary Duration cells remain read-only even when their children use mixed units.
Milestones and zero duration
Section titled “Milestones and zero duration”Setting a task's Duration to 0 schedules and renders it as a milestone. Unlike a derived summary Duration, the milestone Duration cell remains editable. Entering any positive value, such as 4h or 2d, stores the converted canonical hours and changes the task type back to task. The same reversible behavior applies in the Task Information dialog.
Programmatic helpers
Section titled “Programmatic helpers”The Enterprise package exports shared date-layer helpers used by source hydration, scheduling, editors, and projection. Duration parsing, conversion, and formatting live in one module, so every integration follows the same canonical-hour rules:
import { parseDuration, formatDurationValue, durationToHours, hoursToDuration, durationToElapsedHours, elapsedHoursToDuration, resolveDurationSettings,} from '@revolist/revogrid-enterprise';Use these helpers in custom editors or persistence adapters instead of implementing a second unit conversion table.