Skip to content

v0.3.0 — Hours per day are the hours a calendar's shifts work

Latest

Choose a tag to compare

@danafitkowski danafitkowski released this 10 Oct 17:35

A minor release. A calendar's hours per day are the hours its shifts work when every working day of its week works the same number of hours and day_hr_cnt says otherwise. That is how P6 schedules, measured on Primavera P6 Professional 23.12.1's own F9.

Changed

  • Hours per day come from the shifts when day_hr_cnt disagrees with all of them. P6 schedules a duration in hours against the calendar's shifts; day_hr_cnt ("Hours per Day") only converts hours to days for display. Scheduled with F9 on 10-Oct-2026, a Monday-Saturday 07:00-17:00 calendar declaring 8 ran a 40 h activity over four days. get_calendar_map divided by 8 and gave five; it now gives hours_per_day 10, and duration_hours_to_days('40', cal) gives 4.

    Each working day's hours are read from the DaysOfWeek block, in either P6 slot order, with a 00:00 finish read as the end of the day. A week whose working days work different hours keeps day_hr_cnt, and so does a calendar with no hours to read. The rule is the one cpp-cpm-engine v2.9.54's parseXER applies.

Added

  • declared_hours_per_day on such a calendar: the file's day_hr_cnt, as it was.
  • calendar_shift_hours(cal_map) lists those calendars.
  • CalendarShiftHoursWarning, raised once per such calendar.

What can move

hours_per_day on a calendar of that shape, and every conversion that reads it: duration_hours_to_days, the float generate_summary reports, and anything a caller computes from the map. Nothing moves on any other calendar.

Why a minor release. Before 1.0 this project moves the minor number for a release that changes results a caller already reads.

Testing

tests/test_calendar_shift_hours_2026_10_10.py has 7 synthetic tests. The three that pin the change fail on v0.2.1, and two more fail there because the function they call is new. pytest tests/ is 116 tests across 12 files: 115 pass and the engine-parity test skips, and all 116 pass with cpp-cpm-engine v2.9.54's python_reference on sys.path.

See CHANGELOG.md.