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/units ausgelieferte Fassung hinkt hinterher (#1578). Wer undefined 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 als int64, meinen aber Verschiedenes:

* FormatIso(datetime, output) und die übrigen Format…-Funktionen erwarten den Wert — einen Unix-Zeitstempel in Sekunden.
* ParseIso(input, result) und die übrigen Parse…-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 an FormatIso übergeben, meldet der Compiler nichts (beide sind int64) — 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

 
FormatLocale lokalisiert seit #1415 wirklich. Unterstützt werden die Sprachkennungen de, at, ch, en, fr, es, it und pt — geprüft werden nur die ersten beiden Zeichen. en_US bekommt 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 auf FormatIso zurück. Ob ein Locale erkannt wird, beantwortet LocaleSupported(locale): bool vorab.

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.

 
ParseFlexible probiert vier Formate in dieser Reihenfolge (#1603): ISO 8601 mit Zeitanteil, RFC 2822, ISO-Datum ohne Zeit (Zeitanteil 00:00:00) und die deutsche Schreibweise 17.08.2026 mit optionalem 14:30 oder 14:30:00. Ein US-amerikanisches 8/17/2026 scheitert weiterhin.

Die Parser prüfen die Trennzeichen an festen Stellen, nicht die Semantik: ParseIso verlangt - an Position 4 und 7, T an 10, : an 13 und 16. Ein Leerzeichen statt T (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

 
WeekNumber allein reicht für eine Datumsangabe nicht. Der 29.12.2025 liegt in KW 1 des Jahres 2026 — genau dafür gibt es WeekYear. Wer „KW x / Jahr aus %Y„ schreibt, produziert an jedem Jahreswechsel eine falsche Angabe.

DiffMonths und DiffYears zä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().

 
AddMonths klemmt, 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. Eine TZ-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; TZ wirkt nur über %z.
  • DiffSeconds(a, b) rechnet b − a — die umgekehrte Reihenfolge der Namen.
  • FormatDate und FormatTime nehmen Einzelwerte, keinen Zeitstempel. Wer versehentlich einen Zeitstempel übergibt, bekommt eine Ziffernfolge ohne Fehlermeldung.
  • ToUnixTimestamp und FromUnixTimestamp tun nichts — der Datetime-Wert ist bereits der Zeitstempel. Sie stehen nur der Lesbarkeit halber da.
  • Jahr vierstellig — aber kein Müll mehr. FormatDate und 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. %f liefert immer 000000, ToMilliseconds multipliziert 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.