@REM Routine berechnet verschiedene Datumsfelder und gibt diese als Environment-
@REM variablen zurück (Prefix DATE_). Wird die Routine ohne Parameter aufgerufen,
@REM wird das aktuelle Datum verwendet. Ansonsten wird der übergebene Parameter
@REM als Datum (Format: TT.MM.JJJJ) interpretiert und zerlegt. Wenn alles ohne
@REM Fehler gelaufen ist, enthaelt die Variable DATE_STATUS den Wert "OK" (ohne
@REM Anfuehrungszeichen). Wenn nicht, eine Fehlerbeschreibung, die z.B. mit Echo
@REM ausgegeben werden kann.  Routine muß mit CALL GETDATE aufgerufen werden.
@REM Variablen:
@REM    DATE_KURZ          kurzes Datum (z.B.: 02.05.1999)
@REM    DATE_LANG          langes Datum (z.B.: Montag, 2.Mai 1999)
@REM    DATE_TAG           Tag (0 bis max. 31)
@REM    DATE_MONAT         Monat (1 bis 12)
@REM    DATE_JAHR          Jahr (1900 bis ...)
@REM    DATE_MONAT_NAME    Monatsname (Januar, Februar, Maerz, April, usw.)
@REM    DATE_WOCHENTAG     Wochentagsname (Montag, Dienstag, Mittwoch, Donnerstag, usw,)
@REM    DATE_WOCHE         Kalenderwoche (1 bis 52)
@REM    DATE_SCHALTJAHR    0: Jahr ist kein Schaltjahr; 1: Jahr ist ein Schaltjahr
@REM    DATE_TAGE          der vievielte Tag seit dem 1.1 im gleichen Jahr
@REM    DATE_TAGE_1900     der wievielte Tag seit dem 1.1.1900
@REM    DATE_STATUS        OK: Datum konnte korrekt zerlegt werden
@REM
@REM Routine wurde von D.Eberth am 22.11.1999 erstellt
@REM
@REM Aenderungen:
@REM	02.11.2003  D.Eberth	angepasst für Windows XP
@REM	23.09.2003  D.Eberth	angepasst für Windows 2003
@REM
@ECHO OFF

SET DATE_STATUS=unbekannter Fehler
SET DATE_TAG=
SET DATE_MONAT=
SET DATE_JAHR=
SET DATE_MONAT_NAME=
SET DATE_WOCHENTAG=
SET DATE_WOCHE=
SET DATE_SCHALTJAHR=
SET DATE_TAGE=
SET DATE_TAGE_1900=
SET DATE_STATUS=

REM wenn kein Parameter übergeben wurde, das aktuelle Datum verwenden (unter XP hat sich das Format geändert)
VER | FINDSTR /I /C:"Version 5.1" >nul:
IF %ERRORLEVEL% EQU 0 IF [%1] == [] FOR /F "tokens=1,2,3 delims=/. " %%i IN ('date /t') DO CALL :berechne %%i %%j %%k& GOTO weiter
VER | FINDSTR /I /C:"Version 5.2" >nul:
IF %ERRORLEVEL% EQU 0 IF [%1] == [] FOR /F "tokens=1,2,3 delims=/. " %%i IN ('date /t') DO CALL :berechne %%i %%j %%k& GOTO weiter
IF [%1] == [] FOR /F "tokens=2,3,4 delims=/. " %%i IN ('date /t') DO CALL :berechne %%i %%j %%k

:weiter
REM ansonsten das übergebene Datum (z.B. 29.1.1987) verwenden
IF NOT [%1] == [] FOR /F "tokens=1,2,3 delims=./" %%i IN ("%1") DO CALL :berechne %%i %%j %%k

SET DATE_TEMP=
SET DATE_TEMP2=
SET DATE_TEMP3=

GOTO :eof



:berechne

REM zuerst überprüfen, ob Tag, Monat oder Jahr fehlen 
IF NOT [%1] == [] GOTO :ok1
SET DATE_STATUS=Tag fehlt [??.%2.%3]
GOTO :eof
:ok1
IF NOT [%2] == [] GOTO :ok2
SET DATE_STATUS=Monat fehlt [%1.??.%3]
GOTO :eof
:ok2
IF NOT [%3] == [] GOTO :ok3
SET DATE_STATUS=Jahr fehlt [%1.%2.??]
GOTO :eof
:ok3


REM jetzt prüfen, ob der Tag im Bereich 1 bis 31 liegt (genauere Prüfung folgt später)
IF %1 EQU 08 SET /A DATE_TAG=8 & GOTO :ok4
IF %1 EQU 09 SET /A DATE_TAG=9 & GOTO :ok4
IF %1 GEQ 1 IF %1 LEQ 31 SET /A DATE_TAG=%1 & GOTO :ok4
:err1
SET DATE_STATUS=ungueltiger Tag: %1
GOTO :eof
:ok4


REM jetzt prüfen, ob der Monat im Bereich 1 bis 12 liegt
IF %2 EQU 08 SET /A DATE_MONAT=8 & GOTO :ok5
IF %2 EQU 09 SET /A DATE_MONAT=9 & GOTO :ok5
IF %2 GEQ 1 IF %2 LEQ 12 SET /A DATE_MONAT=%2 & GOTO :ok5
SET DATE_STATUS=ungueltiger Monat: %2
GOTO :eof
:ok5


REM jetzt prüfen, ob Jahreszahl korrekt ist (grösser gleich 1900)
IF %3 GEQ 1900            SET /A DATE_JAHR=%3      & GOTO :ok6
IF %3 GEQ 80 IF %3 LEQ 99 SET /A DATE_JAHR=%3+1900 & GOTO :ok6
IF %3 EQU 08              SET /A DATE_JAHR=2008    & GOTO :ok6
IF %3 EQU 09              SET /A DATE_JAHR=2009    & GOTO :ok6
IF %3 GEQ 01 IF %3 LEQ 79 SET /A DATE_JAHR=%3+2000 & GOTO :ok6
IF %3 EQU 00 SET /A DATE_JAHR=%3+2000 && GOTO :ok6
SET DATE_STATUS=ungueltiges Jahr: %3 (groesser gleich 1900)
GOTO :eof
:ok6



CALL :schaltjahr %DATE_JAHR% DATE_SCHALTJAHR

REM jetzt den Tag genauer prüfen (und Monatsnamen festlegen)
GOTO :mon%DATE_MONAT%
REM Januar hat 31 Tage
  :mon1
  SET DATE_MONAT_NAME=Januar
  SET /A DATE_TAGE=DATE_TAG
  GOTO :ok7
REM Februar hat 28 Tage (an Schaltjahren 29 Tage)
  :mon2
  SET DATE_MONAT_NAME=Februar
  SET /A DATE_TAGE=DATE_TAG+31
  IF %DATE_SCHALTJAHR% EQU 1 IF %DATE_TAG% LEQ 29 GOTO :ok7
  IF %DATE_TAG% GTR 28 GOTO :err1
  GOTO :ok7
REM Maerz hat 31 Tage
  :mon3
  SET DATE_MONAT_NAME=Maerz
  SET /A DATE_TAGE=DATE_TAG+31+28+DATE_SCHALTJAHR
  GOTO :ok7
REM April hat 30 Tage
  :mon4
  SET DATE_MONAT_NAME=April
  SET /A DATE_TAGE=DATE_TAG+31+28+DATE_SCHALTJAHR+31
  IF %DATE_TAG% GTR 30 GOTO :err1
  GOTO :ok7
REM Mai hat 31 Tage
  :mon5
  SET DATE_MONAT_NAME=Mai
  SET /A DATE_TAGE=DATE_TAG+31+28+DATE_SCHALTJAHR+31+30
  GOTO :ok7
REM Juni hat 30 Tage
  :mon6
  SET DATE_MONAT_NAME=Juni
  SET /A DATE_TAGE=DATE_TAG+31+28+DATE_SCHALTJAHR+31+30+31
  IF %DATE_TAG% GTR 30 GOTO :err1
  GOTO :ok7
REM Juli hat 31 Tage
  :mon7
  SET DATE_MONAT_NAME=Juli
  SET /A DATE_TAGE=DATE_TAG+31+28+DATE_SCHALTJAHR+31+30+31+30
  GOTO :ok7
REM August hat 31 Tage
  :mon8
  SET DATE_MONAT_NAME=August
  SET /A DATE_TAGE=DATE_TAG+31+28+DATE_SCHALTJAHR+31+30+31+30+31
  GOTO :ok7
REM September hat 30 Tage
  :mon9
  SET DATE_MONAT_NAME=September
  SET /A DATE_TAGE=DATE_TAG+31+28+DATE_SCHALTJAHR+31+30+31+30+31+31
  IF %DATE_TAG% GTR 30 GOTO :err1
  GOTO :ok7
REM Oktober hat 31 Tage
  :mon10
  SET DATE_MONAT_NAME=Oktober
  SET /A DATE_TAGE=DATE_TAG+31+28+DATE_SCHALTJAHR+31+30+31+30+31+31+30
  GOTO :ok7
REM November hat 30 Tage
  :mon11
  SET DATE_MONAT_NAME=November
  SET /A DATE_TAGE=DATE_TAG+31+28+DATE_SCHALTJAHR+31+30+31+30+31+31+30+31
  IF %DATE_TAG% GTR 30 GOTO :err1
  GOTO :ok7
REM Dezember hat 31 Tage
  :mon12
  SET DATE_MONAT_NAME=November
  SET /A DATE_TAGE=DATE_TAG+31+28+DATE_SCHALTJAHR+31+30+31+30+31+31+30+31+30
  GOTO :ok7
:ok7


REM jetzt in DATE_TAGE_1900 die Anzahl der Tage seit 1.1.1900 berechnen (wie in Excel)
REM Info: 1900 ist in Excel ein Schaltjahr. Tatsächlich ist 1900 aber kein Schaltjahr!!
SET /A DATE_TEMP=DATE_JAHR-1900
SET /A DATE_TAGE_1900=DATE_TAGE+DATE_TEMP*365
REM pro 4 Jahre ein Schaltjahr addieren
SET /A DATE_TEMP=DATE_JAHR-1897
SET /A DATE_TAGE_1900+=DATE_TEMP/4
REM pro 100 Jahre ein Schaltjahr subtrahieren
SET /A DATE_TEMP=DATE_JAHR-1801
SET /A DATE_TAGE_1900-=DATE_TEMP/100
REM pro 400 Jahre ein Schaltjahr addieren
SET /A DATE_TEMP=DATE_JAHR-1601
SET /A DATE_TAGE_1900+=DATE_TEMP/400


REM jetzt den Wochentag berechnen
SET /A DATE_TEMP=DATE_TAGE_1900-DATE_TAGE_1900/7*7
GOTO :wt%date_temp%
  :wt0
  SET DATE_WOCHENTAG=Sonntag
  SET /A DATE_TEMP=DATE_TAGE+0
  GOTO :ok8
  :wt1
  SET DATE_WOCHENTAG=Montag
  SET /A DATE_TEMP=DATE_TAGE+6
  GOTO :ok8
  :wt2
  SET DATE_WOCHENTAG=Dienstag
  SET /A DATE_TEMP=DATE_TAGE+5
  GOTO :ok8
  :wt3
  SET DATE_WOCHENTAG=Mittwoch
  SET /A DATE_TEMP=DATE_TAGE+4
  GOTO :ok8
  :wt4
  SET DATE_WOCHENTAG=Donnerstag
  SET /A DATE_TEMP=DATE_TAGE+3
  GOTO :ok8
  :wt5
  SET DATE_WOCHENTAG=Freitag
  SET /A DATE_TEMP=DATE_TAGE+2
  GOTO :ok8
  :wt6
  SET DATE_WOCHENTAG=Samstag
  SET /A DATE_TEMP=DATE_TAGE+1
  GOTO :ok8
:ok8



REM und jetzt noch die Kalenderwoche (beginnt am Montag)
IF %DATE_TEMP% GTR 3 GOTO :kw1
  SET /A DATE_TEMP2=DATE_JAHR-1
  CALL :schaltjahr %DATE_TEMP2% DATE_TEMP3
  SET /A DATE_TEMP+=365+DATE_TEMP3
  GOTO :kw
:kw1
  SET /A DATE_TEMP2=DATE_TEMP-DATE_SCHALTJAHR
  IF %DATE_TEMP2% LSS 369 GOTO :kw
  SET DATE_WOCHE=1
  GOTO :ok9
:kw
SET /A DATE_TEMP2=DATE_TEMP-DATE_TEMP/7*7
SET /A DATE_WOCHE=DATE_TEMP/7
IF %DATE_TEMP2% GEQ 4 SET /A DATE_WOCHE+=1
:ok9

SET DATE_LANG=%DATE_WOCHENTAG%, %DATE_TAG%.%DATE_MONAT_NAME% %DATE_JAHR%
IF %DATE_TAG% LEQ 9 SET DATE_TAG=0%DATE_TAG%
IF %DATE_MONAT% LEQ 9 SET DATE_MONAT=0%DATE_MONAT%
SET DATE_KURZ=%DATE_TAG%.%DATE_MONAT%.%DATE_JAHR%

SET DATE_STATUS=OK

GOTO :eof







REM =============================
REM == versch. kleine Routinen ==
REM =============================

REM prüfen, ob das übergebene Jahr ein Schaltjahr ist
:schaltjahr
    SETLOCAL
    REM alle 400 Jahre ist Schaltjahr
        SET /A TEMP=%1/400
        SET /A TEMP*=400
        IF %TEMP% EQU %1 GOTO :schaltja
    REM alle 100 Jahre ist kein Schaltjahr
        SET /A TEMP=%1/100
        SET /A TEMP*=100
        IF %TEMP% EQU %1 GOTO :schaltnein
    REM alle 4 Jahre ist Schaltjahr
        SET /A TEMP=%1/4
        SET /A TEMP*=4
        IF %TEMP% EQU %1 GOTO :schaltja
    :schaltnein
    ENDLOCAL
    SET %2=0
    GOTO :eof
    :schaltja
    ENDLOCAL
    SET %2=1
GOTO :eof
