Functional Weave
Code in Rust

fleet.drivers-hours@1.0.1

README.md

4,340 bytes · view raw

# fleet.drivers-hours

Status: needs review by a drivers' hours / transport compliance expert before it is published.

Checks a driver's recorded activities against the driving-time and break
rules of Regulation (EC) No 561/2006, as it applies in Great Britain
(assimilated law, formerly "retained EU law"). It returns every breach it
finds, in time order, with the local date and time the limit was passed.

```
checkDriversHours("2026-09-21", "06:00", [
  { kind: "driving", minutes: 300 }, { kind: "rest", minutes: 45 }
])
// { compliant: false, drivingMinutes: 300,
//   breaches: [{ rule: "break", at: "2026-09-21T10:30", actual: 300, limit: 270 }] }
```

## Input

The activities are back to back from `startDate` and `startTime`: each one
starts when the previous one ends, as on a tachograph printout. `kind` is
`driving`, `work` (other work), `availability` (a period of availability) or
`rest` (any break or rest). Neighbouring activities of the same kind are
merged, so a rest recorded as 20 minutes then 25 minutes is one uninterrupted
45-minute break.

Times are local wall-clock time with no time zone or clock change handling.

## Rules checked

| rule | limit | meaning |
|------|-------|---------|
| `break` | 270 minutes | Art. 7: more than 4h30 of driving without a qualifying break. `actual` is the driving in that driving period, up to the break that ended it |
| `daily-driving` | 600 minutes | Art. 6(1): daily driving time over 10 hours |
| `daily-driving` | 540 minutes | Art. 6(1): a third (or later) day over 9 hours in one fixed week; `at` is when that day passed 9 hours |
| `weekly-driving` | 3360 minutes | Art. 6(2): over 56 hours in one fixed week |
| `fortnightly-driving` | 5400 minutes | Art. 6(3): over 90 hours in two consecutive fixed weeks; `at` falls in the second week |

How the activities are read:

- **A break** is a rest of at least 45 minutes, or a rest of at least 15
  minutes followed later by one of at least 30 (in that order: 30 then 15 does
  not count). Other work and periods of availability are not breaks. A
  15-minute rest before any driving in the period is not the first part of a
  split break, since it is not taken during the driving period.
- **A daily rest** is a rest of 9 hours or more. It ends the daily driving
  time (Art. 4(k)); a shorter rest, including the 3-hour first part of a split
  daily rest, does not.
- **Weeks** are fixed weeks, 00:00 Monday to 24:00 Sunday (Art. 4(i)).
  Driving that crosses Sunday midnight counts in both weeks, minute by minute.
  A day's 10-hour extension counts in the week its first driving falls in.
- **The end of the records** closes the last driving period and day, so
  records that stop mid-day are judged on what they show.

Whether daily and weekly *rest* was taken is a separate check:
`fleet.tachograph-rest`.

## What it does not do

- GB domestic drivers' hours rules (Transport Act 1968), AETR, or mixed
  domestic/EU days.
- Multi-manning, ferry or train crossings (Art. 9), the Art. 12 emergency
  departure, and the exemptions and national derogations (Art. 3 and 13).
- The working-time limits (Road Transport (Working Time) Regulations 2005),
  including the 6-hour work break rule.
- Weeks outside the records: the fortnightly check only adds up weeks it has
  data for, so pass the previous week's activities too if they matter.

## Data

The limits are dated rows in `data/limits.json`, effective from 11 April 2007
(Art. 29) and still in force. A date before that is an error.

## Sources

- Regulation (EC) No 561/2006, as it applies in the UK, legislation.gov.uk:
  Article 4 (definitions of break, rest, daily rest, week, daily driving time,
  driving period), Article 6 (9h/10h twice a week, 56h, 90h), Article 7
  (45 minutes after 4h30; 15 then 30), Article 29 (entry into force 11 April
  2007). https://www.legislation.gov.uk/eur/2006/561/contents
- DVSA, "Drivers' hours: Assimilated rules":
  https://www.gov.uk/drivers-hours/eu-rules
- DVSA, "Drivers' hours and tachographs: goods vehicles", section 1 (split
  break order 15 then 30, other work and availability are not breaks, fixed
  week): https://www.gov.uk/guidance/drivers-hours-goods-vehicles/1-eu-and-aetr-rules-on-drivers-hours

1.0.1 fixes Python accepting a trailing newline or non-ASCII digits in startDate and startTime; adds tests.