std.datetime
Datum und Uhrzeit rund um einen Unix-Zeitstempel in Sekunden: formatieren (ISO 8601, RFC 2822, eigene Muster), parsen, rechnen, prüfen. Die Unit arbeitet durchgehend in UTC und braucht keine externen Bibliotheken.
→ std.time · std.string · Standard Library
Alle Beispiele dieser Seite sind mit lyxc 1.1.2E übersetzt und ausgeführt; die gezeigten Ausgaben sind echte Programmausgaben und gegen Pythons datetime geprüft.
Die Erweiterungen aus #1601, #1602, #1603 und #1605 stecken in der Repo-Fassung der Standardbibliothek. Die unter/usr/include/lyx/unitsausgelieferte Fassung hinkt hinterher (#1578). Werundefined function 'DatetimeFromYmdHms' sieht, übersetzt gegen die Repo-Fassung:
lyxc --std-path=/pfad/zum/compiler-repo programm.lyx -o programm
Einsatz: Protokolle und Audit-Trails, HTTP-Kopfzeilen (Date:, Last-Modified:), Kalender- und Buchungslogik, Datenbank-Zeitstempel, SMTP/IMAP.
Datetime-Werte und Ergebniszeiger nicht verwechseln. Beide Parametersorten stehen in den Signaturen alsint64, meinen aber Verschiedenes:
*FormatIso(datetime, output)und die übrigenFormat…-Funktionen erwarten den Wert — einen Unix-Zeitstempel in Sekunden.
*ParseIso(input, result)und die übrigenParse…-Funktionen erwarten einen Zeiger auf einen Speicherbereich, in den das Ergebnis geschrieben wird.
Beim Verketten also den Wert auslesen:
var dt: int64 := alloc(8); ParseIso("2026-08-10T14:30:45"c, dt); // schreibt nach dt var ts: int64 := peek64(dt); // Wert holen FormatIso(ts, ausgabe); // -> 2026-08-10T14:30:45Z
Wird versehentlich der Zeiger anFormatIsoübergeben, meldet der Compiler nichts (beide sindint64) — die Ausgabe ist dann ein Datum irgendwo im Jahr 587.
Ausgabepuffer stellt der Aufrufer. Jede Format…-Funktion schreibt in einen übergebenen Puffer und hängt ein Nullbyte an; zurück kommt die Zahl der Zeichen ohne dieses Nullbyte. 64 Byte reichen für alle festen Formate, für Format mit eigenem Muster entsprechend mehr.
Formatieren
| Signatur | Ergebnis |
|---|---|
FormatIso(datetime, output) | 2026-08-17T07:45:12Z |
FormatRfc2822(datetime, output) | Mon, 17 Aug 2026 07:45:12 +0000 |
Format(datetime, fmt, output) | frei über Platzhalter — siehe Tabelle |
FormatDate(year, month, day, output) | 2026-08-17 — nimmt Einzelwerte, keinen Zeitstempel |
FormatTime(hour, minute, second, output) | 07:45:12 — ebenfalls Einzelwerte |
FormatLocale(datetime, locale, output) | 17.08.2026 14:30:00 (de) — siehe Kasten |
Platzhalter für ''Format''
| Platzhalter | Bedeutung | Beispiel |
|---|---|---|
%Y | Jahr, vierstellig | 2026 |
%y | Jahr, zweistellig | 26 |
%m | Monat, zweistellig | 08 |
%d | Tag, zweistellig | 17 |
%H | Stunde, 00–23 | 07 |
%M | Minute | 45 |
%S | Sekunde | 12 |
%w | Wochentag als Ziffer, 0 = Sonntag | 1 |
%W | Wochentag ausgeschrieben | Monday |
%b | Monatskürzel | Aug |
%B | Monat ausgeschrieben | August |
%p | AM / PM | AM |
%z | Zeitzonenversatz aus TZ | +0000 |
%Z | Zonenname — immer UTC | UTC |
%I | Stunde im 12-Stunden-Format, 01–12 | 02 |
%j | Tag im Jahr, dreistellig | 229 |
%% | ein wörtliches Prozentzeichen | % |
%f | Mikrosekunden — immer 000000 | 000000 |
Ein unbekannter Platzhalter wird weiterhin wörtlich ausgegeben — %e erscheint als %e im Ergebnis. Stumm ist das seit #1602 nicht mehr: der Rückgabewert ist dann negativ, sein Betrag bleibt die Zahl der geschriebenen Zeichen. Wer ihn wie bisher ignoriert, bekommt dieselbe Zeichenkette wie zuvor.
%p %I -> PM 02 rc=5
%j -> 229 rc=3
100%% fertig -> 100% fertig rc=11
%e %s -> %e %s rc=-5
import std.datetime;
import std.alloc;
import std.string;
fn main(): int64 {
var out: int64 := alloc(256);
var o: pchar := out as pchar;
// 2026-08-17T07:45:12Z
var ts: int64 := 1786952712;
FormatIso(ts, o); PrintLn(StrConcat("ISO 8601: ", o));
FormatRfc2822(ts, o); PrintLn(StrConcat("RFC 2822: ", o));
Format(ts, "%d.%m.%Y %H:%M:%S"c, o); PrintLn(StrConcat("deutsch: ", o));
Format(ts, "%W, %d. %B %Y"c, o); PrintLn(StrConcat("lang: ", o));
Format(ts, "%y-%m-%d %I%p"c, o); PrintLn(StrConcat("gemischt: ", o));
Format(ts, "%Z %z %w %b %f"c, o); PrintLn(StrConcat("Rest: ", o));
FormatLocale(ts, "de_DE"c, o); PrintLn(StrConcat("Locale de: ", o));
// Roundtrip: ISO parsen und zurueck
var buf: int64 := alloc(8);
var ok: int64 := ParseIso("2026-08-13T09:45:12Z"c, buf);
PrintLn(StrConcat(StrConcat("ParseIso ok=", IntToStr(ok)), StrConcat(" ts=", IntToStr(peek64(buf)))));
FormatIso(peek64(buf), o);
PrintLn(StrConcat("zurueck: ", o));
return 0;
}
ISO 8601: 2026-08-17T07:45:12Z
RFC 2822: Mon, 17 Aug 2026 07:45:12 +0000
deutsch: 17.08.2026 07:45:12
lang: Monday, 17. August 2026
gemischt: 26-08-17 %IAM
Rest: UTC +0000 1 Aug 000000
Locale de: 2026-08-17T07:45:12Z
ParseIso ok=1 ts=1786614312
zurueck: 2026-08-13T09:45:12Z
FormatLocalelokalisiert seit #1415 wirklich. Unterstützt werden die Sprachkennungende,at,ch,en,fr,es,itundpt— geprüft werden nur die ersten beiden Zeichen.en_USbekommt als einziges Locale die US-Schreibweise mit 12-Stunden-Zählung; alles Übrige folgt der Tag-vor-Monat-Ordnung.
Ein nicht unterstütztes Locale ist kein Fehler: die Funktion fällt still aufFormatIsozurück. Ob ein Locale erkannt wird, beantwortetLocaleSupported(locale): boolvorab.
de_DE : 17.08.2026 14:30:00 en_US : 8/17/2026 2:30:00 PM fr_FR : 17/08/2026 14:30:00 ja_JP : 2026-08-17T14:30:00Z <- Rückfall auf FormatIso LocaleSupported(de_DE) : true LocaleSupported(ja_JP) : false
Die Wochentags- und Monatsnamen (%W,%B,WeekdayLong,MonthLong) sind weiterhin ausschließlich englisch.
Parsen
| Signatur | Erwartet | Rückgabe |
|---|---|---|
ParseIso(input, result) | YYYY-MM-DDTHH:MM:SS (mindestens 19 Zeichen) | 1 / 0 |
ParseRfc2822(input, result) | Www, DD Mon YYYY HH:MM:SS ±HHMM (mindestens 25 Zeichen) | 1 / 0 |
ParseFlexible(input, result) | vier Formate, siehe Kasten | 1 / 0 |
ParseDate(input, year, month, day) | YYYY-MM-DD | 1 / 0 |
ParseTime(input, hour, minute, second) | HH:MM oder HH:MM:SS | 1 / 0 |
result, year, month, day, hour, minute und second sind Zeiger auf je acht Byte, in die das Ergebnis geschrieben wird.
Alle fünf Parser setzen das Ziel seit #1603 vorab auf 0. Ein übersehener Rückgabewert-Test endet damit bei 1970-01-01 statt bei einem plausibel aussehenden Altwert.
import std.datetime;
import std.alloc;
import std.string;
fn main(): int64 {
var out: int64 := alloc(256);
var o: pchar := out as pchar;
var buf: int64 := alloc(8);
// RFC 2822 parsen, auch mit Zeitzonenversatz
PrintLn(StrConcat("ParseRfc2822 ok=", IntToStr(ParseRfc2822("Mon, 17 Aug 2026 07:45:12 +0000"c, buf))));
FormatIso(peek64(buf), o); PrintLn(StrConcat(" -> ", o));
ParseRfc2822("Mon, 17 Aug 2026 09:45:12 +0200"c, buf);
FormatIso(peek64(buf), o); PrintLn(StrConcat("+0200 -> UTC: ", o));
// ParseFlexible nimmt beides
PrintLn(StrConcat("ParseFlexible(ISO): ", IntToStr(ParseFlexible("2026-08-17T07:45:12Z"c, buf))));
PrintLn(StrConcat("ParseFlexible(RFC): ", IntToStr(ParseFlexible("Mon, 17 Aug 2026 07:45:12 +0000"c, buf))));
PrintLn(StrConcat("ParseFlexible(dt.): ", IntToStr(ParseFlexible("17.08.2026"c, buf))));
PrintLn(StrConcat("ParseFlexible(Datum):", IntToStr(ParseFlexible("2026-08-17"c, buf))));
poke64(buf, 0 - 1);
PrintLn(StrConcat("ParseFlexible(Unsinn):", IntToStr(ParseFlexible("kein Datum"c, buf))));
PrintLn(StrConcat(" Zielwert danach: ", IntToStr(peek64(buf))));
// Einzelteile
var y: int64 := alloc(8); var m: int64 := alloc(8); var d: int64 := alloc(8);
PrintLn(StrConcat("ParseDate('2026-08-17') ok=", IntToStr(ParseDate("2026-08-17"c, y, m, d))));
PrintLn(StrConcat(" Jahr/Monat/Tag: ", StrConcat(IntToStr(peek64(y)), StrConcat("/", StrConcat(IntToStr(peek64(m)), StrConcat("/", IntToStr(peek64(d))))))));
PrintLn(StrConcat("ParseDate('2026-13-01') ok=", IntToStr(ParseDate("2026-13-01"c, y, m, d))));
// Zeitzonenversatz der Umgebung
PrintLn(StrConcat("GetTimezoneOffset(): ", IntToStr(GetTimezoneOffset())));
FormatTimezoneOffset(GetTimezoneOffset(), o); PrintLn(StrConcat(" formatiert: ", o));
FormatTimezoneOffset(0 - 18000, o); PrintLn(StrConcat(" -18000 s: ", o));
// Namen
PrintLn(StrConcat(StrConcat("WeekdayLong(1)=", WeekdayLong(1)), StrConcat(" MonthLong(8)=", MonthLong(8))));
return 0;
}
ParseRfc2822 ok=1
-> 2026-08-17T07:45:12Z
+0200 -> UTC: 2026-08-17T07:45:12Z
ParseFlexible(ISO): 1
ParseFlexible(RFC): 1
ParseFlexible(dt.): 1
ParseFlexible(Datum):1
ParseFlexible(Unsinn):0
Zielwert danach: 0
ParseDate('2026-08-17') ok=1
Jahr/Monat/Tag: 2026/8/17
ParseDate('2026-13-01') ok=0
GetTimezoneOffset(): 0
formatiert: +00:00
-18000 s: -05:00
WeekdayLong(1)=Monday MonthLong(8)=August
Der Zeitzonenversatz aus RFC 2822 wird korrekt herausgerechnet: 09:45:12 +0200 ergibt denselben Zeitstempel wie 07:45:12 +0000.
ParseFlexibleprobiert vier Formate in dieser Reihenfolge (#1603): ISO 8601 mit Zeitanteil, RFC 2822, ISO-Datum ohne Zeit (Zeitanteil00:00:00) und die deutsche Schreibweise17.08.2026mit optionalem14:30oder14:30:00. Ein US-amerikanisches8/17/2026scheitert weiterhin.
Die Parser prüfen die Trennzeichen an festen Stellen, nicht die Semantik:ParseIsoverlangt-an Position 4 und 7,Tan 10,:an 13 und 16. Ein Leerzeichen stattT(wie in SQL-Zeitstempeln) wird abgewiesen. Angehängte Bruchteile oder Zonenversätze (…:12.500+02:00) werden dagegen ignoriert, nicht ausgewertet — die Zeit gilt als UTC.
Zeitstempel bauen und zerlegen
Bis #1601 führte der Weg von Kalenderwerten zu einem Zeitstempel nur über eine Zeichenkette — ISO-String zusammensetzen, ParseIso aufrufen. Beide Richtungen gibt es jetzt direkt:
| Signatur | Beschreibung |
|---|---|
DatetimeFromYmdHms(year, month, day, hour, minute, second) | Zeitstempel aus Einzelwerten |
DatetimeFromYmd(year, month, day) | wie oben, Zeitanteil 00:00:00 |
YearOf(dt) / MonthOf(dt) / DayOf(dt) | Kalenderwerte aus dem Zeitstempel |
HourOf(dt) / MinuteOf(dt) / SecondOf(dt) | Uhrzeitwerte aus dem Zeitstempel |
DayOfWeek(dt) | Wochentag zum Zeitstempel, 0 = Sonntag |
DayOfWeekYmd(year, month, day) | Wochentag aus Einzelwerten |
WeekYear(year, month, day) | Jahr, zu dem die ISO-Kalenderwoche gehört |
StartOfDay(dt) / EndOfDay(dt) | 00:00:00 bzw. 23:59:59 desselben Tages |
StartOfMonth(dt) / EndOfMonth(dt) | Monatserster bzw. Monatsletzter |
import std.io;
import std.string;
import std.alloc;
import std.datetime;
fn main(): int64 {
var ts: int64 := DatetimeFromYmdHms(2026, 8, 17, 14, 30, 0);
Print("DatetimeFromYmdHms : "); PrintLn(IntToStr(ts));
Print("YearOf/MonthOf/DayOf : ");
Print(IntToStr(YearOf(ts))); Print(" ");
Print(IntToStr(MonthOf(ts))); Print(" ");
PrintLn(IntToStr(DayOf(ts)));
Print("HourOf/MinuteOf/SecondOf : ");
Print(IntToStr(HourOf(ts))); Print(" ");
Print(IntToStr(MinuteOf(ts))); Print(" ");
PrintLn(IntToStr(SecondOf(ts)));
Print("DayOfWeek : "); Print(IntToStr(DayOfWeek(ts)));
Print(" -> "); PrintLn(WeekdayLong(DayOfWeek(ts)));
Print("WeekNumber/WeekYear 29.12.2025 : ");
Print(IntToStr(WeekNumber(2025, 12, 29))); Print(" / ");
PrintLn(IntToStr(WeekYear(2025, 12, 29)));
Print("StartOfDay/EndOfMonth : ");
Print(IntToStr(StartOfDay(ts))); Print(" ");
PrintLn(IntToStr(EndOfMonth(ts)));
Print("DiffMonths 2026-01-31 -> 2026-08-17 : ");
PrintLn(IntToStr(DiffMonths(DatetimeFromYmd(2026, 1, 31), ts)));
return 0;
}
DatetimeFromYmdHms : 1786977000
YearOf/MonthOf/DayOf : 2026 8 17
HourOf/MinuteOf/SecondOf : 14 30 0
DayOfWeek : 1 -> Monday
WeekNumber/WeekYear 29.12.2025 : 1 / 2026
StartOfDay/EndOfMonth : 1786924800 1788220799
DiffMonths 2026-01-31 -> 2026-08-17 : 6
WeekNumberallein reicht für eine Datumsangabe nicht. Der 29.12.2025 liegt in KW 1 des Jahres 2026 — genau dafür gibt esWeekYear. Wer „KWx/ Jahr aus%Y„ schreibt, produziert an jedem Jahreswechsel eine falsche Angabe.
DiffMonthsundDiffYearszählen volle Einheiten, angefangene nicht. Ein Alter aus dem Geburtsdatum stimmt damit auch am Tag vor dem Geburtstag.
Rechnen und Prüfen
| Signatur | Beschreibung |
|---|---|
AddSeconds(datetime, seconds) | schlichte Addition |
AddMinutes(datetime, minutes) | minutes × 60 |
AddHours(datetime, hours) | hours × 3600 |
AddDays(datetime, days) | days × 86400 |
AddWeeks(datetime, weeks) | weeks × 604800 |
AddMonths(datetime, months) | kalendarisch, mit Klemmung auf den Monatsletzten |
AddYears(datetime, years) | kalendarisch, klemmt den 29. Februar auf den 28. |
DiffSeconds(datetime1, datetime2) | datetime2 − datetime1 — Reihenfolge beachten |
DiffDays(y1, m1, d1, y2, m2, d2) | Tagesdifferenz aus Einzelwerten |
DiffMonths(von, bis) / DiffYears(von, bis) | volle Monate bzw. Jahre zwischen zwei Zeitstempeln |
DaysInMonth(year, month) | 28–31, mit Schaltjahresregel |
DayOfYear(year, month, day) | 1–366 |
WeekNumber(year, month, day) | ISO-8601-Kalenderwoche |
WeekYear(year, month, day) | Jahr zur Kalenderwoche — siehe oben |
IsValidDate / IsValidTime / IsValidDateTime | kalendarische Prüfung, liefert bool |
ToUnixTimestamp / FromUnixTimestamp | Gleichheitsabbildung — der Datetime-Wert ist der Zeitstempel |
ToMilliseconds / FromMilliseconds | × 1000 bzw. / 1000 |
import std.datetime;
import std.alloc;
import std.string;
fn J(b: bool): pchar { if (b) { return "gueltig"; } return "ungueltig"; }
fn main(): int64 {
var out: int64 := alloc(256);
var o: pchar := out as pchar;
// Kalenderrechnen
PrintLn(StrConcat("DaysInMonth(2024, 2): ", IntToStr(DaysInMonth(2024, 2))));
PrintLn(StrConcat("DaysInMonth(2026, 2): ", IntToStr(DaysInMonth(2026, 2))));
PrintLn(StrConcat("DaysInMonth(1900, 2): ", IntToStr(DaysInMonth(1900, 2))));
PrintLn(StrConcat("DayOfYear(2026, 8, 13):", IntToStr(DayOfYear(2026, 8, 13))));
PrintLn(StrConcat("WeekNumber(2026, 8, 13):", IntToStr(WeekNumber(2026, 8, 13))));
PrintLn(StrConcat("DiffDays(2026-08-13 -> 2026-12-24): ", IntToStr(DiffDays(2026, 8, 13, 2026, 12, 24))));
// Gueltigkeit
PrintLn(StrConcat("IsValidDate(2026, 2, 29): ", J(IsValidDate(2026, 2, 29))));
PrintLn(StrConcat("IsValidDate(2024, 2, 29): ", J(IsValidDate(2024, 2, 29))));
PrintLn(StrConcat("IsValidTime(24, 0, 0): ", J(IsValidTime(24, 0, 0))));
// Arithmetik am Monatsende
var buf: int64 := alloc(8);
ParseIso("2026-01-31T12:00:00Z"c, buf);
var jan31: int64 := peek64(buf);
FormatIso(AddMonths(jan31, 1), o); PrintLn(StrConcat("31.01. + 1 Monat: ", o));
FormatIso(AddMonths(jan31, 13), o); PrintLn(StrConcat("31.01. + 13 Monate:", o));
FormatIso(AddDays(jan31, 1), o); PrintLn(StrConcat("31.01. + 1 Tag: ", o));
ParseIso("2024-02-29T12:00:00Z"c, buf);
FormatIso(AddYears(peek64(buf), 1), o); PrintLn(StrConcat("29.02.2024 + 1 Jahr:", o));
// Dauer
FormatDuration(93784, o); PrintLn(StrConcat("FormatDuration(93784): ", o));
FormatDurationShort(93784, o); PrintLn(StrConcat("FormatDurationShort(93784): ", o));
FormatDuration(45, o); PrintLn(StrConcat("FormatDuration(45): ", o));
return 0;
}
DaysInMonth(2024, 2): 29
DaysInMonth(2026, 2): 28
DaysInMonth(1900, 2): 28
DayOfYear(2026, 8, 13):225
WeekNumber(2026, 8, 13):33
DiffDays(2026-08-13 -> 2026-12-24): 133
IsValidDate(2026, 2, 29): ungueltig
IsValidDate(2024, 2, 29): gueltig
IsValidTime(24, 0, 0): ungueltig
31.01. + 1 Monat: 2026-02-28T12:00:00Z
31.01. + 13 Monate:2027-02-28T12:00:00Z
31.01. + 1 Tag: 2026-02-01T12:00:00Z
29.02.2024 + 1 Jahr:2025-02-28T12:00:00Z
FormatDuration(93784): 26h 03m 04s
FormatDurationShort(93784): 26:03:04
FormatDuration(45): 45s
Die Schaltjahresregel stimmt bis zur Jahrhundertausnahme (1900 hatte 28 Tage, 2024 hat 29), Wochennummer und Tagesnummer decken sich mit Pythons isocalendar() und timetuple().
AddMonthsklemmt, statt überzulaufen. 31.01. + 1 Monat ergibt den 28.02., nicht den 03.03. Das ist die übliche Kaufmannsregel — aber nicht umkehrbar:AddMonths(AddMonths(t, 1), -1)liefert den 28.01., nicht den 31.01. Wer Fristen rechnet, sollte das Ausgangsdatum getrennt aufheben.
Relative Zeit und Dauer
| Signatur | Beispielausgabe |
|---|---|
FormatRelative(datetime, output) | 2 hours ago, in 3 days — gegen die aktuelle Zeit |
FormatDuration(seconds, output) | 26h 03m 04s, -26h 03m 04s, 12345h |
FormatDurationShort(seconds, output) | 26:03:04, -00:45 |
Negative Dauern und Dauern ab 1000 Stunden ergaben bis #1605 stumm Müllzeichen oder einen Leerstring. Beide Funktionen rechnen jetzt mit dem Betrag und stellen ein - voran; die Stundenzahl ist nicht mehr auf drei Stellen begrenzt:
FormatDuration(-93784) -> -26h 03m 04s
FormatDuration(1000*3600) -> 1000h
FormatDurationShort(-45) -> -00:45
FormatRelative holt die Gegenwart über clock_gettime; bis lyxc 1.0.17C rechnete es wegen einer nicht gebundenen Zeitquelle gegen die Epoche und lieferte deshalb Abstände von über 50 Jahren (#1179). Die Ausgabe ist englisch.
Zeitzonen
| Signatur | Beschreibung |
|---|---|
GetTimezoneOffset(): int64 | Versatz zu UTC in Sekunden, aus der Umgebungsvariablen TZ |
FormatTimezoneOffset(offset_seconds, output) | +02:00 / -05:00 |
Ohne gesetztes TZ ist der Versatz 0. FormatIso und FormatRfc2822 schreiben grundsätzlich UTC (Z bzw. +0000) — der Versatz wirkt nur über den Platzhalter %z und über FormatTimezoneOffset.
TZ | Ergebnis |
|---|---|
CET-1 | 3600 |
EST5 | −18000 |
UTC oder nicht gesetzt | 0 |
IST-5:30 | 18000 statt 19800 |
CET-1CEST,M3.5.0,M10.5.0/3 | 3600 — Sommerzeitregel bleibt unbeachtet |
Der Minutenanteil wird verschluckt. Zonen mit halber oder viertelstündiger Abweichung — Indien (+05:30), Iran (+03:30), Nepal (+05:45), Neufundland (−03:30), Teile Australiens — bekommen einen falschen Versatz, ohne Fehlermeldung (#1416).
Sommerzeit gibt es nicht. EineTZ-Angabe mit Umstellungsregel liefert immer den Standardversatz, unabhängig vom Datum. Wer lokale Zeit anzeigen muss, rechnet den Versatz selbst und behandelt die Umstellung außerhalb dieser Unit.
Namen
| Signatur | Wertebereich | Ergebnis |
|---|---|---|
WeekdayShort(weekday) | 0–6, 0 = Sonntag | Mon |
WeekdayLong(weekday) | 0–6 | Monday |
MonthShort(month) | 1–12 | Aug |
MonthLong(month) | 1–12 | August |
Alle vier liefern englische Namen und geben einen internen Zeiger zurück — nicht freigeben. Den Wochentag zu einem Zeitstempel liefert DayOfWeek(dt) als Zahl — damit sind WeekdayShort und WeekdayLong ohne Umweg über Format benutzbar. Für Einzelwerte gibt es DayOfWeekYmd(year, month, day).
Fallstricke
- Alles ist UTC. Es gibt keine lokale Zeitrechnung;
TZwirkt nur über%z. DiffSeconds(a, b)rechnetb − a— die umgekehrte Reihenfolge der Namen.FormatDateundFormatTimenehmen Einzelwerte, keinen Zeitstempel. Wer versehentlich einen Zeitstempel übergibt, bekommt eine Ziffernfolge ohne Fehlermeldung.ToUnixTimestampundFromUnixTimestamptun nichts — der Datetime-Wert ist bereits der Zeitstempel. Sie stehen nur der Lesbarkeit halber da.- Jahr vierstellig — aber kein Müll mehr.
FormatDateund die%Y-Ausgabe rechnen mit vier Stellen; Jahre außerhalb 1000–9999 fallen seit #1605 auf die vollständige Zahl in abweichender Breite zurück, statt Steuerzeichen zu erzeugen. - Keine Mikrosekunden.
%fliefert immer000000,ToMillisecondsmultipliziert schlicht mit 1000. - Ausgabepuffer großzügig bemessen — keine
Format…-Funktion kennt eine Obergrenze und keine prüft, wie viel Platz vorhanden ist.
Weiterführend: std.time — Uhr, Schlafen, Messung · std.env · Standard Library
Quelle: std/datetime.lyx · Autor: Andreas Röne · Copyright: 2024–2025 Andreas Röne
Letzte Aktualisierung: 2026-08-18 — nachgezogen auf lyxc 1.1.2E: neuer Abschnitt „Zeitstempel bauen und zerlegen“ (#1601), Platzhalter %I, %j und %% sowie negativer Rückgabewert bei unbekanntem Spezifizierer (#1602), ParseFlexible mit vier Formaten und vorab genulltem Ziel (#1603), Vorzeichen- und Bereichsprüfung der Dauerausgabe (#1605), FormatLocale lokalisiert wirklich (#1415).
Vorherige Aktualisierung: 2026-08-13 — Seite gegen std/datetime.lyx überarbeitet: drei lauffähige Beispiele mit echter Ausgabe (gegen Pythons datetime geprüft), vollständige Platzhalter-Tabelle für Format, Parser-Erwartungen, Klemmverhalten von AddMonths/AddYears, Zeitzonen-Tabelle und Fallstricke. Belegt und als Issue erfasst: FormatLocale ignoriert den Locale (#1415), GetTimezoneOffset verschluckt den Minutenanteil (#1416). Geprüft mit lyxc 1.0.21A.
