Skip to Content
Evaluate Get Started

Work Calendar

A timer that expires after "2 days" does not always mean 48 hours. In business workflows, a 2-day approval deadline means 2 working days - excluding weekends, holidays, and after-hours time. Without a calendar, every timer with a business deadline needs custom code to skip non-working time.

A Work Calendar defines which days and hours count as working time. Timers that use calendar-aware interval units - whours, wdays, wminutes - skip non-working time automatically. You define the calendar once, and every timer in every workflow respects it.

With a Work Calendar, you can set a timer to "4 whours" and know it fires after 4 hours of actual working time, not 4 wall-clock hours. For example, a "2 wdays" timer started at 17:00 on Friday fires at 10:00 on Tuesday (assuming 9-to-6, Monday-to-Friday), skipping the weekend entirely.

What it is

A Work Calendar defines when work happens and when it does not. You specify the start of the workday, the number of working hours per day, which days of the week are weekends, and which specific dates are holidays. The timer subsystem then counts only working time when a calendar-aware interval is used.

Think of it as a business-day calendar you hang on the wall: "Monday to Friday, 9 AM to 6 PM, closed on public holidays." Any timer set in working hours, working days, or working months follows this calendar - non-working time simply does not count toward the deadline.

When a timer interval is specified in calendar-aware units, the runtime computes the elapsed time using only the working periods defined in the calendar. Regular time units (hours, days, minutes) always use wall-clock time and ignore the calendar.

For developers: Implement the ICalendar interface from OptimaJet.Workflow.Core.Runtime.Calendars or use the built-in Calendar class with chainable configuration via extension methods. Register calendars with runtime.WithCalendars(...) and set a default with runtime.SetDefaultCalendar(...). The runtime resolves which calendar to use in this order: process instance calendar, then scheme calendar, then runtime default calendar.

using OptimaJet.Workflow.Core.Runtime;using OptimaJet.Workflow.Core.Runtime.Calendars;// Use the built-in Calendar class with chainable setupvar calendar = Calendar.Create("StandardBusiness")    .SetStartOfWork(new TimeSpan(9, 0, 0))    .SetWorkingHours(new TimeSpan(8, 0, 0))    .SetWeekends(DayOfWeek.Saturday, DayOfWeek.Sunday);// Register with the runtime and set as defaultruntime.WithCalendars(calendar);runtime.SetDefaultCalendar(calendar.Name);

Calendar-aware interval units

The following interval units trigger calendar-aware calculation. Any interval value that uses one of these units is evaluated against the assigned Work Calendar.

Calendar-aware interval units
UnitAliasesExampleMeaning
Working hourswhours, whour, wh4 whours4 hours of working time
Working dayswdays, wday, wd2 wdays2 full working days
Working minuteswminutes, wminute, wm30 wminutes30 minutes of working time
Working monthswmonths, wmonth, wmm1 wmonth1 calendar month of working days
Working yearswyears, wyear, wy1 wyear1 calendar year of working days

Calendar-aware and regular time units cannot be combined in a single interval value. The runtime throws an ArgumentException if they are mixed.

Calendar resolution

The runtime resolves which Work Calendar to use in this order: process instance calendar > scheme calendar > runtime default calendar. If a process instance has a CalendarName set, that calendar is used. If not, the scheme's CalendarName is checked. If neither is set, the runtime's DefaultCalendarName applies. This lets you use different calendars per tenant, per workflow type, or per individual instance.

Custom calendars

For advanced cases, implement the ICalendar interface directly. The interface requires you to define working days, working hours, and methods for finding workday boundaries and calculating working time ranges. You can also define per-year holiday overrides using the Year class, specifying which dates are holidays or extra workdays for a specific year.

Why it matters

A Work Calendar delivers these outcomes:

  • Accurate business-time deadlines - SLA timers, approval escalations, and contract expiry dates count only working time. A "3 wdays" approval timer always means 3 business days, regardless of weekends or holidays.
  • No custom date arithmetic - Without a calendar, every timer-based workflow needs custom code to skip weekends and holidays. The calendar eliminates this code entirely.
  • Per-tenant or per-process calendars - Different business units or tenants can use different calendars. An APAC team can use one calendar while an EMEA team uses another, even in the same runtime.
  • Holiday-aware scheduling - Public holidays defined in Year objects are automatically excluded. No need to update scheduling logic when holiday dates change each year.

Who it is for

Evaluator (CEO, CTO, PM): A Work Calendar ensures that time-sensitive workflows match how your business actually operates - weekends and holidays are skipped, SLAs are measured in business time, and no custom code is needed to handle regional differences.

Developer: Define a calendar once with the built-in Calendar class, register it with runtime.WithCalendars(...), and use w -prefixed timer units in your scheme. The timer subsystem handles the rest.

Enterprise architect: Calendar resolution flows from instance to scheme to runtime default, supporting multi-tenant deployments with different business calendars. Year-level holiday overrides let you plan known non-working days in advance.

When to use it

Use a Work Calendar whenever a timer interval must align with business availability:

  • Approval escalation timers - An approval that auto-escalates after 4 working hours should not escalate on Saturday afternoon. The calendar skips non-working time automatically.
  • Service-level agreements - An SLA measured in business days that starts at 16:00 on a Friday should fire on Tuesday, not Sunday. A Work Calendar makes this the default behavior.
  • Scheduled notifications - A notification that should only fire during business hours needs no custom time-of-day checks. Calendar-aware timers handle the filtering.
  • Multi-region deployments - Each region gets its own calendar with different holidays and working hours. The runtime default calendar applies when neither instance nor scheme specifies one.

How it compares

The table below compares using a Work Calendar with the alternative of custom date arithmetic.

Comparison of work calendar approaches
ApproachWhat it requiresResult
Custom date arithmeticWrite skip-weekend logic, maintain holiday tables, update for each new workflowFragile, duplicated code that must be maintained across every timer-based workflow
Workflow Engine Work CalendarDefine a calendar once, register it with the runtime, use whours/wdays units in timer intervalsAutomatic exclusion of non-working time for every timer, configurable per process, scheme, or runtime

The calendar approach removes the code and maintenance burden of date arithmetic. Every timer in every workflow automatically respects the same calendar rules.

Frequently asked questions

What timer interval units are calendar-aware?

The calendar-aware units are whours, wdays, wminutes, wmonths, and wyears (with short aliases like wh, wd, wm, wmm, wy). Regular hours, days, minutes, months, and years use wall-clock time and ignore the calendar.

How do I assign different calendars to different process instances?

Set the CalendarName parameter on the process instance. The runtime resolves the calendar in this order: process instance calendar first, then scheme calendar, then runtime default calendar. This lets you assign calendars per tenant, per workflow type, or per individual instance.

What happens if I mix calendar-aware and regular time units in one interval?

The system throws an ArgumentException. Calendar-aware and regular time units cannot be combined in a single interval value. Use either calendar units (prefixed with w) or regular units, not both.

Do I need special licensing for the Work Calendar feature?

No. The ICalendar interface and the built-in Calendar class are part of the core runtime and available in all editions.

See also