Skip to main content

Crate mako_fristen

Crate mako_fristen 

Source
Expand description

Every Frist in German market communication, in one leaf crate.

Deadlines are the regulatory asset this platform is built around, and this crate is the one answer to “when is this due”. It depends on nothing but time, so every service can read it without pulling in a workflow engine — which is what keeps the calendar, the per-Prüfidentifikator answer tables and the alerting from each carrying a copy that disagrees with the others.

QuestionAnswer
What is today’s date, in the market’s terms?heute, berlin_date, berlin_midnight, berlin_now
When is the 4th Werktag after this instant?add_werktage, deadline_at_werktage, end_of_werktag_after, next_werktag_at
Which window does PID 55001 carry?antwort
Which messages does receiving it oblige me to send?meldung
When must the CONTRL / APERAK go out?contrl_due_at, aperak_strom_due_at, aperak_gas_folgeprozess_due_at, aperak_gas_initialprozess_due_at

mako-engine re-exports this crate as mako_fristen, so existing call sites are unchanged.

§Three clocks, never one number

The mistake this crate is shaped to prevent is treating any of these as the others. They differ by orders of magnitude and they fail for different reasons.

ClockWindowMeaning
CONTRL6 wall-clock hours; 15 min for a Strom UTILMD/ORDERS Syntaxfehlermeldung (6 h on a Saturday), 45 min for a GABi-Gas ALOCAT; deferred to the end of a Formatumstellung window (CONTRL AHB 1.0 §2.3.1, §2.4.1)the syntax check of the Übertragungsdatei
APERAK45 min Strom weekday; Gas: next Werktag 12:00 (Folgeprozess) or 3 Werktage (Initialprozess)the message was accepted for processing
Antwortfristper PID — 11:00 of the 1. Werktag for a GPKE Anmeldung, 4 Werktage for a Gas Anmeldung, 3/5/7/1 WT for WiM Stromthe business answer is owed

There is no 24-hour GPKE window, under BK6-24-174 or anything else. The technical acknowledgement is 45 minutes (aperak_strom_due_at) and the business answer is a wall-clock instant on the first Werktag after the Übertragungstag (mako-pruefung). A flat 24 h is neither, and it is wrong in the direction that does not announce itself: it reports a lapsed Frist as still running.

§Werktage

use mako_fristen::{self as fristen, HolidayCalendar};
use time::{Date, Month};

// 5 Werktage after Monday 2025-01-06:
let start = Date::from_calendar_date(2025, Month::January, 6).unwrap();
let due   = fristen::add_werktage(start, 5, HolidayCalendar::BdewMaKo);
// Tue 07, Wed 08, Thu 09, Fri 10, Mon 13 → 2025-01-13
// (Saturday and Sunday are not Werktage in market communication)
assert_eq!(due, Date::from_calendar_date(2025, Month::January, 13).unwrap());

§Holiday calendar: BDEW-defined, Germany-wide

HolidayCalendar::BdewMaKo is the single holiday calendar used in all BNetzA MaKo processes. BDEW EDI@Energy specifies a conservative-inclusive approach: every public holiday observed in any German state is treated as a non-Werktag. This guarantees no Frist is ever shorter than the AHB requires. Per-state calendars are not used in BDEW MaKo.

§CONTRL Übertragungsquittung

use mako_fristen::{self as fristen, ContrlAnlass};
use time::{Date, Month, OffsetDateTime, Time};

let received = OffsetDateTime::new_utc(
    Date::from_calendar_date(2026, Month::September, 9).unwrap(),
    Time::from_hms(9, 0, 0).unwrap(),
);
let due = fristen::contrl_due_at(received, ContrlAnlass::Regelfall);
assert_eq!(due - received, time::Duration::hours(6));

Modules§

abmeldung
Vorlauffristen der NB-seitigen Abmeldung — how far ahead the grid operator must announce that a supplier’s assignment ends.
antwort
The business answer Frist per inbound Prüfidentifikator.
meldung
Meldepflichten — messages a Festlegung obliges a party to send, with no answer of their own.
vorlauf
Vorlauffristen — the windows anchored on a date the message carries.

Enums§

ContrlAnlass
What the CONTRL is answering — the pair that decides its window.
HolidayCalendar
Selects which set of public holidays to observe when counting Werktage.

Constants§

APERAK_GAS_FOLGEPROZESS_LABEL
Deadline label for Gas APERAK sending obligations on Folgeprozesse.
APERAK_GAS_INITIALPROZESS_LABEL
Deadline label for Gas APERAK sending obligations on Initialprozesse.
APERAK_STROM_WEEKDAY_MINUTES
Minutes within which a Strom APERAK must be sent on weekdays (Mon–Fri).
APERAK_STROM_WINDOW_LABEL
Deadline label for Strom APERAK 45-minute sending obligations.
APERAK_WINDOW_LABEL_PREFIX
Shared prefix of every APERAK delivery-window label.
CONTRL_ALOCAT_MINUTEN
Minutes within which the CONTRL on a GABi-Gas ALOCAT must go out (CONTRL AHB 1.0 §2.3.1).
CONTRL_FRIST_HOURS
The default wall-clock hours within which a CONTRL must be sent after receiving an EDIFACT interchange or APERAK.
CONTRL_FRIST_LABEL
Deadline label used in the DeadlineStore for CONTRL delivery obligations.
CONTRL_STROM_SCHNELL_MINUTEN
Minutes within which a Strom Syntaxfehlermeldung on a UTILMD or ORDERS must go out on a day other than Saturday (CONTRL AHB 1.0 §2.4.1).
GAS_INITIALPROZESS_PIDS
The Gas Prüfidentifikatoren that open a business process — the Initialprozessschritte, which carry the 3-Werktage APERAK window instead of the next-Werktag-noon one.

Functions§

add_hours
Add hours wall-clock hours to from.
add_months
Shift a date n calendar months forward, clamping to the month’s last day.
add_werktage
Add n Werktage (working days) to from.
aperak_gas_due_at
The Gas APERAK sending deadline for an inbound Geschäftsvorfall, chosen by its Prüfidentifikator.
aperak_gas_folgeprozess_due_at
Compute the Gas APERAK sending deadline for Folgeprozesse.
aperak_gas_initialprozess_due_at
Compute the Gas APERAK sending deadline for Initialprozesse.
aperak_hat_anerkennungsmeldung
Whether the Sparte’s APERAK regime has a positive acknowledgement at all.
aperak_strom_due_at
Compute the Strom APERAK sending deadline after receiving a Strom UTILMD or ORDERS message.
berlin_at
Construct an OffsetDateTime at at Europe/Berlin on date, in UTC.
berlin_date
The Europe/Berlin calendar date of instant.
berlin_midnight
The instant at which the Europe/Berlin calendar day date begins, expressed in UTC.
berlin_now
Now, expressed in the Europe/Berlin offset.
contrl_due_at
Compute the CONTRL delivery deadline for anlass.
deadline_at_werktage
Compute a deadline werktage Werktage after from, expressed as an OffsetDateTime at 17:00 Europe/Berlin on the deadline date.
discharges_delivery_window
Does delivering message_type discharge the delivery window label?
end_of_day_berlin
The last moment of date in Europe/Berlin.
end_of_werktag_after
„unverzüglich, spätestens jedoch bis zum Ablauf des werktage. Werktags nach Eingang“ — the GeLi Gas answer-Frist shape.
heute
Today, as the German market states it — the Europe/Berlin calendar date.
is_werktag
Return true when date is a Werktag under cal.
next_werktag
Return the first Werktag that is on or after from.
next_werktag_at
„… Uhr des 1. Werktags nach dem ÜT“ — the dominant answer-Frist shape in GPKE Teil 2.
nth_werktag_at
„Unverzüglich, jedoch spätester ÜZ ist at Uhr des n. WT nach dem ÜT.“
sub_werktage
Subtract n Werktage from from — the mirror of add_werktage.
subtract_months
Shift a date n calendar months back, clamping to the month’s last day.
werktage_between
How many Werktage separate from and to — the inverse of add_werktage.