# PEPPOL-EN16931-F001: Write dates as plain YYYY-MM-DD with no time zone

Peppol dates must be exactly ten characters, `YYYY-MM-DD`. A time zone suffix such as `Z` or `+01:00` passes the XSD but fails this rule.

- Layer: Peppol BIS Billing
- Severity: fatal (the document is invalid)
- Topics: Core fields
- Official definition: https://docs.peppol.eu/poacc/billing/3.0/rules/ubl-peppol/PEPPOL-EN16931-F001/
- Explanation last updated: 2026-09-24

## The short answer

`PEPPOL-EN16931-F001` fails when a date element holds anything other than a ten-character `YYYY-MM-DD` value. In the recorded example the due date is `2026-10-08Z`; remove the time zone suffix and write `2026-10-08`.

The XSD does not catch this. The UBL date type allows an optional time zone, so `2026-10-08Z` and `2026-10-08+01:00` are both valid against the schema and only this Peppol rule rejects them.

## What the rule checks

The rule selects every element named `cbc:IssueDate`, `cbc:DueDate`, `cbc:TaxPointDate`, `cbc:StartDate`, `cbc:EndDate` or `cbc:ActualDeliveryDate`, wherever it sits, and reports each failing one at its own location. When tried, a time zone on a line period start date, on the delivery date and on the preceding invoice issue date inside `cac:BillingReference` was reported each time.

A value passes when it is exactly ten characters long and is a valid date. Anything longer fails, surrounding spaces included: when tried, ` 2026-10-08 ` passed the XSD, which collapses whitespace in a date, and failed this rule.

Values that are not dates at all, such as `08/10/2026` or `2026-10-08T00:00:00`, never get here. The XSD layer rejects them as schema errors, and the Peppol rules are skipped.

Elements outside that list are not checked. When tried, a credit note with `cac:PaymentMeans/cbc:PaymentDueDate` set to `2026-10-08Z` passed every layer, although the Peppol syntax page for that element lists this rule.

| Term | Meaning | UBL element |
|---|---|---|
| BT-2 | Invoice issue date | `cbc:IssueDate` |
| BT-9 | Payment due date | `cbc:DueDate (a credit note uses cac:PaymentMeans/cbc:PaymentDueDate, which this rule does not select)` |
| BT-7 | Value added tax point date | `cbc:TaxPointDate` |
| BT-72 | Actual delivery date | `cac:Delivery/cbc:ActualDeliveryDate` |
| BT-73 | Invoicing period start date | `cac:InvoicePeriod/cbc:StartDate` |
| BT-74 | Invoicing period end date | `cac:InvoicePeriod/cbc:EndDate` |
| BT-26 | Preceding Invoice issue date | `cac:BillingReference/cac:InvoiceDocumentReference/cbc:IssueDate` |

## How an integration ends up here

Possible causes, from the shape of the rule rather than from measured usage:

- Dates are serialised from a timestamp type, and the library appends `Z` or an offset because the value carries a time zone.
- An XML binding generated from the UBL schema maps `xs:date` to a calendar type that writes its time zone by default.
- The value is formatted with an ISO 8601 routine that adds the current offset, such as `+01:00` during British Summer Time.
- A template or a fixed-width source field pads the date with spaces or leaves a line break inside the element.

## How to fix it

1. Use the location in each finding to find the element. There is one finding per bad date, so the list is complete.
2. Take the calendar date in the business time zone of the invoice first, then drop the time, so that removing the suffix does not also move the date by a day.
3. Format it from a plain local date type, with no time and no zone, using an explicit four-digit year, two-digit month and two-digit day separated by hyphens.
4. Write the value with nothing else inside the element: no spaces, no line breaks.
5. Use the same formatter for every date in the document, including line periods, the delivery date, the preceding invoice issue date and the credit note due date, even though this rule does not check the last one.

## Before and after

These are fragments, not complete documents. The complete synthetic documents they come from are linked below.

Fragment of the failing invoice: the due date carries a Z time zone suffix

```xml
<cbc:ID>EXAMPLE-INV-001</cbc:ID>
<cbc:IssueDate>2026-09-08</cbc:IssueDate>
<cbc:DueDate>2026-10-08Z</cbc:DueDate>
<cbc:InvoiceTypeCode>380</cbc:InvoiceTypeCode>
```

Fragment of the corrected invoice: the due date is a plain date

```xml
<cbc:ID>EXAMPLE-INV-001</cbc:ID>
<cbc:IssueDate>2026-09-08</cbc:IssueDate>
<cbc:DueDate>2026-10-08</cbc:DueDate>
<cbc:InvoiceTypeCode>380</cbc:InvoiceTypeCode>
```

Only `cbc:DueDate` differs: `2026-10-08Z` in the failing invoice, `2026-10-08` in the corrected one. The failing document reports only `PEPPOL-EN16931-F001`; the XSD and EN 16931 layers both pass because a date with a time zone is still a valid `xs:date`.

### What the validator reported

- The failing invoice reports **PEPPOL-EN16931-F001**. The corrected document passes every layer with no findings.
  - [Download the failing XML](https://ironfang.uk/finance/rule-examples/PEPPOL-EN16931-F001-invalid.xml)
  - [Download the corrected XML](https://ironfang.uk/finance/rule-examples/invoice-minimal.xml)

Recorded on phive 12.1.0 / phive-rules-peppol 4.5.6 / Saxon-HE 12.10, the engine behind the free validator, using synthetic data. A recorded result is regression evidence for these documents; it is not a certification.

## Where it applies

- Applies to `Invoice` and `CreditNote`. When tried, a credit note issue date of `2026-09-08Z` was reported. A credit note has no root-level `cbc:DueDate`: adding one fails the XSD, and its due date belongs in `cac:PaymentMeans/cbc:PaymentDueDate`, which is outside this rule.
- A Peppol rule, reported in the Peppol layer only. The EN 16931 layer accepted every suffixed date that was tried.
- Dates the schema cannot read are reported as XSD schema errors, never as this rule.

## Related rules

- [BR-29 compares the invoicing period dates whose format this rule checks](https://ironfang.uk/docs/finance/rules/BR-29.md)
- [PEPPOL-EN16931-R110 compares line period start dates, another set of dates this rule formats](https://ironfang.uk/docs/finance/rules/PEPPOL-EN16931-R110.md)
- [BR-CO-03 decides whether a tax point date, one of the checked elements, may be sent at all](https://ironfang.uk/docs/finance/rules/BR-CO-03.md)

## Scope and source

Written for Peppol BIS Billing 3.0.21 (May 2026), EN 16931 1.3.16, as applied to UBL 2.1 Invoice and CreditNote documents. Other profiles, syntaxes and releases can define this identifier differently. Guidance version 2026-09-24.1: source checked 2026-09-24, explanation last updated 2026-09-24.

[The official definition of PEPPOL-EN16931-F001](https://docs.peppol.eu/poacc/billing/3.0/rules/ubl-peppol/PEPPOL-EN16931-F001/) carries the normative wording and test. This page is our explanation of it, not a copy.

Guidance does not change the engine verdict. Fixing this finding does not mean the document passes every layer, and validation does not certify legal or tax compliance or transmit a document over Peppol.

## Links

- [This rule as a web page](https://ironfang.uk/docs/finance/rules/PEPPOL-EN16931-F001)
- [Free Peppol invoice validator](https://ironfang.uk/tools/peppol-validator)
- [Rule index](https://ironfang.uk/docs/finance/rules.md)
- [Ironfang Finance API docs](https://ironfang.uk/docs/finance)
- The same rule is available to MCP clients as the tool `finance.rule.get` on https://mcp.ironfang.uk/mcp
