Datum & Zeit in Basic

Auf dieser Seite finden sie einige Artikel zur Verwendung von Basic (LibreOffice-Basic, Visual Basic, VBA) mit Datum und Zeit.
Dazu gehören Umwandlungen wichtiger interner Datenformate (Y1900, UNIX Timestamp, JD) und die Codierung von Standard-Texten nach ISO-8859.
Viel Arbeit muss man leider für Weltzeit UTC, Zeitzonen und Sommerzeit aufwenden - Themen die von Basic wenig unterstützt werden.
Alle Live-Beispiele dieser Seite werden mit Javascript berechnet, d.h. Basic wird hier simuliert.
Basic Die Programmiersprache Basic (LibreOffice-Basic, Visual Basic, VBA)
Datum & Zeit Datum und Zeit
Datentyp Die interne Darstellung von Datum und Zeit in Basic
System Datum & Zeit aus dem Betriebssystem des PC
Bestandteile Zusammensetzung und Zerlegung von Datum & Zeit in Basic
Weltzeit Angaben zu Weltzeit (UTC) Zeitzone, Offset
Sommerzeit Berücksichtigung von Normalzeit und Sommerzeit
ZeitStempel Unix-Timestamp: Sekunden seit 1970-01-01
JD & MJD Julianischer Tag (JD) und Modifizierter julianischer Tag (MJD)
Anzeigeformat und kulturspezifische Unterschiede
Das international standardisierte Format: YYYY-MO-DD hh:mi:ss
Monatsnamen, Wochentage, Kalenderwoche, ...
OnTime Das Basic-Ereignis (Event) OnTime
Links Ausgewählte Links zum Thema 'Basic @ Datum & Zeit'
Verwandte Themen
Datum & Zeit in der Informatik, Grundlagen (Astronomie)
NTP Die Synchronisation der PC-Systemzeit
Oster-Formel Berechnung der fixen und beweglichen christlichen Feiertage
Umrechnung verschiedener Datum & Zeit-Systeme in Basic
Programmiersprachen Datum & Zeit in C/C++, Javascript, Perl, PHP, SQL, Linux (Shell-Konsole), Windows-(cmd-Konsole), ...

Datum & Zeit

Kalender

Heute gilt in den meisten Teilen der Welt der → Gregorianische Kalender.

Die Basic-Eigenschaft Calendar entspricht dem verwendeten Kalender.
  Calendar = vbCalGreg
setzt den Gregorianischen Kalender.
In anderen Kulturen werden teilweise andere Kalender verwendet, jedoch angesichts der Globalisierung mit geringer Bedeutung. Die Unterschiede reduzieren sich dann auf die Berechnung lokaler Feiertage.

Andere Kalender-verwandte Daten wie Monatsnamen, Wochentag oder Kalenderwoche sind → kulturspezifisch und daher selbst für das gleiche Datum → unterschiedlich !

Details zum Thema Datum und Zeit

Zeit:

Die aktuelle Zeit ist vom Standort auf der Erdoberfläche abhängig. Daraus ergibt sich die jeweilige → Zeitzone.

Eine internationsl einheitliche Weltzeit ist die → Universal Time Coordinated (UTC): die Zeit am Nullmeridian (Greenwich), früher GMT.

Die lokale Zeit wird darüber hinaus in einigen Staaten im Rahmen der → Sommerzeit (daylight savings) 2mal jährlich an unterschiedlichen Tagen geändert.

Details zum Thema Datum und Zeit

Interne Darstellung & Daten-Typ

Interne Darstellung

Damit man mit Datum & Zeit auch rechnen kann, wird dieser Datentyp in den meisten Betriebssystemen und Programmen intern (!) als Zahl geführt.

Das bedingt die willkürliche Festlegung auf einen Nullpunkt. Aus dem intern verwendeten Datentyp (Bit-Anzahl) ergeben sich die Unter- und Obergrenzen für das darstellbare Datum.

Das Y1900-System :

Basic verwendet für Datum und Zeit das 'Y1900'-System:
Der Nullpunkt dieser Zeitskala liegt 'ungefähr' am Beginn des Jahres 1900:
1899-12-30 00:00:00
Ab diesem Datum wird der Zahlenwert um die Zahl 1 pro Tag erhöht.

Test: Tragen sie in zwei Zellen eines Kalkulations-Programms (LibreOffice, OpenOffice, MS-Excel) die gleiche Formel =HEUTE() ein.
Formatieren sie eine der beiden Zellen als Standard-Zahl (Menü Format | Zellen | Zahlen | Standard).
Live-Ergebnis:
HEUTE() = 0
HEUTE() = 0000-00-00

Die Tageszeit wird als Gleitkomma-Anteil des Datum-Zeit-Typs festgelegt.
Den Zeiten 0:00, 12:00, 24:00 entsprechen die Zahlenwerte 0.00, 0.50, 1.00
So ist gewährleistet, dass Differenzen zwischen Datum-. und Zeit-Angaben rasch und einfach berechnet werden können.

Test: Wiederholen sie den links beschriebenen Datum-Test mit der Funktion =JETZT(), welche Datum und aktuelle Zeit liefert.
Live-Ergebnis:
JETZT() = 0
JETZT() = 0000-00-00 00:00:00
Grenzen:
Negative Zahlenwerte bezeichnen Tage vor 1900. LibreOffice und OpenOffice erlauben jedes Datum der Jahre 1..32767 und damit die Arbeit mit den meisten historischen Daten
MS-Software kann aus unbekannten Gründen nicht mit negativen Y1900-Werten rechnen. In MS-Excel liegt die Untergrenze bei 1900-01-01.
Die Obergrenze wurde in MS-Excel ebenfalls willkürlich mit 9999-12-31 festgelegt, das entspricht dem Y1900-Zahlenwert 2958465

MS-Programme für Apple's MacOS verwenden 1904-01-01 als Nullpunkt. Auch hier liegt die Obergrenze bei 9999-12-31, das entspricht dem Y1900-Zahlenwert 2957003.

Andere Programme und Betriebssysteme verwenden für Datum und Zeit andere Systeme als Y1900 !
Sie müssen daher Datum und Zeit für den Transport der Daten umrechnen oder in ein → Standard-Textformat bringen !
Im internen Kalender von MS-Programmen ist seit vielen Jahren ein Fehler: Die Programme zählen den 1900-02-29, diesen Tag hat es jedoch nie gegeben, da im Jahr 1900 nach dem → Gregorianischen Kalender der Schalttag ausgefallen ist. Wegen der Untergrenze bei 1900 betrifft das zum Glück nur eine kleine Anzahl weniger wichtiger Tage. Es ist allerdings bezeichnend, dass der Hersteller offenbar nicht daran denkt, einen Fehler auch einmal zu korrigieren.

Basic Daten-Typ "Date":

Variablen vom Typ Date werden als 64-Bit-Gleitkommazahlen (8 Byte) nach → IEEE-754 gespeichert und können ein Datum im Bereich vom 0100-01-01 bis zum 9999-12-31 (inkl. der Uhrzeit) darstellen.
Ein Unterschied zum Typ Double ist nicht erkennbar. Alle vorgestellten Beispiele funktionieren mit Double

Ein Datums-"Literal" muss man in # Zeichen einschließen, z.B.:
#January 1, 2000#
#1 Jan 2000#.

Date verwendet zur Darstellung des Datums das auf dem PC eingestellte 'kurze Datumsformat'.
Die Zeit wird mit dem eingestellten Zeitformat dargestellt.

Bei Umwandlung anderer Zahlen-Typen in Date-Werte
ergeben die Vorkommastellen das Datum, die Nachkommastellen die Uhrzeit.

Negative Zahlen repräsentieren ein Datum vor 1900 (unter Berücksichtigung des M$-Kalender-Fehlers 1899-12-30). Damit entspricht das Format dem z.B. von üblichen Kalkulations-Programmen verwendeten (Gleitkomma-Zahl, Double Precision), jedoch ohne die genannte Untergrenze.
In LibreOffice und OpenOffice kann man auch mit negativen Y1900-Werten ab Y1900(1582-12-01)=-115811 problemlos arbeiten.
Lediglich MS-Excel kann mit historischen Daten vor 1900 weder rechnen, noch kann man diese eingeben oder anzeigen.

Eine Möglichkeit zum Speichern der Zeitzone oder zur Umrechnung der Daten in/von Weltzeit UTC ist leider weder in Kalkulations-Programmen noch in Basic vorgesehen. Man müss diese Daten selbst verwalten und die Umrechnung selbst programmieren.
Details dazu auf dieser Seite unter ↓ UTC

Zonenzeit

Das Y1900-Datum wird in der lokalen Zeitzone angegeben. Daher gibt es Zeit-Sprünge, die sowohl vom Ort (Zeitzone) als auch vom Datum (Normalzeit / Sommerzeit) abhängen.
Aus diesem Grund sind Daten im Y1900-Format international nicht vergleichbar. Man kann Y1900-Daten aus unterschiedlichen Zeitzonen in Weltzeit UTC umrechnen oder besser gleich den global eindeutigen ↓ UNIX-Timestamp verwenden.

Umrechnung mit der Differenz zwischen lokaler Zeitzone und Weltzeit UTC in Stunden. Dieser Wert beträgt in Mitteleuropa (CET, MEZ) bei Normalzeit tzoh=1 und bei Sommerzeit tzoh=2
Y1900_utc = Y1900_cet - tzoh/24
Y1900_cet = Y1900_utc + tzoh/24
Details zu diesem Thema auf der Seite Datum und Zeit

System - Datum & -Zeit

Die Basic-Function Date liefert das ganzzahlige aktuelle Datum ohne Zeit, analog zur Funktion =HEUTE() von Kalkulations-Programmen.
Das aktuelle Datum ergibt Zahlenwerte >32767, daher müssen sie den Typ Double oder Long verwenden.
Live:
Date = 0
Anwendung:
Dim x as Double
' Dim x As Long
x = Date
Die Basic-Function Time liefert die aktuelle Zeit ohne Datum.
Der gelieferte Zahlenwert ist eine Gleitkomma-Zahl im Bereich 0..1
Eine analoge Funktion scheint es in Kalkulations-Programmen nicht zu geben.
Live:
Time = 0
Anwendung:
Dim x As Double
x = Time
Die Basic-Function Now gibt Datum und Zeit als Gleitkomma-Zahl zurück, analog zur Funktion =JETZT() von Kalkulations-Programmen.
Live:
Now = 0
Anwendung:
Dim x As Double
x = Now
Die Angabe von Datum & Zeit erfolgt offenbar immer in Lokalzeit, d.h. je nach Einstellung von Zeitzone und Sommerzeit am jeweiligen PC. Intern wird vermutlich (z.B. bei Datei-Zeiten) Weltzeit UTC gespeichert, das wird vor den AnwenderInnen jedoch komplett abgeschirmt. Offenbar nimmt der Hersteller an, dass seine KundInnen zu dumm sind, um zwischen Lokalzeit und Weltzeit zu unterscheiden ...

Bestandteile - Jahr, Monat, Tag, Stunde, Minute, Sekunde

Y1900-Datum yyyy,mo,dd,hh,mi,ss iso

In diesem Basic-Beispiel wird ein Y1900-Datum mydate durch die Funktion y1900_to_ymdhms() in seine ganzzahligen Bestandteile zerlegt. Das Ergebnis wird in einem Alarmfenster (MsgBox) angezeigt und als String (Text) zurückgegeben.

Eine Basic-Function kann nur genau einen Funktionswert zurückgeben, nicht jedoch ein Array von 6 Zahlen, wie es hier notwendig wäre..
Mit einem Trick kann man diese Beschränkung umgehen:
Das aufrufende Programm übergibt ein (leeres) → Array als Argument an die Funktion, welche die 6 Ergebnis-Daten in das Array einträgt. Die Funktion gibt keinen oder einen beliebigen Wert zurück, der nicht verwendet wird. Nach Ausführung der Funktion stehen die Daten im Array des aufrufenden Programms zur Verfügung.

Dieser Trick funktioniert allerdings nur innerhalb von Basic. An ein Kalkulations-Programm kann man immer nur einen Wert zurückgeben.
Details zu Basic-Arrays

Function y1900_to_ymdhms(mydate)
Dim s As String
s = "Year = " & Year(mydate)
s = s & Chr(13) & "Month = " &_
Month(mydate)
s = s & Chr(13) & "Day = " &_
Day(mydate)
s = s & Chr(13) & "Hour = " &_
Hour(mydate)
s = s & Chr(13) & "Minute = " &_
Minute(mydate)
s = s & Chr(13) & "Second = " &_
Second(mydate)
MsgBox (s)
y1900_to_ymdhms = s
End Function

yyyy,mo,dd,hh,mi,ss Y1900-Datum

In diesem Beispiel wird eine Y1900-Variable (Basic-Datum+Zeit) aus den ganzzahligen Bestandteilen zusammengesetzt.
Falls sie diese Funktion als "BenutzerInnen-definierte Funktion" in einem Kalkulations-Programm verwenden (LibreOffice, OpenOffice, MS-Excel, ...) verwenden, dann sollten sie die Zellen in einem Datum-Zeit-Format formatieren.
Das (einzige) weltweit eindeutige → ISO-8601-Format kann man in allen neueren Kalkulations-Programmen auswählen, mindestens jedoch als BenutzerInnen-deninierten Format angeben:
JJJJ-MM-TT hh:mm:ss
(Zelle markieren, Menübefehl Format | Zellen | Zahlen | Benutzerdefiniert )

Function ymdhms_to_y1900(yyyy, mo, dd, hh, mi, ss)
ymdhms_to_y1900 = DateSerial(yyyy, mo, dd) _
+ TimeSerial(hh, mi, ss)
End Function
Die gleiche Funktion, jedoch etwas aufwändiger programmiert und sowohl mit LibreOffice-Basic als auch MS-VBA kompatibel:

Alle Argumente sind optional, d.h. man kann beliebig viele davon weglassen. Man muss allerdings die Reihenfolge der Argumente einhalten. Alle nicht angegebenen Argumente erhalten Standard-Werte.

Wenn man ein optionales Argument weglässt, dann wird an seiner Stelle ein Standard-Wert iyy...iss eingesetzt.

Wenn man auch das Jahr weglässt, dann wird der 1.Tag des aktuellen Jahres zurückgegeben.

Wenn ein Argument den sinnvollen Werte-Bereich überschreitet, dann rechnet die Funktion sinngemäß. Beispiel: Wenn man für die Stunden hh=-1 angibt, dann wird die Zeit des Vortags um 23:00 verwendet.

Man kann die Zeilen-Verlängerung mit _ Underline-Zeichen weglassen und die entsprechenden Funktion kürzer, jedoch weniger übersichtlich formulieren.

Die Funktion IsMissing() gibt an, ob ein optionales Argument übergeben wurde oder nicht. Sie wird von MS-VBA offenbar nur auf Variable des Typs Variant angewendet.
Function ymdhms_to_y1900( _
Optional yyyy As Variant, _
Optional mo As Variant, _
Optional dd As Variant, _
Optional hh As Variant, _
Optional mi As Variant, _
Optional ss As Variant) As Double
Dim iyy, imo, idd, ihh, imi, iss As Integer
Dim y1900 As Double
iyy = Year(Date)
imo = 1
idd = 1
ihh = 0
imi = 0
iss = 0
If (Not IsMissing(yyyy)) Then iyy = yyyy
If (Not IsMissing(mo)) Then imo = mo
If (Not IsMissing(dd)) Then idd = dd
If (Not IsMissing(hh)) Then ihh = hh
If (Not IsMissing(mi)) Then imi = mi
If (Not IsMissing(ss)) Then iss = ss
y1900 = DateSerial(iyy, imo, idd)
y1900 = y1900 + TimeSerial(ihh, imi, iss)
ymdhms_to_y1900 = y1900
End Function

Weltzeit (Universal Time Coordinated, UTC) und lokale Zonenzeit

Die Weltzeit UTC (früher GMT) ist der weltweit eindeutige Standard für die Tageszeit. UTC ist unabhängig von Ort (Zeitzone) und Datum (Sommerzeit).
Alle wichtigen Server sind auf UTC eingestellt, nicht auf die lokale Zeitzone. Darüber hinaus wird ein Server-PC periodisch mit einem Zeit-Standard synchronisiert (→ Network Time Protocol, NTP). Der Server liefert selbst die Zeit für alle PC eines lokalen Netzwerks.
Alle Live-Daten dieser Seite folgen der Zeit des Webservers. Zum Vergleich die aktuelle Zeit ihres PC, des Servers, und die Weltzeit UTC.
Lokalzeit (Server):
00:00:00
Lokalzeit (Ihr PC):
00:00:00
UTC:
00:00:00
Das von Basic und den meisten anderen MS-Programmen verwendete Format Y1900 kennt weder Zeitzonen noch Sommerzeit. Ohne diese Daten ist jedoch jede Zeit-Angabe unbestimmt. Man muss selbst für korrekte Daten bzw. deren Umrechung sorgen. Korrekturen sind mindestens dann notwendig, wenn man Daten aus mehreren Zeitzonen verwendet, oder Daten mit PC anderer Zonen austauscht, oder wenn man Zeit-Differenzen über die Grenzen der Sommerzeit-Umstellung berechnen will.
Leider bietet Basic offenbar keine Funktionen zum Lesen der Zeitdifferenz zu UTC (timezone offset) oder der aktuellen Sommer/Winter-Zeit, oder zur Umrechnung zwischen Lokalzeit und UTC.
Es ist absurd, dass man diese wichtigen Daten mühsam suchen muss, um die Weltzeit zu berechnen.
Darüber hinaus gibt es keine Möglichkeit, diese Daten mit zumutbarem Aufwand unabhängig vom Betriebssystem zu gewinnen.
Hier werden getrennte Methoden für Linux und Windows vorgestellt.

Windows

Die Registry-Datenbank enthält die Daten der Zeitzone:
Das Programm regedit.exe ist in jedem Windows-System enthalten und bietet einen manuellen Zugang zur Registry-Datenbank.
Verwenden sie es nur zum Lesen der Daten - Änderungen der Registry können die Funktion von Programmen oder System beschädigen !

In disem Registry-Objekt befinden sich die Schlüssel (keys):
HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentontrolSet \ Control \ TimeZoneInformation
Schlüssel:
Namen StandardName, DaylightName der Zeitzone: Hier sind kaum brauchbare deutschen Langnamen enthalten ('Westeuropäische Sommerzeit' statt 'MEZ' oder 'CET').
Schlüssel Bias enthält den Timezone Offset in Minuten, das ist für CET (konstant) -60.
Schlüssel DaylightBias enthält die zusätzliche (!) Differenz bei Sommerzeit in Minuten, das ist für fast alle Zonen -60.
Schlüssel ActiveBias enthält die aktuelle Differenz zur Weltzeit UTC in Minuten. Dieser Wert beträgt für CET @ Normalzeit -60, bei Sommerzeit -120.
Umrechnung (Einheiten berücksichtigen):
UTC = Zonenzeit - Bias - DaylightBias
UTC = Zonenzeit - ActiveBias
Vorzeichen der Differenz: Je weiter östlich ein Ort, desto später ist es dort. Der Zahlenwert der CET (MEZ) ist daher stets um 1 oder 2 Stunden größer als UTC (Greenwich).

Es gibt mehrere Möglichkeiten, mit Basic Daten aus der Registry zu lesen. Dieses Beispiel liefert die aktuelle Differenz zur Weltzeit UTC in Stunden:
Function windows_current_tzoh() As Integer
Dim rk As String
rk = "HKEY_LOCAL_MACHINE\SYSTEM\"
rk = rk & "CurrentControlSet\Control\"
rk = rk & "TimeZoneInformation\ActiveTimeBias"
windows_current_tzoh = -registry_read(rk) / 60
End Function

Private Function registry_read(key As String)
Dim wsh
Set wsh = CreateObject("WScript.Shell")
registry_read = wsh.RegRead(key)
End Function
Die Hilfs-Funktion registry_read() kann (nur auf Windows !) beliebige Daten der Registry lesen und für Basic-Funktionen verfügbar machen.
Ein anderes Registry-Objekt enthält einen Vorrat an Informationen über zahlreiche Zeitzonen:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\TimeZones
In diesem Schlüssel (key) des Objekts sind die Details der Mitteleuropäischen Zeit (MEZ, CET) enthalten:
Central Europe Standard Time

Linux

Auf Lunux gibt es keine Registry-Datenbank und - ebenso wie auf Windows - keine Möglichkeit, die Ausgabe von Konsolen-Programmen (date) zu lesen.
Hier wird gezeigt, wie man eine Umgebungs-Variable TZOH definiert, die man mit beliebigen Programmen lesen kann, z.B. in Basic mit der Standard-Funktion ENVIRON()

Linux Arbeits-PC:
Suchen sie das Start-Programm der Linux-Shell. Das ist (wenn sie als Administrator root angemeldet sind) z.B. eine Text-Datei /etc/bash.bashrc oder als User eine Datei /home/username/.bashrc oder /home/username/.profile - Konsultieren sie dazu das Manual ihrer Linux-Distribution.
Die in dieser Datei enthaltenen Anweisungen werden bei System-Start, bei der User-Anmeldung oder bei jedem Öffnen einer Linux Shell-Konsole ausgeführt.
Fügen sie diese Zeile am Ende der Shell-Start-Datei an:
declare -x TZOH=$(($(date "+%H")-$(date -u "+%H")))
Damit wird die Differenz zwischen den Stunden von Lokalzeit und Weltzeit berechnet und an die Umgebungs-Variable TZOH zugewiesen.

Ein Linux-Server läuft meist lange Zeit ohne Unterbrechung. In diesem Fall tragen sie die Zeile in eine Text-Datei ein, z.B. als /usr/local/bin/tzoh
#!/bin/sh
declare -x TZOH=$(($(date "+%H")-$(date -u "+%H")))
exit 0
Danach lassen sie dieses Script-Programm täglich um 01:00 automatisch ausführen.
Details zur Programmierung der Linux cron-Funktionen

Wenn die Umgebungs-Variable eingerichtet wurde, dann kann man ihren aktuellen Wert an einer Linux-Konsole ausgeben lassen:
# export | grep TZ
sollte mindestens diese Zeile ausgeben
declare -x TZ="1"
Der Wert beträgt für Mitteleuropa/Normalzeit "1", für Sommerzeit "2"

Mit dieser Basic-Funktion kann man den aktuellen Wert des TimeZoneOffset in Stunden lesen:
Function linux_current_tzoh() As Integer
linux_current_tzoh = environ("TZOH")
End Function
Die Basic-Funktion linux_current_tzoh() lässt sich intern (von anderen Basic-Funktionen) oder als 'Benutzer-definierte Funktion' in jedem Kalkulations-Programm (z.B. LibreOffice) verwenden.

Man kann auch auf Windows eine Umgebungs-Variable TZOH einrichten. In diesem Fall ist die Basic-Funktion sogar ohne Änderung portabel. Das gilt allerdings nur dann, wenn auf allen verwendeten PC die Umgebungs-Variable TZOH eingerichtet wurde, und wenn ihr Wert korrekt (2mal jährlich) aktualisiert wird.

Aktuelle Weltzeit UTC

Eine Variante der Funktion current_tzoh() (↑ Windows- und ↑ Linux-Beispiele) gibt die aktuelle (!) Differenz der (Windows)-PC-Systemzeit zur Weltzeit UTC in Stunden zurück.
Damit können sie (nur) das aktuelle Datum in UTC umrechnen:
Now = 0
current_tzoh = 0
utc = Now - tzoh/24 = 0

Der links gezeigte Algorithmus gilt leider nur für aktuelle Daten:
Die Umrechnung beliebigerDaten in UTC ist vergleichsweise kompliziert. Dazu müssen sie feststellen, ob am betreffenden Zeitpunkt gerade Sommerzeit gilt / galt (nächstes ↓ Kapitel).

Normalzeit und Sommerzeit

Die Länge eines Tages beträgt 24 Stunden. Im Sommer geht die Sonne früher auf und später unter. Daran ändert sich nichts, wenn man Mitternacht rechnerisch um 1 Stunde verschiebt. Diese Maßnahme nützt niemandem, kostet jedoch einen enormen Aufwand, um alle Zeiten umzurechnen, alle Uhren umzustellen, Züge anzuhalten, usw. Wenn die Befürworter dieses Schwachsinns für die Folgen bezahlen müssten, dann wäre die Sommerzeit (Daylight savings) wohl bald Vergangenheit. Mittlerweile ist es auch um die damit angeblich eingesparte Energie still geworden...

Sommerzeit Umstellung

Das Beispiel rechts (vereinfacht) berechnet die Umstellungs-Zeitpunkte auf / von Sommerzeit nach derzeitigen EU-Regeln.
Der Wechsel von Normalzeit auf Sommerzeit erfolgt am letzten Sonntag im März um 01:00 UTC = 02:00 CET
Der Wechsel von Sommerzeit auf Normalzeit erfolgt am letzten Sonntag im Oktober um 01:00 UTC = 03:00 CET(Sommerzeit).

Die Hilfs-Funktion dls_refdate() benötigt als Argumente Jahr, Monat (nur 3 oder 10) und einen Options-Schalter.
Zuerst wird ein anderes Bezugsdatum berechnet, nämlich für Monat mo=3 der 1.April, für mo=10 der 1.November.
Von diesem Tag wird der Wochentag wref nach ISO-Standard berechnet.
Daraus lässt sich mit der Standardfunktion DateSerial() der vorangegangene Sonntag berechnen, mit Funktion TimeSerial() die Zeit 01:00:00.
Damit ist der gewünschte Umstellungs-Zeitpunkt in UTC (!) berechnet.

Der Rest des Beispiels rechnet den Zeitpunkt ref auf Lokalzeit um, wenn das Argument utc_loc>0 ist. Dazu wird mit Funktion get_current_tzoh() die Differenz der lokalen Zeitzone in Stunden gelesen, für Oktober zusätzlich die Differenz der Sommerzeit. Beispiele für diese Hilfs-Funktion finden sie im ↑ vorigen Kapitel, leider getrennt für Linux und Windows.

Function dls_refdate(yyyy, mo, utc_loc)
Dim ref As Double
Dim tzoh, wref As Integer
Dim rk As String
  ' Calculate RefDate UTC
ref = DateSerial(yyyy, mo + 1, 1)
wref = Weekday(ref, vbMonday)
ref = DateSerial(yyyy, mo + 1, 1 - wref)
ref = ref + TimeSerial(1, 0, 0)
' Calculate LocalTime
If (utc_loc> 0) Then
tzoh = get_current_tzoh()
If mo = 10 Then
tzoh = tzoh + get_dloh()
End If
ref = ref + TimeSerial(tzoh, 0, 0)
End If
dls_refdate = ref
End Function
Hilfsfunktion get_dloh() berechnet die konstante zusätzliche Differenz der Sommerzeit in Stunden. Auch dieser Wert wird zweckmäßig nur einmal gelesen und gespeichert.
Derzeit beträgt dieser Wert für ganz Europa und die meisten anderen Staaten 1 Stunde, unabhängig von der Zeitzone. Mit dem Ende der Sommerzeit-Regel wird dieser Wert wieder 0 betragen.
Function get_dloh As Integer
Dim rk As String
rk = "HKEY_LOCAL_MACHINE\SYSTEM\"
rk = rk & " CurrentControlSet\Control\"
rk = rk & " TimeZoneInformation\DaylightBias"
get_dloh = - registry_read(rk) / 60
End Function
Live-Beispiel: Umstellung auf Sommerzeit in UTC:
ref3 = dls_refdate(0000,3,0) = 0
y1900_to_iso(ref3) = 0000-00-00 00:00:00
Die Funktion gibt ein Datum im Y1900-Format zurück, dieses wird zur Anzeige in das Standard → ISO-8601-Format umgewandelt.
Live-Beispiel: Umstellung auf Normalzeit in Lokalzeit (!):
ref10 = dls_refdate(0000,10,1) = 0
y1900_to_iso(ref10) = 0000-00-00 00:00:00
Das Datum im Y1900-Format können sie sowohl in Basic als auch in einem Kalkulations-Programm direkt weiter verarbeiten.

Umrechnung Lokalzeit → UTC

Die konstante Differenz der lokalen Zeitzone wird in jedem Falle korrigiert, das ist für CET +1 Stunde.
Bei Sommerzeit wird zusätzlich die Sommerzeit-Differenz (+1 Stunde) korrigiert. Dazu vergleicht man den betreffenden Zeitpunkt mit den Sommerzeit-Umstellungs-Daten (s.o.).

In der Praxis wird diese Funktion komplizierter ausgeführt, läuft jedoch wesentlich schneller: Für die Monate 1..2 und 11..12 gilt immer die Normalzeit, für die Monate 4..9 immer die Sommerzeit.
Nur März und Oktober erfordern eine genauere Analyse: Bis 24.März gilt immer Normalzeit, bis 24.Oktober immer Sommerzeit.
Nur für die wenigen verbleibenden Tage muss tatsächlich der Vergleich mit einem der beiden Umstellungs-Daten berechnet werden.

Function localdate_to_utc(localdate)
Dim yyyy, tzoh As Integer
Dim ref3, ref10 As Double
tzoh = get_tzoh()
yyyy = Year(localdate)
ref3 = dls_refdate(yyyy, 3, 1)
ref10 = dls_refdate(yyyy, 10, 1)
If (localdate - ref3) > 0 And (localdate - ref10) < 0 Then
tzoh = tzoh + get_dloh()
End If
localdate_to_utc = localdate - TimeSerial(tzoh, 0, 0)
End Function

Umrechnung UTC → Lokalzeit

Die Funktion arbeitet ganz ähnlich wie das oben vorgestellte Beispiel localdate_to_utc()
Die Umstellungs-Daten für den Vergleich müssen in diesem Fall als UTC-Zeiten vorliegen, also jeweils um 01:00:00 UTC.

Auch diese Funktion wird in der Praxis anders ausgeführt: Die meisten Fälle werden mit Hilfe einfacher bedingter Verzweigungen wesentlich rascher erledigt. Nur wenige Tage erfordern tatsächlich den Vergleich mit einem der beiden Umstellungs-Daten.
Function utc_to_localdate(utc)
Dim yyyy, tzoh As Integer
Dim ref3, ref10 As Double
tzoh = get_tzoh()
yyyy = Year(localdate)
ref3 = dls_refdate(yyyy, 3, 0)
ref10 = dls_refdate(yyyy, 10, 0)
If (utc - ref3) > 0 And (utc - ref10) < 0 Then
tzoh = tzoh + get_dloh()
End If
utc_to_localdate = utc + TimeSerial(tzoh, 0, 0)
End Function

Unix-Timestamp:   Sekunden seit   1970-01-01 00:00:00 UTC

UNIX-Systeme (z.B. Linux), Datenbanken und die meisten modernen Programmiersprachen verwenden zur internen Darstellung und zur Berechnung von Datum & Zeit UNIX-Zeitstempel (TimeStamp). Sie geben die Anzahl Sekunden seit 1970-01-01 UTC an.
Durch Verwendung der Weltzeit UTC ist ein Timestamp unabhängig von Ort (Zeitzone) und Datum (Sommerzeit).

Das Beispiel rechts berechnet einen Unix-Timestamp aus dem aktuellen Y1900-Datum Lokalzeit:
Der Faktor 25569 entspricht dem Y1900-Wert von 1970-01-01, 86400 ist die Anzahl Sekunden pro Tag, tzoh die Zeitdifferenz zwischen Lokalzeit und UTC in Stunden (timezone offset).
Da Y1900 keine Information von Zeitzone und Sommerzeit enthält, muss diese zur Umrechnung zusätzlich herangezogen werden - In diesem Fall durch das Argument tzoh, welches in Mitteleuropa (CET, MEZ) bei Normalzeit 1 beträgt, bei Sommerzeit 2.
Berechnung eines UNIX-Timestamp aus einem Y1900-Datum:
Function y1900_to_uts(y1900, tzoh)
uts = (y1900 - tzoh / 24 - 25569) * 86400
End Function

Live-Ergebnis:
y1900_to_uts(Now,0) = 0
Dieses Beispiel berechnet ein Y1900-Datum in Weltzeit UTC aus einem Unix-Timestamp.
Function uts_to_y1900_utc(uts)
uts_to_y1900_utc = uts / 86400 + 25569
End Function
Live-Ergebnis:
uts = 0
uts_to_y1900_utc(uts) = 0
Dieses Beispiel berechnet ein Y1900-Datum in Lokalzeit aus einem Unix-Timestamp.
Zur Berechnung ist die Angabe der jeweils gültigen Zeitdifferenz notwendig - abhängig von der Sommerzeit !
Details dazu finden sie auf dieser Seite in den Kapiteln ↑ Zeitzonen und ↑ Sommerzeit.
Function uts_to_y1900_loc(uts, tzoh)
uts_to_y1900_loc = uts / 86400 + 25569 + tzoh / 24
End Function
Live-Ergebnis:
uts = 0
uts_to_y1900_loc(uts,0) = 0
Details zu diesem Thema finden sie auf den Seiten Datum und Zeit und SQL-Timestamp

Julianischer Tag (Julian Day, JD) und Modifizierter julianischer Tag (MJD)

Der Julianische Tag (JD) ist ein System zur gemeinsamen Darstellung von Datum und Zeit in einer einzigen Gleitkomma-Zahl.
Dieses System verwendet als Einheit Tage (ebenso wie Y1900), als Nullpunkt -4712-01-01.
JD wird immer in Weltzeit UTC angegeben und ist daher unabhängig von Ort (Zeitzone) und Datum (Sommerzeit).
Mit JD kann man besonders gut über sehr lange Zeiträume hinweg rechnen.
In der Astronomie wird zur Angabe von Datum und Zeit häufig der Julianische Tag (Julian Day, JD) verwendet.
In der Astro-Literatur und in Astro-Webs finden sie Algorithmen (Rechen-Vorschriften) zur Berechnung des JD aus den Bestandteilen (yy-mo-dd hh:mi:ss) und umgekehrt.
Der Modifizierte Julianische Tag (MJD) ist eine Praxis-freundliche Variante von JD, die vorwiegend für neuere historische Daten verwendet wird.

Y1900 JD

Für jedes Datum >= 1900-03-01 kann man den Julianischen Tag bequem aus dem Y1900-Wert berechnen, der von allen gängigen Microsoft-Programmen geliefert wird.

Mit LibreOffice oder OpenOffice kann man das Y1900-Datum und damit auch die gezeigte Basic-Funktion bereits ab >= 1582-12-01 verwenden.
Für weiter zurückliegende Daten muss man den Algorithmus des nächsten Absatzes verwenden.

Leider liefert keines der Standard Kalkulations-Programme die Weltzeit UTC. Die Differenz beträgt in Mitteleuropa 1 Stunde (1/24 Tag), bei Sommerzeit 2 Stunden.
Function y1900_to_jd(y1900)
y1900_to_jd = y1900 + 2415018.5
End Function
Anwendung in einem Kalkulations-Programm:
(Aktuelle Daten mit Taste F9)
   ABC
1 2415018,5 
2DatumJD
3 =JETZT()-1/24 =A3+$B$1 =y1900_to_jd(A3)
4=DATUM(1900;3;1)=A4+$B$1 =y1900_to_jd(A4)
5=DATUM(1582;12;1)=A5+$B$1 =y1900_to_jd(A5)

JD Y1900

Aus dem Julianischen Tag JD kann man umgekehrt auch den Y1900-Wert ab den gleichen Untergrenzen berechnen, wie oben angegeben.
Function jd_to_y1900(jd)
jd_to_y1900 = jd - 2415018.5
End Function

yyyy,mo,dd,hh_utc,mi,ss JD

Dieses Beispiel berechnet den JD aus den Bestandteilen
Jahr, Monat, Tag, Stunden (Weltzeit UTC !), Minuten, Sekunden.
Der Algorithmus wurde aus verschiedenen Quellen entnommen und modifiziert.

Jahre "unserer Zeit" (Anno Domini, AD oder "current era" CE) werden als positive Jahreszahlen eingegeben. Jahre "vor unserer Zeit" (Before Christ, BC) werden als negative Jahreszahlen eingegeben.
Das Jahr yyyy=0 ist nicht zulässig.

Die Tages-Grenze von JD liegt bei 12:00 mittags - Um diese Zeit treten ganzzahlige JD-Werte auf.

Für die Berechnung sind keine Grenzen gesetzt, d.h. es werden auch negative JD berechnet - Man kann mit ihnen auch bequem rechnen, z.B. Differenzen bilden.

Die Hilfsfunktion symfloor() finden sie weiter unten.

Live-Test (hier mit Javascript berechnet)
JD(Heute) = 0
JD(Jetzt) = 0
Function jd( _
yyyy As Double, mo As Double, dd As Double, _
Optional hh As Double = 0, _
Optional mi As Double = 0, _
Optional ss As Double = 0) As Double
' Use UTC !
Dim gregdat, ja, ma, t As Double
gregdat = 588828
' year
If (yyyy<0) Then yyyy = yyyy + 1
' month
ma = 0
If (mo>2) Then
ma = mo + 1
Else
yyyy = yyyy - 1
ma = mo + 13
End If
' calculate jd
jd = Int(365.25 * yyyy) + Int(30.6001 * ma) + dd + 1720995
' correct greg
If ((dd+31*(mo+12*yyyy)) >= gregdat) Then
ja = symfloor(yyyy / 100)
jd = jd + 2 - ja + symfloor(ja / 4)
End If
' time
t = (hh + mi / 60 + ss / 3600) / 24
jd = jd - 0.5 + t
End Function

JD yyyy,mm,dd,hh_utc,mi,ss iso

Dieses Beispiel berechnet die ganzzahligen Datum und Zeit-Bestandteile aus einem JD.

Da eine Funktion nur einen einzigen Wert zurückgeben kann, wird hier ein Text (String) nach ISO-Norm erstellt (Details dazu auf dieser Seite unter ISO-8601).

Aus den Bestandteilen yyyy...ss könnte man mit den Basic Standard-Funktionen DateSerial() und TimeSerial() auch eine Y1900-Variable berechnen, allerdings nur für einen sehr kleinen Teil des (theoretisch unendlich) großen JD-Bereichs.

Die Beispiel-Funktion jd_to_iso() gibt UTC (Weltzeit) als String nach dem Standard ISO-9601 zurück.

Details zur Umrechnung auf Lokalzeit auf dieser Seite unter UTC, Zeitzonen, Sommerzeit.
Function jd_to_iso(jd) As String
Dim rest, y400, y100, y4, y1, mx As Double
Dim yyyy, mo, dd, hh, mi, ss As Double
Dim iso As String
' Schaltjahre
rest = jd + 32044
y400 = Int(rest / 146097)
rest = dmod(rest, 146097)
y100 = mymin(3, Int(rest / 36524))
rest = rest - 36524 * y100
y4 = Int(rest / 1461)
rest = dmod(rest, 1461)
y1 = mymin(3, Int(rest / 365))
rest = rest - 365 * y1
' Datum
yyyy = (y400 - 12) * 400 + y100 * 100 + y4 * 4 + y1
mx = Int((rest * 111 + 41) / 3395)
rest = rest - 30 * mx - Int((mx + 1) * 7 / 12) + 1
dd = Int(rest + 0.5)
mx = mx + 3
mo = ((mx + 11) Mod 12) + 1
yyyy = yyyy + Int(mx / 13)
' Zeit
rest = (rest - dd) * 24
hh = Int(rest)
rest = (rest - hh) * 60
mi = Int(rest)
rest = (rest - mi) * 60
ss = Round(rest)
hh = hh + 12
' String
jd_to_iso = ymdhms_to_iso(yyyy, mo, dd, hh, mi, ss)
End Function

Y1900 MJD Y1900

Gültige Y1900-Werte und gültige MJD-Werte kann man direkt umrechnen. Lediglich für außerhalb liegende Daten muss man den Umweg über JD (nächster Absatz) wählen.
Function y1900_to_mjd(y1900)
y1900_to_mjd = y1900 + 15018
End Function

Function mjd_to_y1900(mjd)
mjd_to_y1900 = mjd - 15018
End Function

yyyy,mm,dd MJD

Das Modifizierte Julianische Datum (MJD) ist eine Praxis-nahe Variante des JD. Sie beschreibt ein Datum im Bereich 1858-11-17 .. 2132-08-31 mit einer 5stelligen ganzen Dezimalzahl.
MJD wird u.a. für neuere historische und für aktuelle Datum-Werte eingesetzt.
Das Funktionsbeispiel rechts berechnet den aktuellen MJD für heute.
Function mjd(yy, mo, dd)
mjd = jd(yy, mo, dd, 0, 0, 0) - 2400000.5
End Function

Live-Test (hier mit Javascript berechnet):
MJD(Heute) = 0

MJD yyyy,mm,dd iso

Da eine Funktion nur einen einzigen Wert zurückgeben kann, weren die Datum-Bestandteile als Text (String) nach Standard → ISO-8601 verpackt.
Function mjd_to_iso(mjd)
Dim jd As Double
jd = mjd - 2400000.5
mjd_to_iso = jd_to_iso(jd)
End Function
Diese Hilfsfunktionen werden von den JD-Beispielen verwendet:

Private Function symfloor(x)
If (x < 0) Then
symfloor = -Int(-x)
Else
symfloor = Int(x)
End If
End Function
Private Function dmod(a, b)
dmod = a - Int(a / b) * b
End Function

Private Function mymin(a, b)
If (b < a) Then
mymin = b
Else
mymin = a
End If
End Function
Details zum Thema Datum und Zeit und zu Funktionen ganzer Zahlen (floor, modulo, ...)

ISO 8601 - Der Internationale Standard für Datum und Zeit

Dieser Standard ist das Ergebnis der Bestrebungen, die Formulierung von Datum und Zeit international einheitlich und unmissverständlich festzulegen. ISO-8601 ist unabhängig von Sprache, Kultur, Betriebssystem, Hersteller oder Programm. Datum und Zeit haben das String-Format
YYYY-MM-TT hh:mm:ss
Live (Lokalzeit):
0000-00-00 00:00:00
ISO-8601 wird von allen modernen Programmen unterstützt, z.B. von LibreOffice.
Der Standard wird von älteren MS-Programmen ignoriert und von neueren Versionen zwar angeboten, jedoch (meist unter dem Namen 'International') gut versteckt.
Immerhin kann man das ISO-Format in jedem Fall als Benutzer-spezifisches Format JJJJ-MM-TT hh:mm:ss eingeben.
Tipp: Um Datum und/oder Zeit in der Zelle eines Kalkulations-Blatts anzuzeigen, ist es nicht notwendig, einen String zu erstellen. Tragen sie den Wert als Y1900-Gleitkomma-Zahl ein und formatieren sie die Zelle mit Menü Format | Zellen | Datum / Uhrzeit. Tipp: Zur Codierung und Decodierung von Datum- und Zeit-Strings eignen sich besonders gut → Reguläre Ausdrücke ! - Diese Methoden werden von allen modernen Programmiersprachen ausser von Basic unterstützt ...
Dieses Beispiel kann man verwenden, um Basic-Datum-Zeit-Daten in das ISO-Format umzuwandeln.

Als Varianten kann man Funktionen erstellen, um nur das Datum oder nur die Zeit nach ISO-8601 zu codieren, bzw. um diese Strings aus einem ISO-8601-Datum zu extrahieren.
Function y1900_to_iso(mydate) As String
Dim iso As String
iso = Year(mydate)
iso = iso & "-" & _
Right("00" & Month(mydate), 2)
iso = iso & "-" & _
Right("00" & Day(mydate), 2)
iso = iso & " " & _
Right("00" & Hour(mydate), 2)
iso = iso & ":" & _
Right("00" & Minute(mydate), 2)
iso = iso & ":" & _
Right("00" & Second(mydate), 2)
y1900_to_iso = iso
End Function
Details zu diesem Thema auf der Seite ISO-8601t

Kulturspezifische Unterschiede bei Datum und Zeit

Verwenden sie bei der Erstellung eigener Programme keinesfalls kultur-spezifische Teile, sondern folgen sie in allen Fällen dem internationalen Standard → ISO-8601.
Auch ihre KundInnen werden früher oder später vorteilhaft das ISO-Format verwenden.
Falls sie davon abweichende Formate/Regeln verwenden wollen/müssen, dann leiten sie diese in Zusatz-Funktionen aus dem Standard ab.
So können sie später problemlos weitere Formate hinzufügen, oder überholte Formate wieder entfernen.
Die Namen der Monate und Wochentage sind naturgemäß je nach verwendeter Sprache verschieden.
Kleine Feinheiten bleiben manchmal unentdeckt: In Deutschland wird z.B. 'Januar' verwendet, in Österreich 'Jänner'.
Bei Import oder Eingabe von Text-Daten in ein Kalkulations-Programm (z.B. MS-Excel) wird z.B. 'Januar 2000' als Datum erkannt, 'Jänner 2000' jedoch manchmal als Text - das ergibt schwer zu findende Fehler.

Für den Transport / Austausch bestimmte Daten dürfen daher weder Monats- noch Tages-Namen enthalten !

Verwenden sie vorzugsweise den international eindeutigen Standard → ISO-8601 oder gar keine Strings, sondern ↑ Ganze Zahlen für die üblichen 6 Bestandteile (yyyy, mo, dd, hh, mi, ss).

Jahr, Monat und Tag.

Die Reihenfolge der Bestandteile in Datum-Strings ist kulturspezifisch:
In Europa verwendet man Tag-Monat-Jahr, in den USA Monat-Tag-Jahr, sowie unterschiedliche Trennzeichen.
Bei Tages-Zahlen<=12 kann das zu unangenehmen Verwechslungen führen.
Eine salomonische und weltweit eindeutige Lösung ist die hierarchische Angabe nach → Standard ISO-8601: JJJJ-MM-TT

Live: Das heutige Datum:
ISO-8601-Format
2000-01-01
Europa-Format
1.1.2000
US-Format
1/1/2000

Kalenderwoche:

Im kommerziellen Bereich ist die Angabe der Kalenderwoche (z.B. für Liefertermine) üblich. Das Beispiel rechts berechnet die KW nach ISO-Standard (ohne Gewähr !):
Weltweit und nach ISO-Standard beginnt die Woche am Montag
Nach Standard ISO-8601 ist die erste Kalenderwoche eines Jahres diejenige, von welcher mindestens 4 Tage im neuen Jahr liegen. Ein Jahr kann 52 ... 53 KW umfassen.
Manche Staaten (USA, einige neue EU-Mitglieder) verwenden abweichende Definitionen, in ca. 3% aller Jahre gibt es sogar KW54.

Die USA verwenden natürlich andere Regeln:
US-Wochen beginnen am Sonntag
Die erste Kalenderwoche beginnt am 1.Jänner
Deshalb kann es am Anfang und am Ende eines Jahres kürzere Wochen-Fragmente geben.
Vorsicht - manche Programme verwenden US-Regeln, ohne das anzugeben ! Die Excel-Funktion 'Kalenderwoche' liefert z.B. (derzeit) völlig unbrauchbare Resultate.

Lassen sie die Kalenderwoche beim Transport von Daten weg und überlassen sie dem Zielprogramm die Berechnung der jeweiligen Kalenderwoche aus dem Datum.
Function kw(y1900) As Integer
Dim dref As Long
dref = kw_ref(Year(y1900))
kw = (y1900 - dref) \ 7 + 1
If kw < 1 Then
dref = kw_ref(Year(y1900) - 1)
kw = (y1900 - dref) \ 7 + 1
End If
End Function

Function kw_ref(yyyy) As Integer
Dim wref As Integer
Dim dref As Long
dref = DateSerial(yyyy, 1, 4)
wref = Weekday(dref, vbMonday)
kw_ref = dref - wref + 1
End Function

Live-Daten:
Aktuelle KW (ISO-Standard)
0
und in den USA
0

Tag des Jahres:

Dieser Wert ist nicht kultur-spezifisch, zumindest für alle Staaten, in welchen der international übliche Gregorianische Kalender verwendet wird. Die Funktion passt jedoch in dieses Kapitel.
Live: day_of_year = 0
Function day_of_year(y1900) As Integer
Dim y1 As Integer
Dim d1 As Long
d1 = DateSerial(Year(y1900), 1, 1)
day_of_year = y1900 - d1 + 1
End Function

Wochentag:

Es ist klar, dass die Namen der Wochentage verschieden je nach Sprache sind. Deren unterschiedliche Zählung ist weniger bekannt:
Die laufende Wochentag-Nr wird nach Standard ISO-8601 von Mo→1, Di→2, ... So→7 gezählt.
Die USA verwenden So→1 bis Sa→7, manche Programme So→0 bis Sa→6.
Die Basic-Function Weekday(date,f) muss daher mit f=2 verwendet werden, ähnlich wie die Kalkulations-Funktion WOCHENTAG().
Wochentags-Nr lassen sich gut aus dem JD berechnen. Das funktioniert auch für Jahre<1900 und >10000. Rechts ein Muster für den einfachen Algorithmus.

Lassen sie die Wochentag-Nummer beim Transport von Daten weg und überlassen sie dem Zielprogramm die Berechnung des jeweiligen Wochentages nach den jeweiligen lokalen Vorgaben.

Wenn sie den Wochentag nur anzeigen, jedoch nicht berechnen wollen, dann bieten Kalkulations-Programme dazu das Format 'TTT': Von jedem Datum (im internen Y1900-Format) wird dann nur der Wochentag angezeigt.
Ermittlung des aktuellen Wochentags:
Function weekday_now() As String
Dim wdnr as Integer
wdnr = Weekday(Now, 2)
weekday_now = Choose(wdnr, _
"Mo", "Di", "Mi", "Do", "Fr", "Sa", "So")
End Function

Berechnung der Wochentags-Nummer aus dem JD (Julian Day):
Function jd_to_wdnr(jd) As Integer
jd_to_wdnr = (jd + 1.5) Mod 7
If (jd_to_wdnr = 0) Then jd_to_wdnr = 7
End Function

Heute ist ?Tag, daher
Tag-Nr (Standard)
0
und in den USA
0

Tageszeit:

Die Angabe der Tageszeit erfolgt weltweit im Standard 24-Stunden-Format.
Nur die USA verwenden immer noch das 12-Stunden-Format mit den Zusätzen "AM" (vormittags) und "PM" (nachmittags).
Vor 12:00 gilt "AM", danach "PM"
Erst ab 13:00 wird die Stunde um 12 vermindert angezeigt.
Von 00:00 bis 00:59 früh werden 12 Stunden angezeigt.

Viel Geld ist bereits für die Umrechnung dieser Angaben verschwendet worden, viel wird wohl noch nachfolgen.
Hier wird kein Basic-Beispiel gezeigt, da Kalkulations-Programme wie LibreOffice oder MS-Excel die Zeit sowohl im Standard- als auch im US-Format anzeigen können.
Die aktuelle Zeit und einige charakteristische Zeiten:
StandardUS-Format
00:00:00
00:00:00 AM
00:30:0012:30:00 AM
01:30:0001:30:00 AM
11:30:0011:30:00 AM
12:30:0012:30:00 PM
13:30:0001:30:00 PM
Details zu diesem Thema im Kapitel Datum und Zeit

Das Basic-Ereignis (Event) OnTime

Application.OnTime

Mit dem → Event OnTime kann man Aktionen zu einem vor-bestimmten Zeitpunkt auslösen.

Das erste Beispiel legt fest, das Sub test() zur 'absoluten Zeit' um 17:00 aufzurufen.
Als Argumente setzt man die frühest-gewünschte Ausführungszeit und das auszuführende Sub ein.
Ein Programm kann zum gewünschten Zeitpunkt beschäftigt (busy) sein - In diesem Fall wartet die Ausführung (sie können zusätzlich auch einen spätesten Zeitpunkt angeben).

Das 2. Beispiel zeigt, wie man ein gesetztes OnTime-Event ändert - Hier wird das Ereignis mit Schedule=False wieder gelöscht.

Wenn man sich auf die korrekte Einstellung einer (fremden) PC-Uhr nicht verlassen kann, dann ist die Angabe relativer Zeiten vorteilhaft. Sie sehen das im Beispiel 'Ausführung nach 15 Sekunden'.
' Ausfuehrung um 12:30
Application.OnTime TimeValue("17:00:00"), "test"
' Aenderung (Loeschen des Auftrags):
Application.OnTime EarliestTime:=_
TimeValue("12:30:00"), _
Procedure:="test", _
Schedule:=False
' Ausfuehrung nach 15 Sekunden:
Application.OnTime Now + TimeValue("00:00:15"), "test"
' Mehrere Events ausloesen:
Application.OnTime Now + TimeValue("00:00:30"), "test"
Application.OnTime Now + TimeValue("00:01:00"), "test"

Sub test()
MsgBox ("Jetzt = " & Now)
End Sub

Jede Sekunde ...

Das Beispiel schreibt laufend die aktuelle Zeit in eine Zelle eines Kalkulations-Blatts.

Vergeben sie den Namen zeit für eine Zelle:
Zelle markieren, Menübefehl Einfügen | Namen | Definieren | zeit
Tragen sie die Zahl 0,5 ein und formatieren sie mit Menübefehl Format | Zellen | Uhrzeit | 13:30:55 (oder ähnlich). Die Zelle sollte 12:00:00 anzeigen.

Tragen sie die Beispiele in ein Basic-Modul ein:
Die globale Variable run steuert die laufende Anzeige.
Sub do_start() startet die Anzeige, Sub do_stop() beendet sie.
Sub jede_sekunde() trägt die aktuelle Zeit in Zelle zeit ein und ruft sich nach Ablauf von 1 sec mit Methode OnTime selbst auf.

Erzeugen sie 2 Bildschirm-Tasten: Menübefehl Ansicht | Symbolleisten | Formular, Klicken sie auf Schaltfläche und ziehen sie mit der Maus eine Tasten-Objekt auf. Die erste Taste erhält die Ausfschrift Start und mit Rechtsklick | Makro zuweisen das Programm do_start()
An die zweite Taste mit der Aufschrift Stop wird das Programm do_stop() zugewiesen.

Das Programm jede_sekunde() führt die eigentliche Arbeit aus und schreibt die aktuelle Zeit in die Zelle. Danach wird ein Timer gesetzt, der das Programm nach 1 sec erneut startet usw.

Bei jedem automatisch ablaufenden Programm sollte ein Abbruch vorgesehen werden. Das Sub do_stop() setzt die globale Variable run=False und stoppt damit die laufende Anzeige.
Dim run As Boolean

Sub do_start()
run = True
Call jede_sekunde
End Sub

Sub do_stop()
run = False
End Sub

Sub jede_sekunde()
If run Then
Range("zeit").Value = Time
Application.OnTime Now + TimeValue("00:00:01"), "jede_sekunde"
End If
End Sub

TimeValue()

Die verwendete Funktion TimeValue() wandelt einen Zeit-String in eine Y1900-Variable um. Sie wird für bessere Anschaulichkeit verwendet. Wenn das nicht notwendig ist, verwendet man besser direkt die Y1900-Zahlen.
TimeValue("12:00:00") = 12/24 = 0.5
TimeValue("01:00:00") = 1/24 = 0.0416667
TimeValue("00:01:00") = 1/24/60 = 0.0006944

Ausgewählte Links zum Thema 'Basic @ Datum & Zeit'

  Visual Basic 2005 Handbuch (Andreas Kühnel / Galileo) - .NET-DateTime

Letzte Änderung dieser Seite: 2012-02-29 23:01:56