ISO 8601 Timer Formats Reference
Complete reference for ISO 8601 date/time formats supported by the process engine.
Overview
The process engine supports three ISO 8601 timer formats:
- Time Date - Specific point in time (e.g., 2026-12-31T23:59:59Z)
- Time Duration - Relative duration (e.g., P7D = 7 days)
- Time Cycle - Recurring schedule (e.g., R/P1D = repeat every day)
Time Date Format
Schedule execution at a specific date and time.
Format
YYYY-MM-DDThh:mm:ss[.sss][±hh:mm|Z]
Components
| Component | Description | Example |
|---|---|---|
YYYY | 4-digit year | 2026 |
MM | 2-digit month (01-12) | 06 |
DD | 2-digit day (01-31) | 15 |
T | Date/time separator | T |
hh | 2-digit hour (00-23) | 14 |
mm | 2-digit minute (00-59) | 30 |
ss | 2-digit second (00-59) | 45 |
.sss | Milliseconds (optional) | .500 |
Z | UTC timezone | Z |
±hh:mm | Timezone offset | +01:00 or -05:00 |
Examples
<!-- UTC time -->
<bpmn:timeDate>2026-12-31T23:59:59Z</bpmn:timeDate>
<!-- With milliseconds -->
<bpmn:timeDate>2026-06-15T14:30:45.500Z</bpmn:timeDate>
<!-- With timezone offset (UTC+1) -->
<bpmn:timeDate>2026-01-01T00:00:00+01:00</bpmn:timeDate>
<!-- EST timezone (UTC-5) -->
<bpmn:timeDate>2026-03-20T09:00:00-05:00</bpmn:timeDate>
<!-- WAT timezone (UTC+1) -->
<bpmn:timeDate>2026-07-01T12:00:00+01:00</bpmn:timeDate>
Use Cases
- Product launches: Schedule at specific date/time
- Campaign starts: Begin at exact moment
- Maintenance windows: Start at scheduled time
- Contract effective dates: Activate at specific time
- Scheduled reports: Generate at exact time
- End of promotion: Expire at specific time
Common Patterns
<!-- New Year process -->
<bpmn:timeDate>2027-01-01T00:00:00Z</bpmn:timeDate>
<!-- Quarter end reporting -->
<bpmn:timeDate>2026-03-31T23:59:59Z</bpmn:timeDate>
<!-- Business day start (9 AM local time) -->
<bpmn:timeDate>2026-06-15T09:00:00+01:00</bpmn:timeDate>
<!-- End of business day (5 PM local time) -->
<bpmn:timeDate>2026-06-15T17:00:00+01:00</bpmn:timeDate>
Time Duration Format
Specify relative duration from current time or task start.
Format
P[n]Y[n]M[n]DT[n]H[n]M[n]S
Components
| Component | Description | Example |
|---|---|---|
P | Period designator (required) | P |
Y | Years | 1Y |
M | Months (before T) | 3M |
W | Weeks | 2W |
D | Days | 7D |
T | Time separator | T |
H | Hours (after T) | 2H |
M | Minutes (after T) | 30M |
S | Seconds (after T) | 45S |
Examples
Minutes
<!-- 15 minutes -->
<bpmn:timeDuration>PT15M</bpmn:timeDuration>
<!-- 30 minutes -->
<bpmn:timeDuration>PT30M</bpmn:timeDuration>
<!-- 45 minutes -->
<bpmn:timeDuration>PT45M</bpmn:timeDuration>
Hours
<!-- 1 hour -->
<bpmn:timeDuration>PT1H</bpmn:timeDuration>
<!-- 2 hours -->
<bpmn:timeDuration>PT2H</bpmn:timeDuration>
<!-- 12 hours -->
<bpmn:timeDuration>PT12H</bpmn:timeDuration>
<!-- 24 hours (1 day can also use P1D) -->
<bpmn:timeDuration>PT24H</bpmn:timeDuration>
<!-- 2 hours 30 minutes -->
<bpmn:timeDuration>PT2H30M</bpmn:timeDuration>
Days
<!-- 1 day -->
<bpmn:timeDuration>P1D</bpmn:timeDuration>
<!-- 3 days -->
<bpmn:timeDuration>P3D</bpmn:timeDuration>
<!-- 7 days (1 week) -->
<bpmn:timeDuration>P7D</bpmn:timeDuration>
<!-- 14 days (2 weeks) -->
<bpmn:timeDuration>P14D</bpmn:timeDuration>
<!-- 30 days -->
<bpmn:timeDuration>P30D</bpmn:timeDuration>
<!-- 1 day 12 hours -->
<bpmn:timeDuration>P1DT12H</bpmn:timeDuration>
Weeks
<!-- 1 week -->
<bpmn:timeDuration>P1W</bpmn:timeDuration>
<!-- 2 weeks -->
<bpmn:timeDuration>P2W</bpmn:timeDuration>
<!-- 4 weeks -->
<bpmn:timeDuration>P4W</bpmn:timeDuration>
Months
<!-- 1 month -->
<bpmn:timeDuration>P1M</bpmn:timeDuration>
<!-- 3 months (quarter) -->
<bpmn:timeDuration>P3M</bpmn:timeDuration>
<!-- 6 months (half year) -->
<bpmn:timeDuration>P6M</bpmn:timeDuration>
<!-- 1 year (12 months) -->
<bpmn:timeDuration>P12M</bpmn:timeDuration>
Years
<!-- 1 year -->
<bpmn:timeDuration>P1Y</bpmn:timeDuration>
<!-- 2 years -->
<bpmn:timeDuration>P2Y</bpmn:timeDuration>
<!-- 5 years -->
<bpmn:timeDuration>P5Y</bpmn:timeDuration>
Complex Durations
<!-- 1 year 6 months -->
<bpmn:timeDuration>P1Y6M</bpmn:timeDuration>
<!-- 2 days 3 hours 30 minutes -->
<bpmn:timeDuration>P2DT3H30M</bpmn:timeDuration>
<!-- 1 month 2 weeks 3 days -->
<bpmn:timeDuration>P1M2W3D</bpmn:timeDuration>
<!-- 1 day 12 hours 30 minutes 45 seconds -->
<bpmn:timeDuration>P1DT12H30M45S</bpmn:timeDuration>
Use Cases by Duration
Short Durations (Minutes to Hours)
- API timeouts: PT30S, PT1M, PT5M
- User notifications: PT15M (15 min reminder)
- Session expiry: PT30M (30 min session)
- Retry delays: PT1M, PT5M, PT15M
Medium Durations (Days to Weeks)
- User task timeouts: P1D, P3D, P7D
- Approval deadlines: P2D, P5D
- Payment grace periods: P7D, P14D, P30D
- Document review: P3D, P7D
Long Durations (Months to Years)
- Contract reviews: P3M, P6M, P1Y
- License renewals: P1Y, P2Y, P3Y
- Loan maturity: P1Y, P5Y, P10Y
- Subscription renewals: P1M, P3M, P1Y
Duration Calculation
The engine calculates durations from:
- Timer start events: From when process starts
- Intermediate timer events: From when flow reaches timer
- Boundary timer events: From when task starts
Example:
Task starts: 2026-06-15 10:00:00
Timer duration: P1DT2H30M (1 day 2 hours 30 minutes)
Timer fires: 2026-06-16 12:30:00
Time Cycle Format
Define recurring schedules using cron or repeat patterns.
Format
R[n]/[duration or cron]
Components
| Component | Description | Example |
|---|---|---|
R | Repeat designator | R |
n | Number of repetitions (optional, infinite if omitted) | 3 |
/ | Separator | / |
| Duration | ISO 8601 duration | PT1H |
| Cron | Cron expression | 0 2 * * * |
Repeat with Duration
<!-- Repeat every hour (infinite) -->
<bpmn:timeCycle>R/PT1H</bpmn:timeCycle>
<!-- Repeat every 30 minutes (infinite) -->
<bpmn:timeCycle>R/PT30M</bpmn:timeCycle>
<!-- Repeat every day (infinite) -->
<bpmn:timeCycle>R/P1D</bpmn:timeCycle>
<!-- Repeat every week (infinite) -->
<bpmn:timeCycle>R/P1W</bpmn:timeCycle>
<!-- Repeat 3 times with 1 hour interval -->
<bpmn:timeCycle>R3/PT1H</bpmn:timeCycle>
<!-- Repeat 5 times daily -->
<bpmn:timeCycle>R5/P1D</bpmn:timeCycle>
Cron Expression Format
minute hour day month dayOfWeek
| Field | Values | Description |
|---|---|---|
| minute | 0-59 | Minute of hour |
| hour | 0-23 | Hour of day (24-hour) |
| day | 1-31 | Day of month |
| month | 1-12 | Month of year |
| dayOfWeek | 0-6 | Day of week (0 = Sunday) |
Cron Special Characters
| Character | Meaning | Example |
|---|---|---|
* | Any value | * = every |
, | List of values | 1,3,5 = 1st, 3rd, 5th |
- | Range of values | 1-5 = 1 through 5 |
/ | Step values | */15 = every 15 |
Cron Examples
Daily Schedules
<!-- Every day at 2 AM -->
<bpmn:timeCycle>0 2 * * *</bpmn:timeCycle>
<!-- Every day at midnight -->
<bpmn:timeCycle>0 0 * * *</bpmn:timeCycle>
<!-- Every day at 9 AM -->
<bpmn:timeCycle>0 9 * * *</bpmn:timeCycle>
<!-- Every day at 5 PM -->
<bpmn:timeCycle>0 17 * * *</bpmn:timeCycle>
<!-- Every day at noon -->
<bpmn:timeCycle>0 12 * * *</bpmn:timeCycle>
Hourly Schedules
<!-- Every hour at minute 0 -->
<bpmn:timeCycle>0 * * * *</bpmn:timeCycle>
<!-- Every hour at minute 30 -->
<bpmn:timeCycle>30 * * * *</bpmn:timeCycle>
<!-- Every 15 minutes -->
<bpmn:timeCycle>*/15 * * * *</bpmn:timeCycle>
<!-- Every 30 minutes -->
<bpmn:timeCycle>*/30 * * * *</bpmn:timeCycle>
Weekly Schedules
<!-- Every Monday at 9 AM -->
<bpmn:timeCycle>0 9 * * 1</bpmn:timeCycle>
<!-- Every Friday at 5 PM -->
<bpmn:timeCycle>0 17 * * 5</bpmn:timeCycle>
<!-- Monday to Friday at 9 AM -->
<bpmn:timeCycle>0 9 * * 1-5</bpmn:timeCycle>
<!-- Weekend (Saturday and Sunday) at noon -->
<bpmn:timeCycle>0 12 * * 0,6</bpmn:timeCycle>
<!-- Every Wednesday at 2 PM -->
<bpmn:timeCycle>0 14 * * 3</bpmn:timeCycle>
Monthly Schedules
<!-- 1st of every month at midnight -->
<bpmn:timeCycle>0 0 1 * *</bpmn:timeCycle>
<!-- 15th of every month at 9 AM -->
<bpmn:timeCycle>0 9 15 * *</bpmn:timeCycle>
<!-- Last day of month (31st, may not work all months) -->
<bpmn:timeCycle>0 0 31 * *</bpmn:timeCycle>
<!-- 1st and 15th of every month at noon -->
<bpmn:timeCycle>0 12 1,15 * *</bpmn:timeCycle>
Quarterly Schedules
<!-- First day of quarter (Jan, Apr, Jul, Oct) at midnight -->
<bpmn:timeCycle>0 0 1 1,4,7,10 *</bpmn:timeCycle>
<!-- End of quarter (Mar, Jun, Sep, Dec) at 11:59 PM -->
<bpmn:timeCycle>59 23 31 3,6,9,12 *</bpmn:timeCycle>
Business Hours
<!-- Every weekday hour from 9 AM to 5 PM -->
<bpmn:timeCycle>0 9-17 * * 1-5</bpmn:timeCycle>
<!-- Every weekday at 9 AM, noon, and 5 PM -->
<bpmn:timeCycle>0 9,12,17 * * 1-5</bpmn:timeCycle>
Cron Use Cases
| Use Case | Cron Expression | Description |
|---|---|---|
| Daily batch job | 0 2 * * * | 2 AM every day |
| Hourly sync | 0 * * * * | Every hour |
| Weekly report | 0 9 * * 1 | Monday 9 AM |
| Monthly invoice | 0 0 1 * * | 1st of month |
| Quarterly review | 0 0 1 1,4,7,10 * | Quarter start |
| Business hours | 0 9-17 * * 1-5 | Weekdays 9-5 |
| Every 15 min | */15 * * * * | 4 times per hour |
| End of day | 0 17 * * 1-5 | Weekdays 5 PM |
Dynamic Timers
Use context variables in timer expressions:
Duration Variables
<!-- Set timeout dynamically -->
<bpmn:scriptTask id="SetTimeout" name="Set Timeout">
<bpmn:script>
if (context.priority === 'HIGH') {
context.timeoutHours = 2;
} else if (context.priority === 'MEDIUM') {
context.timeoutHours = 4;
} else {
context.timeoutHours = 24;
}
</bpmn:script>
</bpmn:scriptTask>
<!-- Use variable in timer -->
<bpmn:boundaryEvent id="DynamicTimeout"
attachedToRef="ProcessTask"
cancelActivity="true">
<bpmn:timerEventDefinition>
<bpmn:timeDuration xsi:type="bpmn:tFormalExpression">
PT${context.timeoutHours}H
</bpmn:timeDuration>
</bpmn:timerEventDefinition>
</bpmn:boundaryEvent>
Date Variables
<!-- Calculate date dynamically -->
<bpmn:scriptTask id="CalculateDate" name="Calculate Date">
<bpmn:script>
// Schedule 3 days from now
var scheduledDate = new Date();
scheduledDate.setDate(scheduledDate.getDate() + 3);
context.scheduledDate = scheduledDate.toISOString();
</bpmn:script>
</bpmn:scriptTask>
<!-- Use variable in timer -->
<bpmn:intermediateCatchEvent id="ScheduledTimer" name="Scheduled">
<bpmn:timerEventDefinition>
<bpmn:timeDate xsi:type="bpmn:tFormalExpression">
${context.scheduledDate}
</bpmn:timeDate>
</bpmn:timerEventDefinition>
</bpmn:intermediateCatchEvent>
Common Durations Quick Reference
| Duration | ISO 8601 Format | Use Case |
|---|---|---|
| 30 seconds | PT30S | API timeout |
| 1 minute | PT1M | Short retry |
| 5 minutes | PT5M | Session warning |
| 15 minutes | PT15M | Quick reminder |
| 30 minutes | PT30M | Session expiry |
| 1 hour | PT1H | SLA warning |
| 2 hours | PT2H | Priority response |
| 4 hours | PT4H | SLA breach |
| 12 hours | PT12H | Half-day wait |
| 1 day | P1D | Standard wait |
| 3 days | P3D | Document review |
| 1 week | P7D or P1W | Approval timeout |
| 2 weeks | P14D or P2W | Extended deadline |
| 1 month | P1M or P30D | Grace period |
| 3 months | P3M or P90D | Quarterly |
| 6 months | P6M or P180D | Half-year |
| 1 year | P1Y or P365D | Annual |
Validation Rules
Valid Formats
<!-- ✅ Valid time date -->
<bpmn:timeDate>2026-12-31T23:59:59Z</bpmn:timeDate>
<!-- ✅ Valid duration -->
<bpmn:timeDuration>P7D</bpmn:timeDuration>
<!-- ✅ Valid cycle -->
<bpmn:timeCycle>R/PT1H</bpmn:timeCycle>
<bpmn:timeCycle>0 2 * * *</bpmn:timeCycle>
<!-- ✅ Dynamic expression -->
<bpmn:timeDuration xsi:type="bpmn:tFormalExpression">
P${context.days}D
</bpmn:timeDuration>
Invalid Formats
<!-- ❌ Invalid: Missing T separator -->
<bpmn:timeDuration>P1D2H</bpmn:timeDuration>
<!-- Should be: P1DT2H -->
<!-- ❌ Invalid: Plain text -->
<bpmn:timeDuration>1 day</bpmn:timeDuration>
<!-- Should be: P1D -->
<!-- ❌ Invalid: Wrong order -->
<bpmn:timeDuration>PT1H2D</bpmn:timeDuration>
<!-- Should be: P2DT1H -->
<!-- ❌ Invalid: Month after T -->
<bpmn:timeDuration>PT1M</bpmn:timeDuration> <!-- This is 1 minute -->
<!-- For 1 month, use: P1M -->
<!-- ❌ Invalid: Incomplete date -->
<bpmn:timeDate>2026-12-31</bpmn:timeDate>
<!-- Should be: 2026-12-31T00:00:00Z -->
Best Practices
✅ Do This
<!-- ✅ Use UTC for absolute times -->
<bpmn:timeDate>2026-12-31T23:59:59Z</bpmn:timeDate>
<!-- ✅ Use clear, readable durations -->
<bpmn:timeDuration>P7D</bpmn:timeDuration> <!-- 7 days -->
<!-- ✅ Use cron for recurring schedules -->
<bpmn:timeCycle>0 2 * * *</bpmn:timeCycle> <!-- Daily at 2 AM -->
<!-- ✅ Use duration for relative waits -->
<bpmn:timeDuration>P1D</bpmn:timeDuration> <!-- Wait 1 day from now -->
<!-- ✅ Document complex expressions -->
<!-- Wait 2 days 3 hours 30 minutes -->
<bpmn:timeDuration>P2DT3H30M</bpmn:timeDuration>
❌ Don't Do This
<!-- ❌ Don't use very short durations -->
<bpmn:timeDuration>PT5S</bpmn:timeDuration> <!-- 5 seconds - use sync logic -->
<!-- ❌ Don't use ambiguous formats -->
<bpmn:timeDuration>PT90M</bpmn:timeDuration> <!-- Use PT1H30M instead -->
<!-- ❌ Don't use very long durations -->
<bpmn:timeDuration>P10Y</bpmn:timeDuration> <!-- 10 years - reconsider design -->
<!-- ❌ Don't forget timezone for dates -->
<bpmn:timeDate>2026-12-31T23:59:59</bpmn:timeDate> <!-- Add Z or offset -->
Related Documentation
- Timer Events - Timer event patterns
- Scheduled Tasks - Batch job patterns
- User Task Timeouts - User task timeouts
- Error Recovery - Retry with delays
Features Used:
- Phase 4: Timer Events
Status: ✅ Production Ready
Version: 2.0
Last Updated: January 2026