Workshop Batch for Runaways - Part III - Datums- und Zeitvariablen im Batch
Immer wieder gern gefragt.. wie kann ich im CMD-Batch Datums- und Zeitvariablen bilden und nutzen.
Ein paar Anregungen dazu hier im Workshop.
Weil es doch immer wieder mal als Frage gepostet wird, möchte ich heute versuchen, den grundsätzlichen Umgang mit Datums-und Zeitwerten in Batchdateien zu skizzieren.
Wozu brauche ich sowas?
Ich habe immer wiederkehrende Anforderungen in der täglichen Admin-Arbeit ( = sich wiederholende Abläufe = berechenbar und automatisierbar = geeignet für Batch).
Unter anderen gibt es zwei Fälle, die sicherlich jede(r) Admin(e) kennt und auch fast jeder Normal-User:
a) Bestimmte Dateien mit einem "von außen sichtbaren Zeitstempel" versehen oder neu anlegen. Beispiel sind Logfiles, die ich mit einem Namen anlege, die das aktuelle Datum erhalten.
Und innerhalb der Logdateien habe ich sicherlich Zeilen, die auch noch die aktuelle Uhrzeit enthalten.
b) Dateien mit einem Zeitstempel versehen, der ihrem Entstehungsdatum oder dem letzten Änderungsdatum entspricht. Beispiel für Entstehungsdatum (auch hier aus dem Forum): Faxprogramme, die eingehende Faxe unter zufällig generierten Dateinamen speichern. Selbst ein Umbenennen dieser Dateien in Dateien nach dem Muster 2000-10-01_13h34.tif macht das Wiederfinden einfacher.
Beispiel für letztes Änderungsdatum: Dateien, deren Namen gleich bleibt, von denen ich aber die Vorgängerversionen erhalten will. Die Anforderung gibt es ständig, von Worddateien bis zu Codeschnipseln... irgendwann gibt es eben eine neuere Version einer Datei und ich möchte die Vorgängerverion nicht überschreiben lassen.
Vorüberlegungen: Was brauche ich alles und was ist das Ziel?
Ziel: ich will Datums- und Zeitinformationen detailliert und strukturiert verwenden können.
Am besten in abfragbare Variablen wie "Tag", "Monat" oder "Jahr" gespeichert.
Ich brauche minimal:
- Datum (aktuell) mit einzeln identifizierbarem Tag, Monat und Jahr - nenne ich mal TT, MM, JJ
- Zeit (aktuell) mit einzeln identifizierbaren Stunden und Minuten - nenne ich mal hh und min
und entsprechend
- Datei-Datum (Erstellungs- bzw. letztes Änderungsdatum) mit einzeln identifizierbarem Tag, Monat und Jahr
- Datei-Zeit (aktuell) mit einzeln identifizierbaren Stunden und Minuten
Optional:
- Sekunden und Tausendstelsekunden bei der Zeit .. (würden dann ss und ms heißen)
- den Wochentag eines Datums (=DoW Day of Week)
- abgeleitetes aus dem Datum wie Tag des Jahres (=DoY Day of Year), Kalenderwoche (KW), Quartal...
Was habe ich?
Tja, jetzt der unangenehme Teil. M$ liefert mir, dem Windows-User, zwar die oben beschriebenen Datums- und Zeitinformationen optisch wiedererkennbar mit den CMD-Befehlen date und time , aber in der Darstellung leider abhängig von
"Es liegt eine fehlende Passgenauigkeit zwischen Anforderungen und Voraussetzungen vor."
Nach dem Spruch geht es mir immer besser.
Wie komme ich zu meinen Datumsvariablen?
Gehen wirs locker an und erstmal zum CMD-Prompt. Mal sehen, wie wir es aufdröseln.
Ein kurzer Blick in die Hilfe zeigt uns drei Varianten, um an Datums/Zeit-Information via CMD-Prompt zu kommen.
- "Date" bzw "Time" eingeben (erwartet Benutzereingabe);
- "Date /t" bzw. "Time /t" (ohne Benutzereingabe, nur Ausgabe; Schalter /t seit Win2000?)
- Abfrage der immer vorhandenen Variablen %date% und %Time% (die Variablen gibts noch nicht unter WinNT, Win9x. Ausweichstrategie siehe letzte Zeile der CMD-Spielereien)
Ich zeig mal, was rauskommt an meinem Rechner, so wie der halt zufällig eingestellt ist:
Ich ändere mal in den Systemsteuerung->"Ländereinstellungen"/"Regional Settings" das Datumsformat auf das angebotene "JJJJ-MM-TT" und erhalte in einem neuen CMD-Fenster:
Weshalb mir M$ hier unaufgefordert den Wochentag mitliefert, weiß nur Bill allein..*seufz
Ist aber auch nicht immer so... manchmal fehlt der Wochentag auch. Wunderwelt Windows.
Auch die DIR-Anzeige übernimmt das Datumsformat:
Na, fragen wir doch mal vom CMD-Prompt aus nach, wie das wohl in der Registry abgelegt ist.
(bei Fragen zu Elementarbefehlen wie REG.exe, FIND.exe bitte die entsprechende Hilfe konsultieren)
Achtung: Ich verwende hier die Reg.exe 2.00. Die NT-Variante und auch die XP-Variante 3.00 haben etwas andere Syntax. Ist aber hier nicht weiter wesentlich.
Scheinen ja auf den ersten Blick nur drei Werte zu sein, die kleine Steuerschrauben für die Datumsdarstellung sein könnten, nämlich idate, sDate und sShortDate.
sShortdate ist selbst erklärend, sDate als Datumstrennzeichen auch nicht sonderlich aufregend.
Zu iDate gibt die M$-Dokumentation folgendes her:
iDate
HKCUControl PanelInternational
Description
Specifies the default format for displaying short dates.
Mal weiterspielen (ändern von iDate von 2 auf 1 und danach auf 0):
Okay, Microsoft, hab ich in Ansätzen verstanden, aber... *kopfkratz*
Fassen wir mal zusammen, was wir jetzt haben.
Folgender kleinster gemeinsamer Nenner gilt unabhängig von Länder- und Usereinstellungen und OS-Version:
Also beschränke ich mal auf das Abgreifen von (ich sags mal im Hobby-Programmierer-Slang, ihr versteht mich ja *gg) TT, MM, JJ und hh, min, ss.
Berücksichtigen will ich wenigstens auch, dass bei englischem/US-amerikanischem OS nicht TT und JJ geliefert werden, sondern DD und YY.
Machen wir erstmal einen simplen Batch-Oneliner zum Warmwerden.
Strategie, ich hole mir Zeit und Datum aus dem Output von "prompt $D $T" und der "date"-Abfrage.
Ich verzichte mal auf alle Registry-Abfragen (nur Bordmittel).
Und unterstelle, die Datums/Zeittrennzeichen sind -egal welche Sprache und welches Format- in diesen hier: (":/.-, ") enthalten.
Und gehe auch davon aus, dass ein Wochentag mitgeliefert wird.
So sähen die beiden Outputs also aus, die ich verwurste (Win2K, deutsch):
Lassen wir mal den Oneliner(ich hab ihn auf ein paar Zeilen verteilt) "GetAllSystemDateTimeInfos_1.bat" drüberlaufen.
Ich rufe den Schnipsel mal auf und frag die gesetzten Variablen ab:
Bei US-Versionen würde rauskommen:
Damit hätten wir zumindest alles, was wir zum Beispiel zum Zusammenbasteln eines neuen Dateinamens für ein Logfile oder ähnliches brauchen.
Beispiel: Aufgabe sei, das Logfile SQL.Log unzubenennen in 2005-10-01_11h39_SQL.Log
Ich denke, den Faden brauche ich nicht weiterspinnen.
Problem dabei ist nur, dass ich eben -weil ich mich NICHT darauf verlassen kann, dass M$ mir den führenden Wochentag im Output liefert, dieser Codeschnipsel in die Grütze fasst, wenn die Output-Formatierung von Date keinen Wochentag enthält.
Also, hilft nichts, wenn ich flexibel bleiben will, muss ich die Strategie ändern. Ich gehe, um auf der sicheren Seite zu stehen, von einem Output aus, der keinen Wochentag enthält.
Und falls der drin sein sollte, schmeiss ich ihn weg.
Wie überzählige Teile eines Output zu entsorgen sind, habe ich schon einige Male vorgeturnt hier im Forum, das Beispiel mit dem Wochentag aus der Datumsausgabe bzw die Tausendstel-Sekunden aus dem Time-String zum Beispiel in diesem Thread (Variablen und Wildcards)
Ich mache also schweren Herzens aus dem Oneliner oben einen Mehrzeiler.
Test am CMD-Prompt:
Okay, schauen wir mal, ob wir mit Auslesen der Registry-Werte schneller, besser, vollständiger zum Ziel kämen.
Ich turn das mal exemplarisch vor für das System-Datum (System-Zeit läuft analog. Schenk ich mir.)
Output wäre:
DateOrder=TT-MM-JJ
TT=01
MM=10
JJ=2005
Führe ich nicht weiter fort. Hilft mir nur wenig weiter, außer das ich tatsächlich die Tag/Monat/Jahr-Reihenfolge iDate und das Datumstrennzeichen sDate "amtlich" habe.
Aber es kann sein, dass ich diese Technik verwenden muss, wenn ich andere Registry-Einstellungen brauche, zum Beispiel
den iFirstDayOfWeek (REG_SZ, 0-6) oder den iFirstWeekOfYear(REG_SZ, 0-2) zur Berechung der Kalenderwoche.
Und, der Vollständigkeit halber: es gibt noch zwei weitere:
den iCalendarType (REG_SZ,1...nn) und darauf bezogen den folgenden Reg-Key:
HKEY_CURRENT_USERControl PanelInternationalCalendarsTwoDigitYearMax (steht z.B. der Strimg "2038" drin)
Dieser Wert zeigt an, bis zu welchem Jahr Datumswerte OHNE Jahrhundertangabe automatisch zum 21. Jahrhundert gehören.
(Also konkret: ein Datum "01.10.05" wird interpretiert als "01.10.2005", das Datum "01.10.87" nicht.)
Wer in seinem Batch sauber arbeiten will, muss die Werte aus der Registry lesen.
Wer lieber ein bisschen rumschlampt (bei der KW-Berechnung z.B.) darf gerne "Konstanten" verwenden.
Ich zeig weiter unten noch, was ich meine.
Uns fehlen ja noch unter anderem die abgeleitete Kalenderwoche, der Wochentag und der Tag des Jahres.
Können wir auf viele Arten berechnen:
Beispiel Berechnung Wochentag aus einem Datum mit Bordmitteln:
Aufruf und Output wären zum Beispiel (setzen einer numerischen Wochentagsvariablen für den 2.Oktober 2005)
Die Kalenderwoche und den Tag des Jahres kann ich auch mit reinen Batch-Bordmitteln ermitteln.
Habe ich auch schon bei ein paar Threads hier im Forum vorgekaspert.
Die skizzierte Mimik mit puren CMD-Befehlen ist wie folgt:
.. Datum ermitteln aus %date%
.. Datum entsprechend dem vorgefundenen aufdröseln in Tag, Monat, Jahr, Wochentag
.. Zwischenberechnung des TagDesJahres (abgespeckte Variante hatte ich mal skizziert unter Laufender Tag im Jahr und Zähler
.. KW berechnen als SET /A KW = %TachDesJahres% - %Wochentach% + 7 ( wenn Wochentach von 0=Mo bis 7=So gesetzt ist)
.. SET /A KW /= 7 ... fertig
Aber es geht ja auch einfacher, wenn ich bestehende Algorithmen bzw. vorhandene Funktionen nutze.
Habe ja nicht den Ehrgeiz, jedes Rad neu zu erfinden. Bei JScript und VBScript existieren ja Datums-Aufdrösel-Funktionen, also nehme ich doch diese.
Beispiel-Codeschnipsel in VBscript:
In Aktion:
Idee ist jetzt ziemlich einfach: wenn ich einen kleinen *.vbs-Zweizeiler benutze, der mir die Werte liefert, die ich in meinem Batch brauche, brauche ich nichts mit eigenen Algorithmen berechnen.
Berechnet haben möchte ich vier Werte:
- Kalenderwoche (so, wie sie z.B. in meiner Firma definiert ist)
- Kalenderwoche wie sie laut Registry errechnet wird. Ihr erinnert Euch an die beiden Werte iFirstDayOfWeek (REG_SZ, 0-6) und iFirstWeekOfYear(REG_SZ, 0-2)? Die stehen da drin, aber ich kann die nicht ändern über die GUI/Ländereinstellungen. Microsoft. *gg
- Wochentag / DoW als numerischen Wert. Egal wie durchnummeriert, ich muss es bloß wissen. Hier kommt es als 1=So, 2=Mo etc zurück
- Tag des Jahres / DoY
Okay, wenn der Zweizeiler so aussieht:
...dann kann ich heute, am 3.10.2005 folgenden Output vom CMD-Prompt aus erhalten:
Prinzip verstanden?
Zum Verständnis der VBS-DatePart()-Parameter empfehle ich M$-Technet Retrieving Specific Portions of a Date and Time Value.
Okay, ich bau das nochmal ein in den GetAllSystemDateTimeVars.bat.
Und wenn ich da eh schon ändere, setze ich auch noch den "sprechenden" Wochentag cDoW als "Mo", "Di", etc für deutsches und englisches Windows.
Und ich erlaube mal statt der defaultmäßigen Aufdröselung von Systemdatum/Systemzeit auch die Berechung von Datum und Zeit, die als Parameter übergeben werden.
Dann noch eine Minimalhilfe (so wie üblich; bei Aufruf mit /? poppt es hoch).
Ich setze sowohl TT wie DD und auch JJ und YY für den Einsatz unter Win (dt) und Win (en).
Dann noch einen optionalen Parameter zum Setzen der ermittelten Werte "global". Nenn ich mal /s wie SET.
Und einen Parameter /u wie UNSET.
Und einen Parameter /q wie Quiet.
Und alle Werte innerhalb eines Datums/einer Zeit will ich zweistellig, mit führender "0"
Und die Jahreszahl 4stellig, also 1997 statt 97 und 2005 statt 05.
Dann müsste jeder Noob/jede Noobine damit klarkommen,
Also dann, The Final Version 0.01 Beta --> Version 0.10 23.10.2008 --> version 0.11. 20.02.2012 -> version 012. 11.10.2013.
Nun nochmal schauen, was passiert:
Und was mach ich jetzt damit??
Endlich kommen wir zur entscheidenden Frage
Ich kann diesen Batch von CMD-Prompt aus oder von anderen Bätchen aufrufen, um mir Datums-/Zeitvariablen zu ermitteln, die ich unabhängig von Benutzereinstellungen, Ländereinstellungen und Windowsunterschieden (von NT, w2000, XP und W2003 Server) verfügbar habe.
Egal auf welchen Rechner ich den laufen lasse.
Und ich verwende dazu keine Registry-Zugriffe oder andere Tools (ausgenommen *.vbs).
Beispiel 1: ich will (in einem Batch) ein LogFile mit der Namens-Struktur JJJJ-MM-TT_hh$min.log anlegen.
oder, Beispiel zwei, ich möchte von CMD-Prompt aus alle VBScripte in einem bestimmten Verzeichnis so umbenennen, dass im Datei-Namen der Kalendertag vorangestellt wird.
Also aus Test.vbs wird 255_Test.vbs etc. Geht vom CMD-Prompt aus mit einer Zeile.
(Ich habe noch ein @echo vor das "ren" gesetzt... wollte ja nur zeigen, was geht.)
Wer jetzt noch Fragen zum Thema Datums- und Zeit-Berechnung in Batch-Dateien hat, der/dem kann auch ich nicht helfen.
Keep on Batchin'
Frank / der Biber aus Bremen
Last Edits:
20.9.2007 v0.10 time/T hat Format "hh:mm" ; %time% dagegen "hh:mm:ss, nn"
Time /t nur im Notfall - wenn %time% nicht definiert ist - verwenden. Nur bei NT also.
siehe yotamans Hinweis unten
11.7.2007 v0.08 NT-Bugfix - %date% / %time% -Umgebungsvariablen kennt Windows NT noch nicht.
Siehe hier: Datensicherung: Probleme mit einer Batchdatei unter NT
29.2.2008 v0.09 Minor cosmetics.
25.2.2009 Späte Korrektur in GetAllDateTimeVars_3.bat (siehe Kommentare dotsch)
19.6.2009 Find /i statt Find beim Variablen-Finden (s.Kommentar Noc06)
20.2.2012 Erweiterung/optimierung s. Kommentar pieh-ejdsch
11.10.2013 Erweiterung Chinesisches Datumsformat von RobSei
Querverweise hier auf administrator.de:
Internationales Datum und Zeitzone bestimmen
Erweiterung: mit AM PM Amerikanischen Zeiten mit AM PM in deutschen 24 Stunden umwandeln (von mycroftone)
Die vorangegangenen Workshops
Workshop Batch for Runaways - Part II - Ein bisschen Handwerkszeug
Workshop Batch for Runaways - Part I - Beispiel FindLongPath.Bat Bedenklich lange Pfade finden
und immer hilfreich
Tutorial zur FOR-Schleife von Friemler
Ein paar Anregungen dazu hier im Workshop.
Weil es doch immer wieder mal als Frage gepostet wird, möchte ich heute versuchen, den grundsätzlichen Umgang mit Datums-und Zeitwerten in Batchdateien zu skizzieren.
Wozu brauche ich sowas?
Ich habe immer wiederkehrende Anforderungen in der täglichen Admin-Arbeit ( = sich wiederholende Abläufe = berechenbar und automatisierbar = geeignet für Batch).
Unter anderen gibt es zwei Fälle, die sicherlich jede(r) Admin(e) kennt und auch fast jeder Normal-User:
a) Bestimmte Dateien mit einem "von außen sichtbaren Zeitstempel" versehen oder neu anlegen. Beispiel sind Logfiles, die ich mit einem Namen anlege, die das aktuelle Datum erhalten.
Und innerhalb der Logdateien habe ich sicherlich Zeilen, die auch noch die aktuelle Uhrzeit enthalten.
b) Dateien mit einem Zeitstempel versehen, der ihrem Entstehungsdatum oder dem letzten Änderungsdatum entspricht. Beispiel für Entstehungsdatum (auch hier aus dem Forum): Faxprogramme, die eingehende Faxe unter zufällig generierten Dateinamen speichern. Selbst ein Umbenennen dieser Dateien in Dateien nach dem Muster 2000-10-01_13h34.tif macht das Wiederfinden einfacher.
Beispiel für letztes Änderungsdatum: Dateien, deren Namen gleich bleibt, von denen ich aber die Vorgängerversionen erhalten will. Die Anforderung gibt es ständig, von Worddateien bis zu Codeschnipseln... irgendwann gibt es eben eine neuere Version einer Datei und ich möchte die Vorgängerverion nicht überschreiben lassen.
Vorüberlegungen: Was brauche ich alles und was ist das Ziel?
Ziel: ich will Datums- und Zeitinformationen detailliert und strukturiert verwenden können.
Am besten in abfragbare Variablen wie "Tag", "Monat" oder "Jahr" gespeichert.
Ich brauche minimal:
- Datum (aktuell) mit einzeln identifizierbarem Tag, Monat und Jahr - nenne ich mal TT, MM, JJ
- Zeit (aktuell) mit einzeln identifizierbaren Stunden und Minuten - nenne ich mal hh und min
und entsprechend
- Datei-Datum (Erstellungs- bzw. letztes Änderungsdatum) mit einzeln identifizierbarem Tag, Monat und Jahr
- Datei-Zeit (aktuell) mit einzeln identifizierbaren Stunden und Minuten
Optional:
- Sekunden und Tausendstelsekunden bei der Zeit .. (würden dann ss und ms heißen)
- den Wochentag eines Datums (=DoW Day of Week)
- abgeleitetes aus dem Datum wie Tag des Jahres (=DoY Day of Year), Kalenderwoche (KW), Quartal...
Was habe ich?
Tja, jetzt der unangenehme Teil. M$ liefert mir, dem Windows-User, zwar die oben beschriebenen Datums- und Zeitinformationen optisch wiedererkennbar mit den CMD-Befehlen date und time , aber in der Darstellung leider abhängig von
- Ländereinstellungen (die Darstellung von Silvester 2005 kann sein "31.12.2005" oder "2005/12/31" oder "31-12-05" oder oder oder..)
- Betriebssystemversionen... auch M$ geht mit dem Geschmack der Zeit. Standard-Darstellung des Datums bei "älteren" OS-Versionen: "Sa, 31.12.2005". "Neuere" OS-Versionen "31.12.2005"
- Benutzereinstellungen Zu allem Überfluss kann der Benutzer auch noch standardmäßig "seine" Umgebung definieren mit "Langen Datumsformaten" wie "Samstag, 31. Dezember 2005" oder "Kurzen Datumsformaten" wie "Sam 31.Dez 2005"
"Es liegt eine fehlende Passgenauigkeit zwischen Anforderungen und Voraussetzungen vor."
Nach dem Spruch geht es mir immer besser.
Wie komme ich zu meinen Datumsvariablen?
Gehen wirs locker an und erstmal zum CMD-Prompt. Mal sehen, wie wir es aufdröseln.
Ein kurzer Blick in die Hilfe zeigt uns drei Varianten, um an Datums/Zeit-Information via CMD-Prompt zu kommen.
- "Date" bzw "Time" eingeben (erwartet Benutzereingabe);
- "Date /t" bzw. "Time /t" (ohne Benutzereingabe, nur Ausgabe; Schalter /t seit Win2000?)
- Abfrage der immer vorhandenen Variablen %date% und %Time% (die Variablen gibts noch nicht unter WinNT, Win9x. Ausweichstrategie siehe letzte Zeile der CMD-Spielereien)
Ich zeig mal, was rauskommt an meinem Rechner, so wie der halt zufällig eingestellt ist:
>date
Aktuelles Datum: Sa 01.10.2005
Geben Sie das neue Datum ein: (TT-MM-JJ)
>time
Aktuelle Zeit: 12:43:14,96
Geben Sie die neue Zeit ein:
>date /t & time /t
Sa 01.10.2005
12:43
>echo %date% %time%
Sa 01.10.2005 12:44:00,82
echo exit|cmd /q /k"prompt $D $T"
Sa 01.10.2005 12:45:03,29
Ich ändere mal in den Systemsteuerung->"Ländereinstellungen"/"Regional Settings" das Datumsformat auf das angebotene "JJJJ-MM-TT" und erhalte in einem neuen CMD-Fenster:
>date
Aktuelles Datum: Sa 2005-10-01
Geben Sie das neue Datum ein: (JJ-MM-TT)
>date /t
Sa 2005-10-01
>echo %date%
Sa 2005-10-01
Ist aber auch nicht immer so... manchmal fehlt der Wochentag auch. Wunderwelt Windows.
Auch die DIR-Anzeige übernimmt das Datumsformat:
>dir *.reg
2005-08-12 21:51 1.272 MyCommandPrompt.reg
2005-09-19 00:16 920 RegDLL_Restore.reg
2005-09-19 00:16 50 RegDLL_Remove.reg
(bei Fragen zu Elementarbefehlen wie REG.exe, FIND.exe bitte die entsprechende Hilfe konsultieren)
Achtung: Ich verwende hier die Reg.exe 2.00. Die NT-Variante und auch die XP-Variante 3.00 haben etwas andere Syntax. Ist aber hier nicht weiter wesentlich.
>reg query "HKCUControl PanelInternational" /s
HKEY_CURRENT_USERControl PanelInternational
iCountry REG_SZ 49
iCurrDigits REG_SZ 2
iCurrency REG_SZ 3
iDate REG_SZ 2
iDigits REG_SZ 2
iLZero REG_SZ 1
iMeasure REG_SZ 0
iNegCurr REG_SZ 8
iTime REG_SZ 1
iTLZero REG_SZ 1
Locale REG_SZ 00000407
s1159 REG_SZ
s2359 REG_SZ
sCountry REG_SZ Deutschland
sCurrency REG_SZ
sDate REG_SZ -
sDecimal REG_SZ ,
sLanguage REG_SZ DEU
sList REG_SZ ;
sLongDate REG_SZ dddd, d. MMMM yyyy
sShortDate REG_SZ yyyy-MM-dd
sThousand REG_SZ .
sTime REG_SZ :
sTimeFormat REG_SZ HH:mm:ss
iTimePrefix REG_SZ 0
sMonDecimalSep REG_SZ ,
sMonThousandSep REG_SZ .
iNegNumber REG_SZ 1
sNativeDigits REG_SZ 0123456789
NumShape REG_SZ 1
iCalendarType REG_SZ 1
iFirstDayOfWeek REG_SZ 0
iFirstWeekOfYear REG_SZ 2
sShortdate ist selbst erklärend, sDate als Datumstrennzeichen auch nicht sonderlich aufregend.
Zu iDate gibt die M$-Dokumentation folgendes her:
iDate
HKCUControl PanelInternational
Data type | Range | Default value |
---|---|---|
REG_SZ | 0 | 1 | 2 | 0 |
Description
Specifies the default format for displaying short dates.
Value | Meaning |
---|---|
0 | mm/dd/yy |
1 | dd/mm/yy |
2 | yy/mm/dd |
Mal weiterspielen (ändern von iDate von 2 auf 1 und danach auf 0):
>reg add "HKCUControl PanelInternational" /v idate /t REG_SZ /d 1 /f
>date
Aktuelles Datum: Sa 01-10-2005
Geben Sie das neue Datum ein: (TT-MM-JJ)
>date /t
Sa 01-10-2005
>reg add "HKCUControl PanelInternational" /v idate /t REG_SZ /d 0 /f
>date /t
Sa 10-01-2005
>date
Aktuelles Datum: Sa 10-01-2005
Geben Sie das neue Datum ein: (MM-TT-JJ)
- ?? Wieso werden mir die Jahrhunderte angezeigt? "01.10.05" will ich doch nur...
- ?? Wieso kommt mal der Wochentag und mal nicht? Heute war er ja immer da... aber weg war er auch schon mal...
- ?? Und wieso bekomme ich den Wochentag im deutschen Windows als 2 Zeichen ("Mo", "Di", "Mi",..) und im US-Amerikanischen als "Mon", "Tue".. mit drei Zeichen?
- ?? Und wenn ich da tatsächlich "Montag" ..."Sonntag" als ganzes Wort stehen haben will?? Bekomm ich nicht hin..
- ?? Und wo kann ich den Output bewundern, den ich mit sLongdate einstelle?
Fassen wir mal zusammen, was wir jetzt haben.
Folgender kleinster gemeinsamer Nenner gilt unabhängig von Länder- und Usereinstellungen und OS-Version:
- beim Output von "date", "date /t", kommt eine Zeile zurück, die Tag, Monat, Jahr enthält
- der Output von "date /t" bzw "time /t" steht auch in der Umgebungsvariablen %date% bzw %time%
- die Reihenfolge von Tag, Monat, Jahr kann ich aus der Registry über idate ermitteln
- das Trennzeichen im Datum kann aus der Registry über sdate ermitteln
- ob ich den Datumsstring mit oder Wochentagsanzeige zurückbekomme, kann ich weder vorher wissen noch steuern.
- wenn ich keine Registryzugriffe machen will, kann ich die Tag/Monat/Jahr.Reihenfolge auch dem "date"-Output ermitteln.
- bei "time", "time /t" scheint es nicht so aufregend zu werden. Da muss ich ggf. die Tausendstel-Sekunden entsorgen und bei den Stunden eine führende Null ergänzen, falls die fehlt. Aber mehr scheint da nicht zu tun zu sein.
- Ermittlung von Tag, Monat, Jahr, Stunde, Minute, Sekunde ist also per Batch mit einem Einzeiler möglich. Das war ja der Pflichtteil.
- Ermittlung von Wochentag, Kalenderwoche oder Tag des Jahres in Batchdateien scheint nicht so ganz aktiv unterstützt zu werden von Microsoft aus. Braucht man da in Redmond anscheinend nicht. *Kopfschüttelt*
Also beschränke ich mal auf das Abgreifen von (ich sags mal im Hobby-Programmierer-Slang, ihr versteht mich ja *gg) TT, MM, JJ und hh, min, ss.
Berücksichtigen will ich wenigstens auch, dass bei englischem/US-amerikanischem OS nicht TT und JJ geliefert werden, sondern DD und YY.
Machen wir erstmal einen simplen Batch-Oneliner zum Warmwerden.
Strategie, ich hole mir Zeit und Datum aus dem Output von "prompt $D $T" und der "date"-Abfrage.
Ich verzichte mal auf alle Registry-Abfragen (nur Bordmittel).
Und unterstelle, die Datums/Zeittrennzeichen sind -egal welche Sprache und welches Format- in diesen hier: (":/.-, ") enthalten.
Und gehe auch davon aus, dass ein Wochentag mitgeliefert wird.
So sähen die beiden Outputs also aus, die ich verwurste (Win2K, deutsch):
>echo exit|cmd /q /k"prompt $D $T"
Sa 01.10.2005 11:38:26,79
>echo.|date
Aktuelles Datum: Sa 01.10.2005
Geben Sie das neue Datum ein: (TT-MM-JJ)
---snipp Codefragment GetAllSystemDateTimeInfos_1.bat-----
For /f "tokens=1-7 delims=:/.-, " %%i in ('echo exit^|cmd /q /k"prompt $D $T"') do (
For /f "tokens=2-4 delims=/-,() skip=1" %%a in ('echo.^|date') do (
for %%@ in ("dow=%%i" "DateOrder=%%a-%%b-%%c" "%%a=%%j" "%%b=%%k" "%%c=%%l" "hh=%%m" "min=%%n" "ss=%%o") do set %%@
)
)
::---snipp Codefragment GetAllSystemDateTimeInfos_1.bat-----
>GetAllSystemDateTimeInfos_1 >nul
For %i in (DateOrder DoW DD TT MM JJ YY hh min ss) do @if defined %i set %i
DateOrder=TT-MM-JJ
DoW=Sa
TT=01
MM=10
JJ=2005
hh=11
min=39
ss=03
DateOrder=YY-MM-DD
DoW=Sa
DD=01
MM=10
YY=2005
hh=11
min=39
ss=03
Beispiel: Aufgabe sei, das Logfile SQL.Log unzubenennen in 2005-10-01_11h39_SQL.Log
>if defined TT if defined JJ ren SQL.Log %JJ%-%MM%-%TT%_%hh%h%min%_SQL.Log
>if defined DD if defined YY ren SQL.Log %YY%-%MM%-%DD%_%hh%h%min%_SQL.Log
Problem dabei ist nur, dass ich eben -weil ich mich NICHT darauf verlassen kann, dass M$ mir den führenden Wochentag im Output liefert, dieser Codeschnipsel in die Grütze fasst, wenn die Output-Formatierung von Date keinen Wochentag enthält.
Also, hilft nichts, wenn ich flexibel bleiben will, muss ich die Strategie ändern. Ich gehe, um auf der sicheren Seite zu stehen, von einem Output aus, der keinen Wochentag enthält.
Und falls der drin sein sollte, schmeiss ich ihn weg.
Wie überzählige Teile eines Output zu entsorgen sind, habe ich schon einige Male vorgeturnt hier im Forum, das Beispiel mit dem Wochentag aus der Datumsausgabe bzw die Tausendstel-Sekunden aus dem Time-String zum Beispiel in diesem Thread (Variablen und Wildcards)
::--------kurzes Codebeispiel zum "schnellen" Bilden von Datums/Zeitstempeln; passt meistens.
...
:CopyWithRename
Set "DatePrefix=%date%" & Set "TimeSuffix=%time%" & REM Namenserweiterungen für die zu kopierende Datei
FOR /f "tokens=2" %%i in ("%datePrefix%") do Set DatePrefix=%%i
FOR /f "tokens=1-3 delims=." %%i in ("%datePrefix%") do Set Dateprefix=%%k%%j%%i
for /F "tokens=1-3 delims=:," %%i in ("%time%") do Set "TimeSuffix=%%i%%j%%k"
Set "TimeSuffix=%TimeSuffix: =0%"
..
::-------snipp GetAllSystemDateTimeInfos_2.bat -----
@echo off & setlocal
:: (c) Biberware 2005 Placed in the Public Domain Oct 2005 for Educational Purposes
:: Ermittelt ein paar Datums/Zeitvariable aus dem CMD-Environment (Systemdatum/Systemzeit) OHNE REG-Abfragen
:: Einschränkung: Sollte schon NT oder höher sein, Deshalb die nächte Zeile
IF NOT "%OS%"=="Windows_NT" echo "%0 läuft nur unter WinNT oder höher. Sorry." && GOTO :eof
SET "AllDateTimeVars=DateOrder KW DoW DoY DD TT MM JJ YY hh min ss ms"
FOR %%i in (%AllDateTimeVars%) do @if defined %%i set %%i=
:: Datum will ich OHNE Wochentag haben. Zwischenschritt mit MyDateOhneDoW
Set MyDateOhneDoW=%date%
:: Die nächste Code-Zeile ändert nur dann etwas, wenn ein Wochentag mitgeliefert wird.
:: Aus "Sa 01.10.2005" wird dann "01.10.2005"
FOR /F "tokens=2" %%i in ("%MyDateOhneDoW%") do Set MyDateOhneDoW=%%i
FOR /F "tokens=1-7 delims=:/.-, " %%i in ("%MyDateOhneDow% %time%") do (
For /f "tokens=2-4 delims=/-,() skip=1" %%a in ('echo.^|date') do (
for %%@ in ("DateOrder=%%a-%%b-%%c" "%%a=%%i" "%%b=%%j" "%%c=%%k" "hh=%%l" "min=%%m" "ss=%%n" "ms=%%o") do set %%@
)
)
:: Lass sehen, was wir haben....
For %%i in (%AllDateTimeVars%) do @if defined %%i set %%i
::-------snapp GetAllSystemDateTimeInfos_2.bat
>GetAllSystemDateTimeInfos_2
DateOrder=TT-MM-JJ
TT=01
MM=10
JJ=2005
hh=13
min=36
ss=30
ms=02
Ich turn das mal exemplarisch vor für das System-Datum (System-Zeit läuft analog. Schenk ich mir.)
::--------snapp GetAllSystemDateTimeInfos_3.bat
@ECHO OFF
:: (c) Biberware 2005 Placed in the Public Domain Oct 2005 for Educational Purposes
:: Ermittelt ein paar Datumsvariablen aus dem CMD-Environment (Systemdatum) <b>MIT </b>REG-Abfragen
IF NOT "%OS%"=="Windows_NT" echo "%0 läuft nur unter WinNT oder höher.Sorry." && GOTO :eof
Setlocal
SET "AllSystemDateTimeVars=DateOrder KW DoW DoY DD TT MM JJ YY hh min ss ms"
:: Systemdatum abgreifen in lokale Variable, erstmal so wie geliefert
Set MyDateOhneDoW=%date%
:: Die nächste Code-Zeile ändert nur dann etwas, wenn ein Wochentag mitgeliefert wird.
:: Aus "Sa 01.10.2005" wird dann "01.10.2005"
FOR /F "tokens=2" %%i in ("%MyDateOhneDoW%") do Set MyDateOhneDoW=%%i
ECHO Heute ist %MyDateOhneDoW%
:: Registry-Werte in ein Temp-File auslesen mit RegEdit.exe
:: <b>Nicht </b>mit REG.exe wegen der Reg.exe-Syntaxunterschiede je nach Version!
Set RegFile=%temp%\%random%.reg
START /W REGEDIT /E %Regfile% "HKEY_CURRENT_USERControl PanelInternational"
:: [Anmerkung 13.2.2006 - Uuups, war mir damals gar nicht bewusst, dass der Parameter "/W" undokumentiert ist]
:: [ Laut Hilfe mit "Start /?" heißt es "Start /Wait"... ich hatte echt nicht drüber nachgedacht. ]
:: Auswerten der Werte iDate (0,1,2) und sDate (Datumstrennzeichen)
FOR /F "tokens=1* delims==" %%i IN ('Type %RegFile% ^| FIND /I "iDate"') DO SET iDate=%%j
FOR /F "tokens=1* delims==" %%i IN ('Type %RegFile% ^| FIND /I "sDate"') DO SET sDate=%%j
DEL %RegFile%
:: RegWerte weiterbehandeln... Anführungszeichen entfernen
SET iDate=%iDate:"=%
SET sDate=%sDate:"=%
:: Und nun in TT, MM, JJ sortieren
FOR /F "TOKENS=1-3 DELIMS=%sDate%" %%a IN ("%MyDateOhneDoW%") DO echo %%a %%b %%c
FOR /F "TOKENS=1-3 DELIMS=%sDate%" %%a IN ("%MyDateOhneDoW%") DO (
IF %iDate%==0 For %%i in ("JJ=%%c" "MM=%%a" "TT=%%b" "DateOrder=MM-TT-JJ") DO SET %%i
IF %iDate%==1 For %%i in ("JJ=%%c" "MM=%%b" "TT=%%a" "DateOrder=TT-MM-JJ") DO SET %%i
IF %iDate%==2 For %%i in ("JJ=%%a" "MM=%%b" "TT=%%c" "DateOrder=JJ-MM-TT") DO SET %%i
)
:: Lass sehen, was wir haben....
For %%i in (%AllSystemDateTimeVars%) do @if defined %%i set %%i
ENDLOCAL
GOTO:EOF
:: --------snapp GetAllSystemDateTimeInfos_3.bat
DateOrder=TT-MM-JJ
TT=01
MM=10
JJ=2005
Führe ich nicht weiter fort. Hilft mir nur wenig weiter, außer das ich tatsächlich die Tag/Monat/Jahr-Reihenfolge iDate und das Datumstrennzeichen sDate "amtlich" habe.
Aber es kann sein, dass ich diese Technik verwenden muss, wenn ich andere Registry-Einstellungen brauche, zum Beispiel
den iFirstDayOfWeek (REG_SZ, 0-6) oder den iFirstWeekOfYear(REG_SZ, 0-2) zur Berechung der Kalenderwoche.
Und, der Vollständigkeit halber: es gibt noch zwei weitere:
den iCalendarType (REG_SZ,1...nn) und darauf bezogen den folgenden Reg-Key:
HKEY_CURRENT_USERControl PanelInternationalCalendarsTwoDigitYearMax (steht z.B. der Strimg "2038" drin)
Dieser Wert zeigt an, bis zu welchem Jahr Datumswerte OHNE Jahrhundertangabe automatisch zum 21. Jahrhundert gehören.
(Also konkret: ein Datum "01.10.05" wird interpretiert als "01.10.2005", das Datum "01.10.87" nicht.)
Wer in seinem Batch sauber arbeiten will, muss die Werte aus der Registry lesen.
Wer lieber ein bisschen rumschlampt (bei der KW-Berechnung z.B.) darf gerne "Konstanten" verwenden.
Ich zeig weiter unten noch, was ich meine.
Uns fehlen ja noch unter anderem die abgeleitete Kalenderwoche, der Wochentag und der Tag des Jahres.
Können wir auf viele Arten berechnen:
Beispiel Berechnung Wochentag aus einem Datum mit Bordmitteln:
:: --- snipp GetDoW-Codeschnipsel.bat
:: Berechnet den DoW / Tag der Woche als numerischen Wert 1=Montag...7=Sonntag
:: IN-Parameter: Para 1-3 yy, mm, dd ( Jahr 2 oder 4stellig, Monat, Tag (mit/ohne führende "0" egal)
:: ..............Para 4 ist ein Variablennamen für den DoW/TachDerWoche
:: ..............Optional: Para 5 die Datumsgrenze (z.B. TwoDigitYearMax aus der REG).
::...............Mein Default (vollkommen willkürlich) 2038
:: ich mach hier <b>KEINE </b> Parameterüberprüfung und ähnliches, soll ja später nicht als eigenständiger Batch verwendet werden.
:: Algorithmus frei nach [http://www.commandline.co.uk/lib/treeview/index.php Batch Function Library for Windows NT4/2000/XP/2003]
@echo off & Setlocal
IF [%5]== (set /a "TwoDigitYearMax=2038%%1000") Else set /a TwoDigitYearMax=%5%%1000
set yy=%1 & set mm=%2 & set dd=%3
if 1%yy% LSS 200 if 1%yy% LSS 1%TwoDigitYearMax% (set yy=20%yy%) else (set yy=19%yy%)
set /a dd=100%dd%%%100,mm=100%mm%%%100
set /a z=14-mm,z/=12,y=yy+4800-z,m=mm+12*z-3,dow=153*m+2
set /a dow=dow/5+dd+y*365+y/4-y/100+y/400-2472630,dow%%=7,dow+=1
endlocal&Set %4=%dow%&goto :EOF
:: --- snipp GetDoW-Codeschnipsel.bat
getDow 2005 10 2 nWochentag
nWochentag=7Die Kalenderwoche und den Tag des Jahres kann ich auch mit reinen Batch-Bordmitteln ermitteln.
Habe ich auch schon bei ein paar Threads hier im Forum vorgekaspert.
Die skizzierte Mimik mit puren CMD-Befehlen ist wie folgt:
.. Datum ermitteln aus %date%
.. Datum entsprechend dem vorgefundenen aufdröseln in Tag, Monat, Jahr, Wochentag
.. Zwischenberechnung des TagDesJahres (abgespeckte Variante hatte ich mal skizziert unter Laufender Tag im Jahr und Zähler
.. KW berechnen als SET /A KW = %TachDesJahres% - %Wochentach% + 7 ( wenn Wochentach von 0=Mo bis 7=So gesetzt ist)
.. SET /A KW /= 7 ... fertig
Aber es geht ja auch einfacher, wenn ich bestehende Algorithmen bzw. vorhandene Funktionen nutze.
Habe ja nicht den Ehrgeiz, jedes Rad neu zu erfinden. Bei JScript und VBScript existieren ja Datums-Aufdrösel-Funktionen, also nehme ich doch diese.
Beispiel-Codeschnipsel in VBscript:
'-------snipp DateStrings.vbs
If wscript.arguments.count = 1 Then
MyDate=wscript.arguments.item(0)
Else
Mydate=Date
End If
wScript.echo "Ausgangsdatum der Berechnungen : " & Mydate
wScript.echo "DoY/Tag des Jahres : datepart('y' ,Date): " & datepart("y" ,MyDate)
wScript.echo "Kalenderwoche : datepart('ww',Date): " & datepart("ww",MyDate)
wScript.echo "DoW/Wochentag 1=So : datepart('w',Date) : " & datepart("w" ,MyDate)
'--------Snapp DateStrings.vbs
>cscript //nologo Datestrings.vbs
Ausgangsdatum der Berechnungen : 03.10.2005
DoY/Tag des Jahres : datepart('y' ,Date): 276
Kalenderwoche : datepart('ww',Date): 41
DoW/Wochentag 1=So : datepart('w',Date) : 2
>cscript //nologo Datestrings.vbs 01.10.2005
Ausgangsdatum der Berechnungen : 01.10.2005
DoY/Tag des Jahres : datepart('y' ,Date): 274
Kalenderwoche : datepart('ww',Date): 40
DoW/Wochentag 1=So : datepart('w',Date) : 7
Berechnet haben möchte ich vier Werte:
- Kalenderwoche (so, wie sie z.B. in meiner Firma definiert ist)
- Kalenderwoche wie sie laut Registry errechnet wird. Ihr erinnert Euch an die beiden Werte iFirstDayOfWeek (REG_SZ, 0-6) und iFirstWeekOfYear(REG_SZ, 0-2)? Die stehen da drin, aber ich kann die nicht ändern über die GUI/Ländereinstellungen. Microsoft. *gg
- Wochentag / DoW als numerischen Wert. Egal wie durchnummeriert, ich muss es bloß wissen. Hier kommt es als 1=So, 2=Mo etc zurück
- Tag des Jahres / DoY
Okay, wenn der Zweizeiler so aussieht:
'----snipp DateKrams.vbs
Wscript.Echo " " & DatePart("ww",Date,vbSunday,vbFirstFourDays) & " " &_
DatePart("ww",Date) & " " & DatePart("w",Date) & " " & DatePart("y",Date)
'------snapp DateKrams.vbs
>for /f "tokens=2-5" %a in ('cscript //nologo DateKrams.vbs') do @echo KW=%a,KWOS=%b,DoW=%c,DoY=%d
KW=40,KWOS=41,DoW=2,DoY=276
Zum Verständnis der VBS-DatePart()-Parameter empfehle ich M$-Technet Retrieving Specific Portions of a Date and Time Value.
Okay, ich bau das nochmal ein in den GetAllSystemDateTimeVars.bat.
Und wenn ich da eh schon ändere, setze ich auch noch den "sprechenden" Wochentag cDoW als "Mo", "Di", etc für deutsches und englisches Windows.
Und ich erlaube mal statt der defaultmäßigen Aufdröselung von Systemdatum/Systemzeit auch die Berechung von Datum und Zeit, die als Parameter übergeben werden.
Dann noch eine Minimalhilfe (so wie üblich; bei Aufruf mit /? poppt es hoch).
Ich setze sowohl TT wie DD und auch JJ und YY für den Einsatz unter Win (dt) und Win (en).
Dann noch einen optionalen Parameter zum Setzen der ermittelten Werte "global". Nenn ich mal /s wie SET.
Und einen Parameter /u wie UNSET.
Und einen Parameter /q wie Quiet.
Und alle Werte innerhalb eines Datums/einer Zeit will ich zweistellig, mit führender "0"
Und die Jahreszahl 4stellig, also 1997 statt 97 und 2005 statt 05.
Dann müsste jeder Noob/jede Noobine damit klarkommen,
Also dann, The Final Version 0.01 Beta --> Version 0.10 23.10.2008 --> version 0.11. 20.02.2012 -> version 012. 11.10.2013.
::-------snipp GetAllDateTimeInfos.cmd -----
@echo off & setlocal
:: (c) Biberware 2005 Placed in the Public Domain Oct 2005 for Educational Purposes
:: Ermittelt Datums/Zeitvariable aus dem CMD-Environment und stellt sie als Variablen bereit
:: Einschränkung: Sollte schon NT oder höher sein. Deshalb die erste Zeile
:: Vers. 0.02 Minor Bugfix; siehe zweiten Kommentar unten. 14.12.2005 by Biber
:: Vers. 0.06a Bugfix/Workarounds für Formfeed-Bug W2K und "Set /a 09"-Bug
:: -------------- Und alle SETs in Anführungszeichen. Siehe unten. 13.2.2006
:: Vers. 0.06b Aus Kompat-Gründen jetzt ohne erwartete "DelayedExpansion"-Reg-Voreinstellung
:: Vers. 0.07 Aufrufe mit Parameter/? bzw /h NACH dem Setzen der %AllDateTimeVar%s verschoben
:: Vers. 0.08 Windows NT scheint die Variablen %date% und %time% nicht zu kennen
:: Vers. 0.09 undokumentierten Befehl "echo." durch undokumentierten "echo" ersetzt
:: Ausgabe nur der "eigenen" Variablen ---> set "eigenevar"|find "eigenevar="
:: Vers. 010 Bugfix Variable AlldateTimeVars wurde nicht gelöscht, siehe srmerlins Kommentar unten
:: Vers. 011 Erweiterung und Feinschliff, s.u. pieh-ejdsch schreibt am 19.02.2012, 17:24:36 Uhr
:: Vers. 012 Erweiterun Umgang mit chinesischem Datumsformat von Robsei, siehe Kommentar vom 11.10.2013 unten.
IF NOT "%OS%"=="Windows_NT" echo "%0 läuft nur unter WinNT oder höher. Sorry." && GOTO :eof
For %%i in ( %1 %2 %3 %4) Do (
If /i [%%i]==[/s] Endlocal
If /i [%%i]==[/u] Endlocal
If /i [%%i]==[/h] %0 /?
)
SET "AllDateTimeVars=DateOrder KW OSKW DoW DoY cDoW DD TT MM JJ YY hh min ss ms"
If /i [%1]==[/?] goto Syntax
FOR %%i in (%AllDateTimeVars%) do @if defined %%i set "%%i="
:: Datum will ich OHNE Wochentag haben. Zwischenschritt mit INDate
:: erweitert, Parameter erlaubt.. Param1=Datumswert;Param2=Zeit
For %%i in (%1 %2 %3) Do If /i %%i==/u Set "AllDateTimeVars=" & goto :Cleanup
:: Vers 0.09 11.7.2007: Windows NT kennt weder %date% noch %time%.
:: Deshalb lieber folgende Syntax wählen statt der beiden Zeilen darunter:
FOR /F "delims=" %%i in ('date/T') do Set "INDate=%%i"
:: Vers. 0.10 20.9.2007: time/T hat Format "hh:mm" ; %time% dagegen "hh:mm:ss, nn"
:: ----> Time /t nur im Notfall - wenn %time% nicht definiert ist - verwenden.
IF defined time set "INTime=%time%"
IF not defined INtime FOR /F "delims=" %%i in ('time/T') do Set "InTime=%%i"
:: --- ersetzt durch Vers. 010 FOR /F "delims=" %%i in ('time/T') do Set "INTime=%%i"
:: -- ersetzt Vers. 0.09 Set "INDate=%date%"
:: -- ersetzt Vers. 0.09 Set "INTime=%time%"
If NOT [%1]== If /i [%1] NEQ [/q] If /i [%1] NEQ [/s] set "INDate=%1"
If NOT [%2]== If /i [%2] NEQ [/q] If /i [%2] NEQ [/s] set "INTime=%2"
:: Die nächste Code-Zeile ändert nur dann etwas, wenn ein Wochentag mitgeliefert wird.
:: Aus "Sa 01.10.2005" wird dann "01.10.2005"
REM vor v 012: FOR /F "tokens=2" %%i in ("%INDate%") do Set "INDate=%%i"
:: Beschränkung auf existierende Datumsformate siehe Posting mit CAT unten.
:: Das Format "Mo, 13. Februar 2006" mit zwei Leerzeichen würde NICHT funktionieren!
REM Datumsformat “Sa 01.10.2005“
If "%indate:~5,1%" == ":" FOR /F "tokens=2" %%i in ("%INDate%") do Set "INDate=%%i"
If "%indate:~5,1%" == "/" FOR /F "tokens=2" %%i in ("%INDate%") do Set "INDate=%%i"
If "%indate:~5,1%" == "." FOR /F "tokens=2" %%i in ("%INDate%") do Set "INDate=%%i"
If "%indate:~5,1%" == "-" FOR /F "tokens=2" %%i in ("%INDate%") do Set "INDate=%%i"
If "%indate:~5,1%" == "," FOR /F "tokens=2" %%i in ("%INDate%") do Set "INDate=%%i"
REM Datumsformat “Fri 10/11/2013"
If "%indate:~6,1%" == ":" FOR /F "tokens=2" %%i in ("%INDate%") do Set "INDate=%%i"
If "%indate:~6,1%" == "/" FOR /F "tokens=2" %%i in ("%INDate%") do Set "INDate=%%i"
If "%indate:~6,1%" == "." FOR /F "tokens=2" %%i in ("%INDate%") do Set "INDate=%%i"
If "%indate:~6,1%" == "-" FOR /F "tokens=2" %%i in ("%INDate%") do Set "INDate=%%i"
If "%indate:~6,1%" == "," FOR /F "tokens=2" %%i in ("%INDate%") do Set "INDate=%%i"
REM Datumsformat “2013-10-10 ???“ (??? sind 3 chinesische Zeichen)
If "%indate:~4,1%" == ":" FOR /F "tokens=1" %%i in ("%INDate%") do Set "INDate=%%i"
If "%indate:~4,1%" == "/" FOR /F "tokens=1" %%i in ("%INDate%") do Set "INDate=%%i"
If "%indate:~4,1%" == "." FOR /F "tokens=1" %%i in ("%INDate%") do Set "INDate=%%i"
If "%indate:~4,1%" == "-" FOR /F "tokens=1" %%i in ("%INDate%") do Set "INDate=%%i"
If "%indate:~4,1%" == "," FOR /F "tokens=1" %%i in ("%INDate%") do Set "INDate=%%i"
:: Erweiterung von RobSei 11.10.2013 -- siehe in den Kommentaren dieses Datums.
FOR /F "tokens=1-7 delims=:/.-, " %%i in ("%INDate% %INTime%") do (
FOR /F "tokens=2-4 delims=./-,() skip=1" %%a in ('date^<nul') do (
for %%@ in ("DateOrder=%%a-%%b-%%c" "%%a=%%i" "%%b=%%j" "%%c=%%k" "hh=%%l" "min=%%m" "ss=%%n" "ms=%%o") do set %%@
)
)
FOR /F "delims=DTMYJ-dtmyj" %%i in ("%DateOrder%") do set "Other=%%i"&if not defined JJ call set "JJ=%%%%i%%"
For %%i in (ss ms) do if not defined %%i set "%%i=00"
:: ----- v005 Workaround wegen W2K-Formfeed-Bug: Kommata als Delimiter im VBS-Schnipsel-Output
SET "vbsSnippet=%temp%\%random%.vbs"
echo If wscript.arguments.count = 1 Then dDate=wscript.arguments.item(0) Else dDate=Date>%vbssnippet%
echo Wscript.Echo "x," ^& DatePart("ww",dDate,vbSunday,vbFirstFourDays) ^& "," ^&_>>%vbsSnippet%
echo DatePart("ww",dDate) ^& "," ^& DatePart("w",dDate) ^& "," ^& DatePart("y",dDate)>>%vbsSnippet%
for /F "delims=, tokens=2-5" %%a in ('cscript //nologo %vbsSnippet% %INDate%') do (
(Set "KW=%%a" ) && Rem Kalenderwoche nach verbreiteter Berechnung
(Set "OSKW=%%b" ) && Rem Kalenderwoche nach Betriebssystemvorgaben nicht über GUI änderbar! *lacht
(Set "DoW=%%c" ) && Rem Day of Week 1=Sonntag, 2= Montag... bei meinen REG-Settings
(Set "DoY=%%d" ) && Rem Day of Year, Kalendertag
)
del %vbssnippet%
:: Tag, Monat und Stunde möchte ich immer zweistellig haben, also mit führender "0"
:: v006-Fix<s>For %%i in (DD TT MM hh) DO IF DEFINED %%i Set /a %%i+=100 </s>
:: v006-Fix wg. Set /A-Bug. THX an superfrog für den Bugreport
:: v006b-Fix-Fix <s>For %%i in (DD TT MM hh) DO IF DEFINED %%i Set "%%i=10!%%i!"</s>
:: --- für die beiden Fixes siehe die Kommentare von superfrog unten -- 14.2.2006
IF defined DD Set "DD=10%DD%"
IF defined TT Set "TT=10%TT%"
IF defined MM Set "MM=10%MM%"
IF defined hh Set "hh=10%hh%"
:: -v006b ----Vier Zeilen ohne DelayedExpansion statt eine FOR..IN..DO-Anweisung
set "hh=%hh:~-2,2%"
set "MM=%MM:~-2,2%"
:: ... und den Wochentag will ich auch, wenigstens in zwei Sprachen.
IF defined DD (
set "DD=%DD:~-2,2%"
IF %DoW%==1 Set "cDoW=Sun"
IF %DoW%==2 Set "cDoW=Mon"
IF %DoW%==3 Set "cDoW=Tue"
IF %DoW%==4 Set "cDoW=Wed"
IF %DoW%==5 Set "cDoW=Thu"
IF %DoW%==6 Set "cDoW=Fri"
IF %DoW%==7 Set "cDoW=Sat"
)
IF defined TT (
set "TT=%TT:~-2,2%"
IF %DoW%==1 Set "cDoW=So"
IF %DoW%==2 Set "cDoW=Mo"
IF %DoW%==3 Set "cDoW=Di"
IF %DoW%==4 Set "cDoW=Mi"
IF %DoW%==5 Set "cDoW=Do"
IF %DoW%==6 Set "cDoW=Fr"
IF %DoW%==7 Set "cDoW=Sa"
)
:: so.. hier schlampe ich mal..
:: alle 2-stelligen Jahre kleiner 39 werden zu 2001...2038
:: alle 2-stelligen Jahre größer gleich 39 und kleiner gleich 99 werden zu 1939 bis 1999
IF not defined YY goto YYskip
IF %YY% LSS 39 set "YY=20%YY%"
IF %YY% LEQ 99 set "YY=19%YY%"
:YYskip
If not defined JJ goto JJskip
IF %JJ% LSS 39 set "JJ=20%JJ%"
IF %JJ% LEQ 99 set "JJ=19%JJ%"
:JJskip
IF defined YY set "JJ=%YY%"
IF defined JJ set "YY=%JJ%"
IF defined DD Set "TT=%DD%"
IF defined TT Set "DD=%TT%"
:: Lass sehen, was wir haben....falls kein Parameter /q
For %%i in (%1 %2 %3 %4) Do If /i %%i==/q goto cleanUp
For %%i in (INDate INTime %Other% %AllDateTimeVars%) do @if defined %%i set %%i|find /i "%%i="
:cleanUp
For %%i in (vbssnippet INTime INDate %Other% Other) Do Set "%%i="
goto :eof
:Syntax
ECHO
ECHO %~nx0 By Frank / dem Biber aus Bremen 2005
ECHO
ECHO Ermittelt strukturierte Informationen über Datum und Zeit
ECHO Angezeigt oder optional in Variablen gesetzt werden:
ECHO %AllDateTimeVars%
ECHO
Echo Syntax:
ECHO %~nx0 [Datum] [Zeit] [/s^|/u] [/q] [/?]
ECHO
ECHO Datum Datumswert wie vom System oder der Dir-Ausgabe geliefert.
ECHO Default Systemdatum.
ECHO Zeit Zeit wie vom System oder der Dir-Ausgabe geliefert. Default Systemzeit.
ECHO /s SET Setzt die oben genannten Umgebungsvariablen
ECHO /u UNSET Löscht die gesetzten Umgebungsvariablen
ECHO /q QUIET Unterdrückt die Bildschirmanzeige der ermittelten Werte
ECHO/^? Zeigt diese schöne Hilfe
Goto :eof
::-------snapp GetAllDateTimeInfos.cmd
GetAllDateTimeInfos /?
GetAllDateTimeInfos.bat By Frank / dem Biber aus Bremen 2005
Ermittelt strukturierte Informationen über Datum und Zeit
Angezeigt oder optional in Variablen gesetzt werden:
DateOrder KW OSKW DoW DoY cDoW DD TT MM JJ YY hh min ss ms
Syntax:
GetAllDateTimeInfos.bat [Datum] [Zeit] [/s|/u] [/q] [/?]
Datum Datumswert wie vom System oder der Dir-Ausgabe geliefert.
Default Systemdatum.
Zeit Zeit wie vom System oder der Dir-Ausgabe geliefert. Default Systemzeit
/s SET Setzt die oben genannten Umgebungsvariablen
/u UNSET Löscht die gesetzten Umgebungsvariablen
/q QUIET Unterdrückt die Bildschirmanzeige der ermittelten Werte
/? Zeigt diese schöne Hilfe
>GetAllDateTimeInfos 01.10.2005 12:33:44
INDate=01.10.2005
INTime=12:33:44
DateOrder=TT-MM-JJ
KW=39
OSKW=40
DoW=7
DoY=274
cDoW=Sa
DD=01
TT=01
MM=10
JJ=2005
YY=2005
hh=12
min=33
ss=44
ms=00
>GetAllDateTimeInfos 01.11.2002 00:00:44
INDate=01.11.2002
INTime=00:00:44
DateOrder=TT-MM-JJ
KW=44
OSKW=44
DoW=6
DoY=305
cDoW=Fr
DD=01
TT=01
MM=11
JJ=2002
YY=2002
hh=00
min=00
ss=44
ms=00
(---hier mal ein zweistelliges Datum aus dem letztem Jahrhundert--)
>GetAllDateTimeInfos 01.04.99 12:47
INDate=01.04.99
INTime=12:47
DateOrder=TT-MM-JJ
KW=13
OSKW=14
DoW=5
DoY=91
cDoW=Do
DD=01
TT=01
MM=04
JJ=1999
YY=1999
hh=12
min=47
ss=00
ms=00
>GetAllDateTimeInfos 01.11.2002 00:00:44 /q /s
(keine Bildschirmausgabe, aber alle Variablen sind gesetzt)
>GetAllDateTimeInfos /u
(keine Bildschirmausgabe, und alle Variablen sind gelöscht)
>GetAllDateTimeInfos
INDate=03.10.2005
INTime= 6:43:02,31
DateOrder=TT-MM-JJ
KW=40
OSKW=41
DoW=2
DoY=276
cDoW=Mo
DD=03
TT=03
MM=10
JJ=2005
YY=2005
hh=06
min=43
ss=02
ms=31
>GetAllDateTimeInfos /q
(keine Bildschirmausgabe, es werden auch keine Variablen gesetzt, aber alle berechnet)
Und was mach ich jetzt damit??
Endlich kommen wir zur entscheidenden Frage
Ich kann diesen Batch von CMD-Prompt aus oder von anderen Bätchen aufrufen, um mir Datums-/Zeitvariablen zu ermitteln, die ich unabhängig von Benutzereinstellungen, Ländereinstellungen und Windowsunterschieden (von NT, w2000, XP und W2003 Server) verfügbar habe.
Egal auf welchen Rechner ich den laufen lasse.
Und ich verwende dazu keine Registry-Zugriffe oder andere Tools (ausgenommen *.vbs).
Beispiel 1: ich will (in einem Batch) ein LogFile mit der Namens-Struktur JJJJ-MM-TT_hh$min.log anlegen.
Call GetAllDateTimeInfos /s
(alle Variablen sind gesetzt)
set logfilename=%JJ%-%MM%-%TT%_%hh%$%min%.log
Call GetAllDateTimeInfos /u
..
Also aus Test.vbs wird 255_Test.vbs etc. Geht vom CMD-Prompt aus mit einer Zeile.
(Ich habe noch ein @echo vor das "ren" gesetzt... wollte ja nur zeigen, was geht.)
>for %i in (d: emp*.vbs) do @for /f "tokens=2 delims==" %a in ('GetAllDateTimeInfos.bat %~ti^|find "DoY"')do @echo ren %~dpnxi %a_%~nxi
ren d: empGetips.vbs 223_Getips.vbs
ren d: empTemplatesPath.vbs 225_TemplatesPath.vbs
ren d: empTemplatesPathHf.vbs 225_TemplatesPathHf.vbs
ren d: empSpecialFolders.vbs 225_SpecialFolders.vbs
ren d: empTemplatesPathHffull.vbs 225_TemplatesPathHffull.vbs
ren d: empRun BatchHiddenwith.Vbs 227_Run BatchHiddenwith.Vbs
ren d: empMonatsOrdnerAnlegen.vbs 246_MonatsOrdnerAnlegen.vbs
ren d: empListLocalUsers.vbs 259_ListLocalUsers.vbs
Keep on Batchin'
Frank / der Biber aus Bremen
Last Edits:
20.9.2007 v0.10 time/T hat Format "hh:mm" ; %time% dagegen "hh:mm:ss, nn"
Time /t nur im Notfall - wenn %time% nicht definiert ist - verwenden. Nur bei NT also.
siehe yotamans Hinweis unten
11.7.2007 v0.08 NT-Bugfix - %date% / %time% -Umgebungsvariablen kennt Windows NT noch nicht.
Siehe hier: Datensicherung: Probleme mit einer Batchdatei unter NT
29.2.2008 v0.09 Minor cosmetics.
25.2.2009 Späte Korrektur in GetAllDateTimeVars_3.bat (siehe Kommentare dotsch)
19.6.2009 Find /i statt Find beim Variablen-Finden (s.Kommentar Noc06)
20.2.2012 Erweiterung/optimierung s. Kommentar pieh-ejdsch
11.10.2013 Erweiterung Chinesisches Datumsformat von RobSei
Querverweise hier auf administrator.de:
Internationales Datum und Zeitzone bestimmen
Erweiterung: mit AM PM Amerikanischen Zeiten mit AM PM in deutschen 24 Stunden umwandeln (von mycroftone)
Die vorangegangenen Workshops
Workshop Batch for Runaways - Part II - Ein bisschen Handwerkszeug
Workshop Batch for Runaways - Part I - Beispiel FindLongPath.Bat Bedenklich lange Pfade finden
und immer hilfreich
Tutorial zur FOR-Schleife von Friemler
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 17083
Url: https://administrator.de/contentid/17083
Ausgedruckt am: 21.11.2024 um 13:11 Uhr
70 Kommentare
Neuester Kommentar
Hi,
super Anleitung.
Habe das meiste auch kapiert.
Normalerweise scipte ich in sh oder zsh.
Wie umstaendlich Win sein kann ist echt faszinierend.
Noch was vorweg.
Habe auch ein bisschen mit der Registry rumgespielt.
Nimmt man den Wert von sLongDate und ersetzt den Wert von sShortDate,
kommt auf jeden Fall die Tag Angabe.
Nun zu Deinem Script.
In meinem Falle bekomme ich gar nichts zurueck oder er meint es ist Donnerstag.
Habe das mal in ein textfile schreiben lassen:
C:\>IF NOT "Windows_NT" == "Windows_NT" echo "test.cmd läuft nur unter WinNT oder höher.Sorry." && GOTO :eof
C:\>If /I [/s] == [/?] goto Syntax
C:\>For %i in (/s) Do (
If /I [%i] == [/s] Endlocal
If /I [%i] == [/u] Endlocal
If /I [%i] == [/h] goto Syntax
)
C:\>(
If /I [/s] == [/s] Endlocal
If /I [/s] == [/u] Endlocal
If /I [/s] == [/h] goto Syntax
)
C:\>SET "AllDateTimeVars=DateOrder KW OSKW DoW DoY cDoW DD TT MM JJ YY hh min ss ms"
C:\>FOR %i in (DateOrder KW OSKW DoW DoY cDoW DD TT MM JJ YY hh min ss ms) do @if defined %i set %i=
C:\>For %i in (/s) Do If /I %i == /u goto :eof
C:\>If /I /s == /u goto :eof
C:\>Set "INDate=Mo, 06. Feb 2006"
C:\>Set "INTime=18:46:17,65"
C:\>If NOT [/s] == If /I [/s] NEQ [/q] If /I [/s] NEQ [/s] set "INDate=/s"
C:\>If NOT == If /I NEQ [/q] If /I NEQ [/s] set "INTime="
C:\>FOR /F "tokens=2" %i in ("Mo, 06. Feb 2006") do Set INDate=%i
C:\>Set INDate=06.
C:\>FOR /F "tokens=1-7 delims=:/.-, " %i in ("06. 18:46:17,65") do (For /F "tokens=2-4 delims=/-,() skip=1" %a in ('echo.|date') do (for %@ in ("DateOrder=%a-%b-%c" "%a=%i" "%b=%j" "%c=%k" "hh=%l" "min=%m" "ss=%n" "ms=%o") do set %@ ) )
C:\>(For /F "tokens=2-4 delims=/-,() skip=1" %a in ('echo.|date') do (for %@ in ("DateOrder=%a-%b-%c" "%a=06" "%b=18" "%c=46" "hh=17" "min=65" "ss=" "ms=") do set %@ ) )
C:\>(for %@ in ("DateOrder=TT-MM-JJ" "TT=06" "MM=18" "JJ=46" "hh=17" "min=65" "ss=" "ms=") do set %@ )
C:\>set "DateOrder=TT-MM-JJ"
C:\>set "TT=06"
C:\>set "MM=18"
C:\>set "JJ=46"
C:\>set "hh=17"
C:\>set "min=65"
C:\>set "ss="
C:\>set "ms="
C:\>For %i in (ss ms) do if not defined %i set "%i=00"
C:\>if not defined ss set "ss=00"
C:\>if not defined ms set "ms=00"
C:\>set vbsSnippet=C:\DOKUME~1\cat\LOKALE~1\Temp\30758.vbs
C:\>echo If wscript.arguments.count = 1 Then dDate=wscript.arguments.item(0) Else dDate=Date 1>C:\DOKUME~1\cat\LOKALE~1\Temp\30758.vbs
C:\>echo Wscript.Echo " " & DatePart("ww",dDate,vbSunday,vbFirstFourDays) & " " &_ 1>>C:\DOKUME~1\cat\LOKALE~1\Temp\30758.vbs
C:\>echo DatePart("ww",dDate) & " " & DatePart("w",dDate) & " " & DatePart("y",dDate) 1>>C:\DOKUME~1\cat\LOKALE~1\Temp\30758.vbs
C:\>for /F "tokens=2-5" %a in ('cscript //nologo C:\DOKUME~1\cat\LOKALE~1\Temp\30758.vbs 06.') do (
(Set "KW=%a" ) && Rem Kalenderwoche nach verbreiteter Berechnung
(Set "OSKW=%b" ) && Rem Kalenderwoche nach Betriebssystemvorgaben nicht über GUI änderbar! *lacht
(Set "DoW=%c" ) && Rem Day of Week 1=Sonntag, 2= Montag... bei meinen REG-Settings
(Set "DoY=%d" ) && Rem Day of Year, Kalendertag
)
C:\>(
(Set "KW=1" ) && Rem Kalenderwoche nach verbreiteter Berechnung
(Set "OSKW=6" ) && Rem Kalenderwoche nach Betriebssystemvorgaben nicht über GUI änderbar! *lacht
(Set "DoW=5" ) && Rem Day of Week 1=Sonntag, 2= Montag... bei meinen REG-Settings
(Set "DoY=" ) && Rem Day of Year, Kalendertag
)
C:\>del C:\DOKUME~1\cat\LOKALE~1\Temp\30758.vbs
C:\>For %i in (DD TT MM hh) DO IF DEFINED %i Set /a %i+=100
C:\>IF DEFINED DD Set /a DD+=100
C:\>IF DEFINED TT Set /a TT+=100
C:\>IF DEFINED MM Set /a MM+=100
C:\>IF DEFINED hh Set /a hh+=100
C:\>set "hh=17"
C:\>set "MM=18"
C:\>IF defined DD (
set "DD=~-2,2"
IF 5 == 1 Set "cDow=Sun"
IF 5 == 2 Set "cDow=Mon"
IF 5 == 3 Set "cDow=Tue"
IF 5 == 4 Set "cDow=Wed"
IF 5 == 5 Set "cDow=Thu"
IF 5 == 6 Set "cDow=Fri"
IF 5 == 7 Set "cDow=Sat"
)
C:\>IF defined TT (
set "TT=06"
IF 5 == 1 Set "cDow=So"
IF 5 == 2 Set "cDow=Mo"
IF 5 == 3 Set "cDow=Di"
IF 5 == 4 Set "cDow=Mi"
IF 5 == 5 Set "cDow=Do"
IF 5 == 6 Set "cDow=Fr"
IF 5 == 7 Set "cDow=Sa"
)
C:\>IF not defined YY goto YYskip
C:\>If not defined JJ goto JJskip
C:\>IF 46 LSS 39 set "JJ=2046"
C:\>IF 46 LEQ 99 set "JJ=1946"
C:\>IF defined YY set "JJ="
C:\>IF defined JJ set "YY=1946"
C:\>IF defined DD Set "TT="
C:\>IF defined TT Set "DD=06"
C:\>For %i in (/s) Do If /I %i == /q goto cleanUp
C:\>If /I /s == /q goto cleanUp
C:\>For %i in (INDate INTime DateOrder KW OSKW DoW DoY cDoW DD TT MM JJ YY hh min ss ms) do @if defined %i set %i
INDate=06.
INTime=18:46:17,65
DateOrder=TT-MM-JJ
KW=1
OSKW=6
DoW=5
cDow=Do
DD=06
TT=06
MM=18
JJ=1946
YY=1946
hh=17
min=65
ss=00
ms=00
C:\>For %i in (vbssnippet INTime INDate) Do Set %i=
C:\>Set vbssnippet=
C:\>Set INTime=
C:\>Set INDate=
C:\>goto :eof
Nun ist die Frage, wo der Fehler ist, bzw was nicht richtig laeuft...
Bis dann.
CAT
super Anleitung.
Habe das meiste auch kapiert.
Normalerweise scipte ich in sh oder zsh.
Wie umstaendlich Win sein kann ist echt faszinierend.
Noch was vorweg.
Habe auch ein bisschen mit der Registry rumgespielt.
Nimmt man den Wert von sLongDate und ersetzt den Wert von sShortDate,
kommt auf jeden Fall die Tag Angabe.
Nun zu Deinem Script.
In meinem Falle bekomme ich gar nichts zurueck oder er meint es ist Donnerstag.
Habe das mal in ein textfile schreiben lassen:
C:\>IF NOT "Windows_NT" == "Windows_NT" echo "test.cmd läuft nur unter WinNT oder höher.Sorry." && GOTO :eof
C:\>If /I [/s] == [/?] goto Syntax
C:\>For %i in (/s) Do (
If /I [%i] == [/s] Endlocal
If /I [%i] == [/u] Endlocal
If /I [%i] == [/h] goto Syntax
)
C:\>(
If /I [/s] == [/s] Endlocal
If /I [/s] == [/u] Endlocal
If /I [/s] == [/h] goto Syntax
)
C:\>SET "AllDateTimeVars=DateOrder KW OSKW DoW DoY cDoW DD TT MM JJ YY hh min ss ms"
C:\>FOR %i in (DateOrder KW OSKW DoW DoY cDoW DD TT MM JJ YY hh min ss ms) do @if defined %i set %i=
C:\>For %i in (/s) Do If /I %i == /u goto :eof
C:\>If /I /s == /u goto :eof
C:\>Set "INDate=Mo, 06. Feb 2006"
C:\>Set "INTime=18:46:17,65"
C:\>If NOT [/s] == If /I [/s] NEQ [/q] If /I [/s] NEQ [/s] set "INDate=/s"
C:\>If NOT == If /I NEQ [/q] If /I NEQ [/s] set "INTime="
C:\>FOR /F "tokens=2" %i in ("Mo, 06. Feb 2006") do Set INDate=%i
C:\>Set INDate=06.
C:\>FOR /F "tokens=1-7 delims=:/.-, " %i in ("06. 18:46:17,65") do (For /F "tokens=2-4 delims=/-,() skip=1" %a in ('echo.|date') do (for %@ in ("DateOrder=%a-%b-%c" "%a=%i" "%b=%j" "%c=%k" "hh=%l" "min=%m" "ss=%n" "ms=%o") do set %@ ) )
C:\>(For /F "tokens=2-4 delims=/-,() skip=1" %a in ('echo.|date') do (for %@ in ("DateOrder=%a-%b-%c" "%a=06" "%b=18" "%c=46" "hh=17" "min=65" "ss=" "ms=") do set %@ ) )
C:\>(for %@ in ("DateOrder=TT-MM-JJ" "TT=06" "MM=18" "JJ=46" "hh=17" "min=65" "ss=" "ms=") do set %@ )
C:\>set "DateOrder=TT-MM-JJ"
C:\>set "TT=06"
C:\>set "MM=18"
C:\>set "JJ=46"
C:\>set "hh=17"
C:\>set "min=65"
C:\>set "ss="
C:\>set "ms="
C:\>For %i in (ss ms) do if not defined %i set "%i=00"
C:\>if not defined ss set "ss=00"
C:\>if not defined ms set "ms=00"
C:\>set vbsSnippet=C:\DOKUME~1\cat\LOKALE~1\Temp\30758.vbs
C:\>echo If wscript.arguments.count = 1 Then dDate=wscript.arguments.item(0) Else dDate=Date 1>C:\DOKUME~1\cat\LOKALE~1\Temp\30758.vbs
C:\>echo Wscript.Echo " " & DatePart("ww",dDate,vbSunday,vbFirstFourDays) & " " &_ 1>>C:\DOKUME~1\cat\LOKALE~1\Temp\30758.vbs
C:\>echo DatePart("ww",dDate) & " " & DatePart("w",dDate) & " " & DatePart("y",dDate) 1>>C:\DOKUME~1\cat\LOKALE~1\Temp\30758.vbs
C:\>for /F "tokens=2-5" %a in ('cscript //nologo C:\DOKUME~1\cat\LOKALE~1\Temp\30758.vbs 06.') do (
(Set "KW=%a" ) && Rem Kalenderwoche nach verbreiteter Berechnung
(Set "OSKW=%b" ) && Rem Kalenderwoche nach Betriebssystemvorgaben nicht über GUI änderbar! *lacht
(Set "DoW=%c" ) && Rem Day of Week 1=Sonntag, 2= Montag... bei meinen REG-Settings
(Set "DoY=%d" ) && Rem Day of Year, Kalendertag
)
C:\>(
(Set "KW=1" ) && Rem Kalenderwoche nach verbreiteter Berechnung
(Set "OSKW=6" ) && Rem Kalenderwoche nach Betriebssystemvorgaben nicht über GUI änderbar! *lacht
(Set "DoW=5" ) && Rem Day of Week 1=Sonntag, 2= Montag... bei meinen REG-Settings
(Set "DoY=" ) && Rem Day of Year, Kalendertag
)
C:\>del C:\DOKUME~1\cat\LOKALE~1\Temp\30758.vbs
C:\>For %i in (DD TT MM hh) DO IF DEFINED %i Set /a %i+=100
C:\>IF DEFINED DD Set /a DD+=100
C:\>IF DEFINED TT Set /a TT+=100
C:\>IF DEFINED MM Set /a MM+=100
C:\>IF DEFINED hh Set /a hh+=100
C:\>set "hh=17"
C:\>set "MM=18"
C:\>IF defined DD (
set "DD=~-2,2"
IF 5 == 1 Set "cDow=Sun"
IF 5 == 2 Set "cDow=Mon"
IF 5 == 3 Set "cDow=Tue"
IF 5 == 4 Set "cDow=Wed"
IF 5 == 5 Set "cDow=Thu"
IF 5 == 6 Set "cDow=Fri"
IF 5 == 7 Set "cDow=Sat"
)
C:\>IF defined TT (
set "TT=06"
IF 5 == 1 Set "cDow=So"
IF 5 == 2 Set "cDow=Mo"
IF 5 == 3 Set "cDow=Di"
IF 5 == 4 Set "cDow=Mi"
IF 5 == 5 Set "cDow=Do"
IF 5 == 6 Set "cDow=Fr"
IF 5 == 7 Set "cDow=Sa"
)
C:\>IF not defined YY goto YYskip
C:\>If not defined JJ goto JJskip
C:\>IF 46 LSS 39 set "JJ=2046"
C:\>IF 46 LEQ 99 set "JJ=1946"
C:\>IF defined YY set "JJ="
C:\>IF defined JJ set "YY=1946"
C:\>IF defined DD Set "TT="
C:\>IF defined TT Set "DD=06"
C:\>For %i in (/s) Do If /I %i == /q goto cleanUp
C:\>If /I /s == /q goto cleanUp
C:\>For %i in (INDate INTime DateOrder KW OSKW DoW DoY cDoW DD TT MM JJ YY hh min ss ms) do @if defined %i set %i
INDate=06.
INTime=18:46:17,65
DateOrder=TT-MM-JJ
KW=1
OSKW=6
DoW=5
cDow=Do
DD=06
TT=06
MM=18
JJ=1946
YY=1946
hh=17
min=65
ss=00
ms=00
C:\>For %i in (vbssnippet INTime INDate) Do Set %i=
C:\>Set vbssnippet=
C:\>Set INTime=
C:\>Set INDate=
C:\>goto :eof
Nun ist die Frage, wo der Fehler ist, bzw was nicht richtig laeuft...
Bis dann.
CAT
Danke fuer Deine Antwort.
also ich habe die Registry mal wieder zurueckgedreht.
zumindest die Einstellungen, die Du aufgezaehlt hast.
Ich bekomme nun auch alles richtig ausgegeben.
Was fuer mich am wichtigsten ist: Der Wochentag.
Den bekomm ich nicht.
Du auch nicht.
cDOW fehlt bei beiden Ergebnissen.
Mit VB script kenn ich mich nun gar nicht aus. Aber ich denke der Fehler liegt dort.
Wird das auf jeden Rechner gleich ausgefuerht?
C:\>(
(Set "KW=6" ) && Rem Kalenderwoche nach verbreiteter Berechnung
(Set "OSKW=2" ) && Rem Kalenderwoche nach Betriebssystemvorgaben nicht über GUI änderbar! *lacht
(Set "DoW=37" ) && Rem Day of Week 1=Sonntag, 2= Montag... bei meinen REG-Settings
(Set "DoY=" ) && Rem Day of Year, Kalendertag
)
Zurueck gibt er diese Werte...
DoW = Wochentag?
Danke
CAT
P.S. Geht nichts uerber `date +%A`, gibt es nicht fuer WIN!
also ich habe die Registry mal wieder zurueckgedreht.
zumindest die Einstellungen, die Du aufgezaehlt hast.
Ich bekomme nun auch alles richtig ausgegeben.
Was fuer mich am wichtigsten ist: Der Wochentag.
Den bekomm ich nicht.
Du auch nicht.
cDOW fehlt bei beiden Ergebnissen.
Mit VB script kenn ich mich nun gar nicht aus. Aber ich denke der Fehler liegt dort.
Wird das auf jeden Rechner gleich ausgefuerht?
C:\>(
(Set "KW=6" ) && Rem Kalenderwoche nach verbreiteter Berechnung
(Set "OSKW=2" ) && Rem Kalenderwoche nach Betriebssystemvorgaben nicht über GUI änderbar! *lacht
(Set "DoW=37" ) && Rem Day of Week 1=Sonntag, 2= Montag... bei meinen REG-Settings
(Set "DoY=" ) && Rem Day of Year, Kalendertag
)
Zurueck gibt er diese Werte...
DoW = Wochentag?
Danke
CAT
P.S. Geht nichts uerber `date +%A`, gibt es nicht fuer WIN!
@Biber
mit deiner Änderung in v0.06 ist mein Problem bezüglich DD/TT wird zu 00 jetzt behoben.
Hatte erst an mir selbst gezweifelt, statt mal davon auszugehen, dass mir da vielleicht ein M$-Bug Probleme bereitet.
Dachte schon ich bin zu blöd, weil es für mich einfach keinen Sinn ergeben wollte, warum es am 07. eines Monats funtioniert, am 08. und 09. aber nicht.
Wie auch immer, das Problem (bei DD=08 oder DD=09) tritt jetzt nicht mehr auf, so dass mein Batch ohne Probleme läuft.
Danke nochmal für deine Hilfe. Hat mir sehr geholfen.
Aber Leute die undankbar sind, obwohl man ihnen Hilfe anbietet, wird es wohl immer geben.
Sollten man sich nicht drüber ärgern.
Es gibt auch Leute die deine nützlichen Beiträge zu schätzen wissen.
Grüße
superfrog
mit deiner Änderung in v0.06 ist mein Problem bezüglich DD/TT wird zu 00 jetzt behoben.
Hatte erst an mir selbst gezweifelt, statt mal davon auszugehen, dass mir da vielleicht ein M$-Bug Probleme bereitet.
Dachte schon ich bin zu blöd, weil es für mich einfach keinen Sinn ergeben wollte, warum es am 07. eines Monats funtioniert, am 08. und 09. aber nicht.
Wie auch immer, das Problem (bei DD=08 oder DD=09) tritt jetzt nicht mehr auf, so dass mein Batch ohne Probleme läuft.
Danke nochmal für deine Hilfe. Hat mir sehr geholfen.
Aber Leute die undankbar sind, obwohl man ihnen Hilfe anbietet, wird es wohl immer geben.
Sollten man sich nicht drüber ärgern.
Es gibt auch Leute die deine nützlichen Beiträge zu schätzen wissen.
Grüße
superfrog
Also als erstes Biber: NICHT aergern.
Habe mir eine Nacht spaeter alle Deine TUTO's reingezogen und muss sagen, ich bin beeindruckt.
Tuto I ist ein bisschen viel finde ich. Also komplex mein ich damit.
Tuto II ist schon sehr viel freundlicher. Zumindest, was das Verstaendnis anbelangt.
Tuto III ist am besten, weil der Stil wie ein Experiment ist.
Der User/Leser wird halt schrittweise darauf hingefuehrt.
Und es macht Spass zu lesen, weil man alle Deine Schritte auch auf der eigenen Konsole nachvollziehen kann.
Naja, habe mich auch mal in den anderen Tuto's umgeschaut, wo man aber deutliche Kompetenzunterschiede feststellen kann. ;)
Mit der Formatierung habe ich auch ein Problem gehabt. War aber so schlau und habe den Inhalt der Site einfach in meinen Gvim kopiert.
Dann gab es keine Probleme mit dem Zeichensatz, der unter Win auch ein bisschen durcheinander scheint manchmal.
Dann habe ich am WE noch eine Neuerung in einer Zeitschrift gefunden:
WinScript XP 3.0
Damit kann man Dialog Boxen und Browserfelder per batch oeffnen.
Ok, wenn man das so weit treiben moechte kann man doch auch in VB-Script das machen oder? Ist aber ein schneller und eleganter Weg, wie ich finde.
http://toolsandmore.de/Central/Produkte/Software/System-Tools/Winscript ...
MFG
CAT
Habe mir eine Nacht spaeter alle Deine TUTO's reingezogen und muss sagen, ich bin beeindruckt.
Tuto I ist ein bisschen viel finde ich. Also komplex mein ich damit.
Tuto II ist schon sehr viel freundlicher. Zumindest, was das Verstaendnis anbelangt.
Tuto III ist am besten, weil der Stil wie ein Experiment ist.
Der User/Leser wird halt schrittweise darauf hingefuehrt.
Und es macht Spass zu lesen, weil man alle Deine Schritte auch auf der eigenen Konsole nachvollziehen kann.
Naja, habe mich auch mal in den anderen Tuto's umgeschaut, wo man aber deutliche Kompetenzunterschiede feststellen kann. ;)
Mit der Formatierung habe ich auch ein Problem gehabt. War aber so schlau und habe den Inhalt der Site einfach in meinen Gvim kopiert.
Dann gab es keine Probleme mit dem Zeichensatz, der unter Win auch ein bisschen durcheinander scheint manchmal.
Dann habe ich am WE noch eine Neuerung in einer Zeitschrift gefunden:
WinScript XP 3.0
Damit kann man Dialog Boxen und Browserfelder per batch oeffnen.
Ok, wenn man das so weit treiben moechte kann man doch auch in VB-Script das machen oder? Ist aber ein schneller und eleganter Weg, wie ich finde.
http://toolsandmore.de/Central/Produkte/Software/System-Tools/Winscript ...
MFG
CAT
Hallo Biber,
leider hat sich an meinem Problem mit der neuen (zugemailten) Version nichts geändert.
Ich kriege damit immer noch diese Ausgabe:
C:\test>New007GetAllDateTimeInfos.bat /s
INDate=13.02.2006
INTime=22:23:42,04
DateOrder=TT-MM-JJ
KW=7
OSKW=2
DoW=44
DD=T!
TT=T!
MM=M!
JJ=2006
YY=2006
hh=h!
min=23
ss=42
ms=04
Ich hab jetzt nochmal ausprobiert und es liegt immer noch an der selben Zeile.
Wenn ich die Zeile
For %%i in (DD TT MM hh) DO IF DEFINED %%i Set "%%i=10!%%i!"
einfach mal auskommentiere, klappt schon alles.
C:\test>New007GetAllDateTimeInfos.bat /s
INDate=13.02.2006
INTime=22:25:26,78
DateOrder=TT-MM-JJ
KW=7
OSKW=2
DoW=44
DD=13
TT=13
MM=02
JJ=2006
YY=2006
hh=22
min=25
ss=26
ms=78
Wenn die Zeile nur dafür notwendig ist um auf 2 Stellen aufzufüllen, dann brauch ich sie ja eigentlich nicht oder ?
Denn bei mir sind die Werte ja auch ohne diese Zeile schon immer zweistellig.
Wundert mich nur, dass es bei dir damit klappt.
Was mich jetzt etwas verwirrt hat, waren die anderen Zeilen, die du da als Kommentar drin hattest.
::IF defined DD Set "DD=10%DD%"
::IF defined TT Set "TT=10%TT%"
::IF defined MM Set "MM=10%MM%"
::IF defined DD Set "hh=10%hh%"
:: Endlocal DisAbleDelayedExpansion
Erfüllen die nicht den gleichen Zweck ?
Wenn ich die mit reinnehme klappt es jedenfalls noch ? Oder war das echt nur als Test von dir gedacht ?
In der 4. Zeile vermute ich, meintest du aber warscheinlich hh, nicht DD.
Also ohne die For-Schleife kriege ich bei mir auf jeden Fall die gewünschten Ergebnisse und damit läuft mein LogBatch jetzt auch so wie gewünscht (sogar am 08. und 09. eines Monats).
Ach und noch ne kleine Sache die mir aufgefallen ist, wenn du im TUT ne Zeile nur durchstreichst, wird sie mir Copy&Paste trotzdem als ganz normale Zeile übernommen. Sollte man evtl. zusätzlich auskommentieren.
Könnte ne Fehlerquelle für andere sein.
Auf jeden Fall erst nochmal Danke für deine Mühe.
nette Grüße
superfrog
leider hat sich an meinem Problem mit der neuen (zugemailten) Version nichts geändert.
Ich kriege damit immer noch diese Ausgabe:
C:\test>New007GetAllDateTimeInfos.bat /s
INDate=13.02.2006
INTime=22:23:42,04
DateOrder=TT-MM-JJ
KW=7
OSKW=2
DoW=44
DD=T!
TT=T!
MM=M!
JJ=2006
YY=2006
hh=h!
min=23
ss=42
ms=04
Ich hab jetzt nochmal ausprobiert und es liegt immer noch an der selben Zeile.
Wenn ich die Zeile
For %%i in (DD TT MM hh) DO IF DEFINED %%i Set "%%i=10!%%i!"
einfach mal auskommentiere, klappt schon alles.
C:\test>New007GetAllDateTimeInfos.bat /s
INDate=13.02.2006
INTime=22:25:26,78
DateOrder=TT-MM-JJ
KW=7
OSKW=2
DoW=44
DD=13
TT=13
MM=02
JJ=2006
YY=2006
hh=22
min=25
ss=26
ms=78
Wenn die Zeile nur dafür notwendig ist um auf 2 Stellen aufzufüllen, dann brauch ich sie ja eigentlich nicht oder ?
Denn bei mir sind die Werte ja auch ohne diese Zeile schon immer zweistellig.
Wundert mich nur, dass es bei dir damit klappt.
Was mich jetzt etwas verwirrt hat, waren die anderen Zeilen, die du da als Kommentar drin hattest.
::IF defined DD Set "DD=10%DD%"
::IF defined TT Set "TT=10%TT%"
::IF defined MM Set "MM=10%MM%"
::IF defined DD Set "hh=10%hh%"
:: Endlocal DisAbleDelayedExpansion
Erfüllen die nicht den gleichen Zweck ?
Wenn ich die mit reinnehme klappt es jedenfalls noch ? Oder war das echt nur als Test von dir gedacht ?
In der 4. Zeile vermute ich, meintest du aber warscheinlich hh, nicht DD.
Also ohne die For-Schleife kriege ich bei mir auf jeden Fall die gewünschten Ergebnisse und damit läuft mein LogBatch jetzt auch so wie gewünscht (sogar am 08. und 09. eines Monats).
Ach und noch ne kleine Sache die mir aufgefallen ist, wenn du im TUT ne Zeile nur durchstreichst, wird sie mir Copy&Paste trotzdem als ganz normale Zeile übernommen. Sollte man evtl. zusätzlich auskommentieren.
Könnte ne Fehlerquelle für andere sein.
Auf jeden Fall erst nochmal Danke für deine Mühe.
nette Grüße
superfrog
Hallo Biber,
schön dass du es noch rausgefunden hast und es kein "nicht-reproduzierbarer Bug" ist.
An sowas kann man nämlich verzweifeln.
Werde mich dann aber wohl für Version a) entscheiden, da wie du schon sagst, ich die Registry-Settings auf anderen Rechnern ja nicht unbedingt weiß.
Obwohl es genau genommen doch nicht so unübersichtlich viele Rechner sein werden, als dass man da nicht auch nen bestimmten Registry-Eintrag vorraussetzen könnte.
Aber ich will die Fehlerquellen bei sowas möglichst minimieren.
Hab meinen Batch jetzt entsprechend angepasst.
Nett von dir dass du, obwohl du es nicht nachvollziehen konntest, trotzdem nochmal geforscht hast.
Abermals Danke.
Grüße
superfrog
schön dass du es noch rausgefunden hast und es kein "nicht-reproduzierbarer Bug" ist.
An sowas kann man nämlich verzweifeln.
Werde mich dann aber wohl für Version a) entscheiden, da wie du schon sagst, ich die Registry-Settings auf anderen Rechnern ja nicht unbedingt weiß.
Obwohl es genau genommen doch nicht so unübersichtlich viele Rechner sein werden, als dass man da nicht auch nen bestimmten Registry-Eintrag vorraussetzen könnte.
Aber ich will die Fehlerquellen bei sowas möglichst minimieren.
Hab meinen Batch jetzt entsprechend angepasst.
Nett von dir dass du, obwohl du es nicht nachvollziehen konntest, trotzdem nochmal geforscht hast.
Abermals Danke.
Grüße
superfrog
Hallo,
klasse Anleitung.
Habe aber leider 2 Kleine Probleme bei mir gefunden.
Beim Aufruf der Batch Datei von einem Netzlaufwerk, das als Laufwerk
Verbunden ist, hängt die Batch, oder geht in eine Schlaufe.
Da der Aufruf von /? und /h Funktioniert, denke ich, das beim Aufruf der VBS
Routine was daneben geht.
Das 2. Problem betrifft die Variablen DoY und cDoW werden nicht angezeigt.
Desweiteren scheint die Variable DoW der Wert für DoY zu sein.
Folgende Ausgabe bekomme ich:
INDate=17.02.2006
INTime=12:00:26,93
DateOrder=TT-MM-JJ
KW=7
OSKW=6
DoW=48
DD=17
TT=17
MM=02
JJ=2006
YY=2006
hh=12
min=00
ss=26
ms=93
Getestet habe ichs auf meinem Rechner (Windows XP Pro De, Sp2), sowie auf einem meiner Server (Windows 2000 De, SP4)
Die Variablen DoY und cDoW werden gar nicht gesetzt.
Muss ich an meinem System noch diverse Einstellungen vornehmen?
Grüße
AS-Net
klasse Anleitung.
Habe aber leider 2 Kleine Probleme bei mir gefunden.
Beim Aufruf der Batch Datei von einem Netzlaufwerk, das als Laufwerk
Verbunden ist, hängt die Batch, oder geht in eine Schlaufe.
Da der Aufruf von /? und /h Funktioniert, denke ich, das beim Aufruf der VBS
Routine was daneben geht.
Das 2. Problem betrifft die Variablen DoY und cDoW werden nicht angezeigt.
Desweiteren scheint die Variable DoW der Wert für DoY zu sein.
Folgende Ausgabe bekomme ich:
INDate=17.02.2006
INTime=12:00:26,93
DateOrder=TT-MM-JJ
KW=7
OSKW=6
DoW=48
DD=17
TT=17
MM=02
JJ=2006
YY=2006
hh=12
min=00
ss=26
ms=93
Getestet habe ichs auf meinem Rechner (Windows XP Pro De, Sp2), sowie auf einem meiner Server (Windows 2000 De, SP4)
Die Variablen DoY und cDoW werden gar nicht gesetzt.
Muss ich an meinem System noch diverse Einstellungen vornehmen?
Grüße
AS-Net
@Biber
Hallo Biber
super Tutorial, darfst gerne so weitermachen, wie hast du geschrieben ? .. "Ich verzichte mal auf alle Registry-Abfragen (nur Bordmittel). .." genau richtig, nochmals super.
So genug gelobt (trotzdem super), eins verstehe ich trotz intensiven studierens nicht.
Wie erreiche ich, das die mit set gesetzten "umgebungsvariablen" in allen anderen (nach Ablauf des GetAllDateTimeInfos.bat) geöffneten Eingabeaufforderungen auch abrufbar und benutzbar sind, also "global" nutzbar.
Du hast zwar mal geschrieben
"... Dann noch einen optionalen Parameter zum Setzen der ermittelten Werte "global". Nenn ich mal /s wie SET. ..."
aber die %umgebungsvariablen% sind nur in diesem cmd-Aufruf verwertbar nicht in weiteren ??
Welchen Schalter habe ich übersehen ? Welche Einstellung muss ich ändern ??
Gruss und Danke
perry6
Hallo Biber
super Tutorial, darfst gerne so weitermachen, wie hast du geschrieben ? .. "Ich verzichte mal auf alle Registry-Abfragen (nur Bordmittel). .." genau richtig, nochmals super.
So genug gelobt (trotzdem super), eins verstehe ich trotz intensiven studierens nicht.
Wie erreiche ich, das die mit set gesetzten "umgebungsvariablen" in allen anderen (nach Ablauf des GetAllDateTimeInfos.bat) geöffneten Eingabeaufforderungen auch abrufbar und benutzbar sind, also "global" nutzbar.
Du hast zwar mal geschrieben
"... Dann noch einen optionalen Parameter zum Setzen der ermittelten Werte "global". Nenn ich mal /s wie SET. ..."
aber die %umgebungsvariablen% sind nur in diesem cmd-Aufruf verwertbar nicht in weiteren ??
Welchen Schalter habe ich übersehen ? Welche Einstellung muss ich ändern ??
Gruss und Danke
perry6
hi Biber,
ein fantastisches Script
Habe eine Anmerkung:
Durch deine Änderung von %time& auf 'time/t' (weil es %time% nicht unter WinNT gibt, werden nun die Sekunden (+ms) nicht mehr ausgegeben (zumindest bei mir)
ich meine damit:
C:\Documents and Settings\Administrator>echo %time%
1:00:48,41
C:\Documents and Settings\Administrator>time/t
01:00
Das ist für meine Zwecke schlecht (will Zeiten in ein Log schreiben, und da brauch ich auch die Sekunden)
ich denke, das kann man so unmgehen
...
set MYTIME=%time%
TIME /T > CURRTIME.tmp
IF NOT DEFINED MYTIME SET /p MYTIME=<CURRTIME.tmp
del /q CURRTIME.tmp
...
und weiter:
FOR /F "delims=" %%i in ("%MYTIME%") do Set "INTime=%%i"
(statt: FOR /F "delims=" %%i in ('time/T') do Set "INTime=%%i" )
...
Falls %time% gesetzt ist, nimmt er es. Falls nicht, nimmt er time/t
lg,
Werner
ein fantastisches Script
Habe eine Anmerkung:
Durch deine Änderung von %time& auf 'time/t' (weil es %time% nicht unter WinNT gibt, werden nun die Sekunden (+ms) nicht mehr ausgegeben (zumindest bei mir)
ich meine damit:
C:\Documents and Settings\Administrator>echo %time%
1:00:48,41
C:\Documents and Settings\Administrator>time/t
01:00
Das ist für meine Zwecke schlecht (will Zeiten in ein Log schreiben, und da brauch ich auch die Sekunden)
ich denke, das kann man so unmgehen
...
set MYTIME=%time%
TIME /T > CURRTIME.tmp
IF NOT DEFINED MYTIME SET /p MYTIME=<CURRTIME.tmp
del /q CURRTIME.tmp
...
und weiter:
FOR /F "delims=" %%i in ("%MYTIME%") do Set "INTime=%%i"
(statt: FOR /F "delims=" %%i in ('time/T') do Set "INTime=%%i" )
...
Falls %time% gesetzt ist, nimmt er es. Falls nicht, nimmt er time/t
lg,
Werner
hab noch eine kleinigkeit hinzugefügt:
Da man oft auch das Jahr 2 stellig braucht:
...
For %%i in (INDate INTime %AllDateTimeVars%) do @if defined %%i set %%i
:: Werner 070920: Add ShortYear
IF defined YY SET "YYSHORT=%YY:~-2,2%"
IF defined JJ SET "JJSHORT=%JJ:~-2,2%"
echo YYshort=%YYSHORT%
echo JJshort=%JJSHORT%
lg,
Werner
Da man oft auch das Jahr 2 stellig braucht:
...
For %%i in (INDate INTime %AllDateTimeVars%) do @if defined %%i set %%i
:: Werner 070920: Add ShortYear
IF defined YY SET "YYSHORT=%YY:~-2,2%"
IF defined JJ SET "JJSHORT=%JJ:~-2,2%"
echo YYshort=%YYSHORT%
echo JJshort=%JJSHORT%
lg,
Werner
Hallo,
hab Dein Artikel gelesen ! und finde es supper. Danke an dieses Stelle!
Hab aber noch ein Frage die Dein Script aufbaut.
Kann ich irgendwie ein verzeichniss durchsuchen und nur die Dateien bestimmtes Monat rausfilten ?
Also ich will in bestimmtes Verzechnis alle Dateien suchen und nur die Dateien bestimmtes Monat zippen oder wo anders verschieben ! Hättest Du da ein Tipp ?
danke im voraus
hab Dein Artikel gelesen ! und finde es supper. Danke an dieses Stelle!
Hab aber noch ein Frage die Dein Script aufbaut.
Kann ich irgendwie ein verzeichniss durchsuchen und nur die Dateien bestimmtes Monat rausfilten ?
Also ich will in bestimmtes Verzechnis alle Dateien suchen und nur die Dateien bestimmtes Monat zippen oder wo anders verschieben ! Hättest Du da ein Tipp ?
danke im voraus
Hallo Biber,
vielen Dank für die Erklärung und Weitergabe Deines KnowHows.
Rauspicken kann ich mir diverse Teile, nur funktioniert Dein batch leider bei mir nicht.
ich bekomme immer eine Fehlermeldung:
"Set" ist syntaktisch an dieser Stelle nicht verarbeitbar.
Dies kommt m.E. aus der Belegung der cDoW.
Wenn ich nach ... set "MM=%MM:~-2,2%" ... einfüge:
IF NOT defined DoW echo DoW nicht definiert
pause
hält der batch bei pause an und sagt vorher, daß DoW nicht definiert ist.
Eine Pause nach den zwei Blöcken: If defined DD / TT erreicht der Batch nicht mehr,
da er mit: "Set" ist syntaktisch an ... abbricht.
Was habe ich falsch konfiguriert? Gibt es das öfter oder bin ich der Einzige?
lg
stefan#
vielen Dank für die Erklärung und Weitergabe Deines KnowHows.
Rauspicken kann ich mir diverse Teile, nur funktioniert Dein batch leider bei mir nicht.
ich bekomme immer eine Fehlermeldung:
"Set" ist syntaktisch an dieser Stelle nicht verarbeitbar.
Dies kommt m.E. aus der Belegung der cDoW.
Wenn ich nach ... set "MM=%MM:~-2,2%" ... einfüge:
IF NOT defined DoW echo DoW nicht definiert
pause
hält der batch bei pause an und sagt vorher, daß DoW nicht definiert ist.
Eine Pause nach den zwei Blöcken: If defined DD / TT erreicht der Batch nicht mehr,
da er mit: "Set" ist syntaktisch an ... abbricht.
Was habe ich falsch konfiguriert? Gibt es das öfter oder bin ich der Einzige?
lg
stefan#
Hallo Biber,
erst mal vorab: Klasse, der Workshop!
Und nu ne kleine Frage, die ich bisher noch nicht lösen konnte...
Deinen Zweizeiler und ne kleine Batch dazu als Grundlage hab ich was ähnliches zusammengebaut, um die Datensicherung mehrerer Server (welche einmal die Woche komplett woandershin gesichert werden) nach Kalenderwochen zu speichern, so weit, so gut, klappt auch. Jetzt das Problem: Da der Speicherplatz leider etwas beschränkt ist (und der Kunde zu geizig, mehr bereitzustellen), kann ich maximal 3 Wochensicherungen auf der Platte unterbringen, für die nächste muss zuerst die älteste Sicherung gelöscht werden. Also hab ich mir gedacht, könnte man ja anhand der aktuellen Kalenderwoche berechnen, einfach davon 3 abziehen, die entsprechende Sicherung mit der Kalenderwochennummer drin löschen, gut ist... Dem war aber nicht so, ich krieg das einfach nicht hin und muss stattdessen zur Zeit jede Woche VOR der aktuellen Sicherung die älteste manuell löschen. Ist jetzt nicht mühselig, aber da ich irgendwann auch mal Urlaub habe, würde ich das gerne automatisieren, bevor mir die Sache um die Ohren fliegt und ich nicht da bin... Leider gibt es vor Ort nur User, die gerade mal wissen, wo der Einschaltknopf vom eigenen Rechner ist, von da ist also auch keine Hilfe zu erwarten. Hast Du irgendeine Idee, wie ich das hinkriegen könnte?
Danke schon mal vorab
testbild
erst mal vorab: Klasse, der Workshop!
Und nu ne kleine Frage, die ich bisher noch nicht lösen konnte...
Deinen Zweizeiler und ne kleine Batch dazu als Grundlage hab ich was ähnliches zusammengebaut, um die Datensicherung mehrerer Server (welche einmal die Woche komplett woandershin gesichert werden) nach Kalenderwochen zu speichern, so weit, so gut, klappt auch. Jetzt das Problem: Da der Speicherplatz leider etwas beschränkt ist (und der Kunde zu geizig, mehr bereitzustellen), kann ich maximal 3 Wochensicherungen auf der Platte unterbringen, für die nächste muss zuerst die älteste Sicherung gelöscht werden. Also hab ich mir gedacht, könnte man ja anhand der aktuellen Kalenderwoche berechnen, einfach davon 3 abziehen, die entsprechende Sicherung mit der Kalenderwochennummer drin löschen, gut ist... Dem war aber nicht so, ich krieg das einfach nicht hin und muss stattdessen zur Zeit jede Woche VOR der aktuellen Sicherung die älteste manuell löschen. Ist jetzt nicht mühselig, aber da ich irgendwann auch mal Urlaub habe, würde ich das gerne automatisieren, bevor mir die Sache um die Ohren fliegt und ich nicht da bin... Leider gibt es vor Ort nur User, die gerade mal wissen, wo der Einschaltknopf vom eigenen Rechner ist, von da ist also auch keine Hilfe zu erwarten. Hast Du irgendeine Idee, wie ich das hinkriegen könnte?
Danke schon mal vorab
testbild
Hallo Biber,
ich tüftele schon eine Weile (leider bis jetzt Erfolglos) mit Deiner Batch herum!
Ich möchte alle Dateien in einem Verzeichnis in das Format:
JJ.MM.TT_hh.mm.ss.ms.txt
umbenennen.
Die Zeit muss dem Zeitstempel der Datei entsprechen!
Hast Du hierfür auf die eine Lösung für mich?
ich tüftele schon eine Weile (leider bis jetzt Erfolglos) mit Deiner Batch herum!
Ich möchte alle Dateien in einem Verzeichnis in das Format:
JJ.MM.TT_hh.mm.ss.ms.txt
umbenennen.
Die Zeit muss dem Zeitstempel der Datei entsprechen!
Hast Du hierfür auf die eine Lösung für mich?
Hallo Biber,
VIELEN Dank für die schnelle und ausführliche Antwort!
hmmmm
auf Millisekunden könnte ich ja verzichten!
Aber ich kann nicht ausschließen, das zwei (oder mehrere) Dateien innerhalb einer Minute erzeugt werden!
Daher sind Sekunden wohl die minimale Anforderung!
Da muss ich noch mal auf die Suche gehen
und schau'n, wo ich die Sekunden her bekomme!
*Schmunzel*
VIELEN Dank für die schnelle und ausführliche Antwort!
hmmmm
auf Millisekunden könnte ich ja verzichten!
Aber ich kann nicht ausschließen, das zwei (oder mehrere) Dateien innerhalb einer Minute erzeugt werden!
Daher sind Sekunden wohl die minimale Anforderung!
Da muss ich noch mal auf die Suche gehen
und schau'n, wo ich die Sekunden her bekomme!
...aber das Sternzeichen könnte ich errechnen..
*Schmunzel*
Danke Biber!
Kleine Anmerkung, 'AllDateTimeVars' wird mit '/u' nicht gelöscht.
Grüße, Steffen
Kleine Anmerkung, 'AllDateTimeVars' wird mit '/u' nicht gelöscht.
Grüße, Steffen
Hallo Biber,
ich setze dein sehr gutes Script schon sein fast 2 Jahren erfolgreich ein, auf WinXP SP2 Rechnern. Heute wollte ich es auf einem XP Sp3 Rechner einrichten leider ohne erfolg, es verschwinden alle Icons auf dem Desktop, inklusive der Startleiste und ich kann nur noch über den TaskManager den Benutzer abmelden.
Ich habe auf dem Client cwrsync drauf und sicher so verschiedene Daten. ich habe deine Datei mit folgendem Befehl in meine rsync Batch Datei mit eingebunden:
Call GetAllDateTimeInfos /s /q
set budir=%JJ%-%MM%-%TT%
set logdir=%JJ%-%MM%-%TT%_%hh%-%min%
Call GetAllDateTimeInfos /u
rsync -rlt --force --stats --ignore-errors --exclude-from=ausschluss.txt --delete --delete-excluded --backup --backup-dir=%budir% -av '/cygdrive/c/Dokumente und Einstellungen/User' TKServer::cwrsyncuser >E:\%logdir%_Logfile_von_User_Eigene.log
Mach ich da was falsch, oder ist dir bekannt dass es mit SP3 Probleme gibt?
ich setze dein sehr gutes Script schon sein fast 2 Jahren erfolgreich ein, auf WinXP SP2 Rechnern. Heute wollte ich es auf einem XP Sp3 Rechner einrichten leider ohne erfolg, es verschwinden alle Icons auf dem Desktop, inklusive der Startleiste und ich kann nur noch über den TaskManager den Benutzer abmelden.
Ich habe auf dem Client cwrsync drauf und sicher so verschiedene Daten. ich habe deine Datei mit folgendem Befehl in meine rsync Batch Datei mit eingebunden:
Call GetAllDateTimeInfos /s /q
set budir=%JJ%-%MM%-%TT%
set logdir=%JJ%-%MM%-%TT%_%hh%-%min%
Call GetAllDateTimeInfos /u
rsync -rlt --force --stats --ignore-errors --exclude-from=ausschluss.txt --delete --delete-excluded --backup --backup-dir=%budir% -av '/cygdrive/c/Dokumente und Einstellungen/User' TKServer::cwrsyncuser >E:\%logdir%_Logfile_von_User_Eigene.log
Mach ich da was falsch, oder ist dir bekannt dass es mit SP3 Probleme gibt?
Hallo Biber,
herzlichen Dank für das Tutorial. Du glänzt nicht nur mit Wissen, sondern kannst es auch sehr gut vermitteln.
Ich habe ein paar Fragen bzw. Anregungen:
herzlichen Dank für das Tutorial. Du glänzt nicht nur mit Wissen, sondern kannst es auch sehr gut vermitteln.
Ich habe ein paar Fragen bzw. Anregungen:
- Du ermittelst die Sekundenbruchteile, also eine zweistellige Zahl. Das müßten demzufolge hundertstel Sekunden und nicht tausendstel Sekunden sein, also Zentisekunden (cs, zs oder hs) und nicht Millisekunden (ms). Stimmt doch, oder?
- Am Ende vieler Zeilen befinden sich ein oder mehrere Leerzeichen. Kann ich (oder muss ich) diesen Weißraum am Ende aller Zeilen bedenkenlos entfernen, oder gibt es irgend eine Zeile, in der er beabsichtigt ist? Als Alternative zur Möglichkeit, sich den Code in Form einer Datei herunterzuladen – was hältst du davon, die Zeilen mit Schlüsselwörtern zu beenden, die der Benutzer dann zusammen mit dem Weißraum per »Suchen und Ersetzen« im Editor entfernt?
- Du wirst mir hoffentlich die folgende Anfängerfrage verzeihen: Wenn ich GetAllDateTimeInfos /s aus einem anderen Batch heraus aufgerufen habe, muss ich die Variablen wieder mit GetAllDateTimeInfos /u löschen?
Hallo Biber!
Danke für die Beantwortung meiner drei Fragen.
Google liefert nur 44 Ergebnisse für Zentisekunde. Die allgemein gebräuchliche Bezeichnung ist sicherlich Hundertstel (Sekunde). Ich meine aber, dass Zentisekunde deutlich bequemer auszusprechen ist.
Die englische Bezeichnung Centisecond findet Google immerhin 11000 mal.
Wie viele Mitbürger Dezimeter oder Dezisekunde nicht verstehen, halte ich in diesem Zusammenhang nicht für relevant, weil wahrscheinlich noch mehr Mitbürger weniger von Batch-Scripting verstehen als ich und sogar 99,9% weniger als du. Ich hätte also keine Bedenken, auch die Bezeichnung Deciseconds einzusetzen, wenn ich davon ausgehen müßte, dass 99,9% meiner Mitbürger auch dann gründlich (einige gar vergeblich) nachdenken müßten, wenn ich Zehntel Sekunde schriebe. Smile.
So viel zur Allgemeingebräuchlichkeit der Bezeichnungen für die Sekundenbruchteile zwischen der vollen Sekunde und der Millisekunde.
Es gibt aber einen internationalen Standard für die Bezeichnungen der Vielfachen und der Bruchteile von Einheiten im metrischen System. Über die Sekunde und das internationale Einheitensystem:
http://en.wikipedia.org/wiki/Second
http://de.wikipedia.org/wiki/Sekunde_(Einheit)#Abgeleitete_Ma.C3.9Feinh ...
http://en.wikipedia.org/wiki/International_System_of_Units#Units
Sowohl Decisecond als auch Centisecond sind wohldefiniert. Dezisekunde und Zentisekunde sind nur die Angleichungen der englischen bzw. lateinischen Bezeichnungen an die deutsche Sprache; sie sind logischerweise ebenfalls offiziell, wenn auch im Alltag ungebräuchlich.
Übrigens gibt es auch einen internationalen Standard für die Reihenfolge und die Schreibweise von Jahr, Monat und Tag (Teil von ISO 8601):
http://www.iso.org/iso/support/faqs/faqs_widely_used_standards/widely_u ...
Wenn also irgendwo folgendes steht:
2003-04-01
Dann sagt der Standard, dass der zweite Block der Monat und der dritte der Tag ist. Und soweit ich verstanden habe, entspräche folgendes schon nicht mehr dem internationalen Standard:
03-04-01 oder 2003/04/01
Es ist also wichtig, dass erstens der Bindestrich verwendet wird und zweitens, dass das Jahr als vierstellige Zahl angegeben wird.
Für den Zeitstempel im Dateinamen meiner Logfiles werde ich folgende Schreibweise verwenden:
YYYY-MM-DDThh;mm;ss
Beispiel
2009-02-21T12;19;00
Das Semikolon kommt dem Doppelpunkt optisch am nächsten und ist im Gegensatz zum Doppelpunkt in Dateinamen erlaubt. Die Schreibweise hat außerdem den Vorteil, dass die Reihenfolge in der Dateienliste, die ein Dateibrowser anzeigt, der Ordnung nach Datum logisch entspricht, wenn sich der Benutzer die Liste nach Namen ordnen lässt.
Mmh, in Bezug auf die Zeitzone, scheint mir der ISO-Standard 8601 wenig eindeutig zu sein. Wenn ich also eines meiner Logfiles an einen Kumpel in der Ukraine verschicken will, wäre es wohl besser, ich schriebe
YYYY-MM-DDUTC+1hh;mm;ss bzw. YYYY-MM-DDUTC+2hh;mm;ss (Sommerzeit)
Oha, auch dafür gibt es eine internationale Schreibweise, nämlich laut http://de.wikipedia.org/wiki/Koordinierte_Weltzeit
YYYY-MM-DDThh;mm;ss+1;00 bzw. YYYY-MM-DDThh;mm;ss+2;00 (Sommerzeit)
Danke für die Beantwortung meiner drei Fragen.
Google liefert nur 44 Ergebnisse für Zentisekunde. Die allgemein gebräuchliche Bezeichnung ist sicherlich Hundertstel (Sekunde). Ich meine aber, dass Zentisekunde deutlich bequemer auszusprechen ist.
Die englische Bezeichnung Centisecond findet Google immerhin 11000 mal.
Wie viele Mitbürger Dezimeter oder Dezisekunde nicht verstehen, halte ich in diesem Zusammenhang nicht für relevant, weil wahrscheinlich noch mehr Mitbürger weniger von Batch-Scripting verstehen als ich und sogar 99,9% weniger als du. Ich hätte also keine Bedenken, auch die Bezeichnung Deciseconds einzusetzen, wenn ich davon ausgehen müßte, dass 99,9% meiner Mitbürger auch dann gründlich (einige gar vergeblich) nachdenken müßten, wenn ich Zehntel Sekunde schriebe. Smile.
So viel zur Allgemeingebräuchlichkeit der Bezeichnungen für die Sekundenbruchteile zwischen der vollen Sekunde und der Millisekunde.
Es gibt aber einen internationalen Standard für die Bezeichnungen der Vielfachen und der Bruchteile von Einheiten im metrischen System. Über die Sekunde und das internationale Einheitensystem:
http://en.wikipedia.org/wiki/Second
http://de.wikipedia.org/wiki/Sekunde_(Einheit)#Abgeleitete_Ma.C3.9Feinh ...
http://en.wikipedia.org/wiki/International_System_of_Units#Units
Sowohl Decisecond als auch Centisecond sind wohldefiniert. Dezisekunde und Zentisekunde sind nur die Angleichungen der englischen bzw. lateinischen Bezeichnungen an die deutsche Sprache; sie sind logischerweise ebenfalls offiziell, wenn auch im Alltag ungebräuchlich.
Übrigens gibt es auch einen internationalen Standard für die Reihenfolge und die Schreibweise von Jahr, Monat und Tag (Teil von ISO 8601):
http://www.iso.org/iso/support/faqs/faqs_widely_used_standards/widely_u ...
Wenn also irgendwo folgendes steht:
2003-04-01
Dann sagt der Standard, dass der zweite Block der Monat und der dritte der Tag ist. Und soweit ich verstanden habe, entspräche folgendes schon nicht mehr dem internationalen Standard:
03-04-01 oder 2003/04/01
Es ist also wichtig, dass erstens der Bindestrich verwendet wird und zweitens, dass das Jahr als vierstellige Zahl angegeben wird.
Für den Zeitstempel im Dateinamen meiner Logfiles werde ich folgende Schreibweise verwenden:
YYYY-MM-DDThh;mm;ss
Beispiel
2009-02-21T12;19;00
Das Semikolon kommt dem Doppelpunkt optisch am nächsten und ist im Gegensatz zum Doppelpunkt in Dateinamen erlaubt. Die Schreibweise hat außerdem den Vorteil, dass die Reihenfolge in der Dateienliste, die ein Dateibrowser anzeigt, der Ordnung nach Datum logisch entspricht, wenn sich der Benutzer die Liste nach Namen ordnen lässt.
Mmh, in Bezug auf die Zeitzone, scheint mir der ISO-Standard 8601 wenig eindeutig zu sein. Wenn ich also eines meiner Logfiles an einen Kumpel in der Ukraine verschicken will, wäre es wohl besser, ich schriebe
YYYY-MM-DDUTC+1hh;mm;ss bzw. YYYY-MM-DDUTC+2hh;mm;ss (Sommerzeit)
Oha, auch dafür gibt es eine internationale Schreibweise, nämlich laut http://de.wikipedia.org/wiki/Koordinierte_Weltzeit
YYYY-MM-DDThh;mm;ss+1;00 bzw. YYYY-MM-DDThh;mm;ss+2;00 (Sommerzeit)
Hallo Biber,
Test unter Windows XP Pro SP3
Ich versuche das nachzuvollziehen. Bei mir ändert sich nur die Reihenfolge von Tag, Monat und Jahr bei der Eingabeaufforderung. An der Reihenfolge im aktuellen Datum ändert sich nur etwas, wenn ich auch den Wert von sShortDate ändere.
Übrigens habe ich nicht getestet, ob die Werte nach einem Windows-Neustart aneinander angepasst werden, wenn man z. B. nur den Wert von iDate ändert. Andererseits ist es meiner Meinung nach praxisfern, dass ein Benutzer die Werte über die Registry anpasst. Worauf ich hinauswill, ist, dass iDate (möglicherweise) nicht mit 100%iger Sicherheit die tatsächliche Reihenfolge bei der Ausgabe des Datums liefert.
(Über ‹Systemsteuerung/Regions- und Sprachoptionen› werden natürlich alle Werte aneinander angepasst, sollten sie wenigstens.)
Ein Fehler in und ein oder zwei Fragen zu GetAllSystemDateTimeInfos_3.bat:
Anstatt
muss es, glaube ich,
heißen, weil sonst nie eine Ausgabe erfolgt.
In diesem Zusammenhang wüßte ich gerne, wozu das at-Zeichen vor dem if gut ist (weil echo ja schon ausgeschaltet ist). Wahrscheinlich wurde die Frage irgendwo im Forum schon mehr als einmal beantwortet. Ichhabe zwar noch nicht das Forum nach einer Antwort durchsucht, bin aber mit Google nicht weitergekommen. Und auch nicht mit der Forum-internen Suche. (Für den Moment gehe ich davon aus, dass das @ lediglich eine Markierung ist, die der Übersicht dienen soll, aber sonst nichts bewirkt, sofern echo bereits ausgeschaltet ist.)
Du hast außerdem geschrieben, der Parameter "/W" sei undokumentiert im Gegensatz zu dem Parameter "/Wait". In GetAllSystemDateTimeInfos_3.bat hast du es trotzdem bei dem undokumentierten Parameter belassen. Absicht oder vergessen?
Editiert
In GetAllSystemDateTimeInfos_3.bat wird das Datum noch mit Hilfe von %date% ermittelt. Das ist in der letzten Version korrigiert:
Lässt sich Code eigentlich als Zitat formatieren?
Editiert 2
Kürzlich habe ich gelesen, dass manche Leute den nativen Befehl Find durch den (Unix ?) Befehl Find ersetzen (Für Windows über cygwin erhältlich, soweit ich mich erinnere). Das Unix-Find scheint sogar recht beliebt bei Windows-Benutzern zu sein. Wäre es nicht gut, in GetAllSystemDateTimeInfos_3.bat den Befehl Find durch Findstr ersetzen? Dann würde es auch bei den Leuten funktionieren, die nicht mehr über den nativen Befehl Find verfügen. Wobei ich nicht weiß, ob es Findstr schon unter (frühen) Windows-NT-Versionen gab. Und kompatibel zu NT soll dein Script ja sein. Übrigens heißen doch auch XP und Vista intern NT. Das Echo
Grüße
dolsch
Test unter Windows XP Pro SP3
Mal weiterspielen (ändern von iDate von 2 auf 1 und danach auf 0):
>reg add "HKCU\Control Panel\International" /v idate /t REG_SZ /d 1 /f
>date
Aktuelles Datum: Sa 01-10-2005
Geben Sie das neue Datum ein: (TT-MM-JJ)
>date /t
Sa 01-10-2005
>reg add "HKCU\Control Panel\International" /v idate /t REG_SZ /d 0 /f
>date /t
Sa 10-01-2005
>date
Aktuelles Datum: Sa 10-01-2005
Geben Sie das neue Datum ein: (MM-TT-JJ)
Ich versuche das nachzuvollziehen. Bei mir ändert sich nur die Reihenfolge von Tag, Monat und Jahr bei der Eingabeaufforderung. An der Reihenfolge im aktuellen Datum ändert sich nur etwas, wenn ich auch den Wert von sShortDate ändere.
Übrigens habe ich nicht getestet, ob die Werte nach einem Windows-Neustart aneinander angepasst werden, wenn man z. B. nur den Wert von iDate ändert. Andererseits ist es meiner Meinung nach praxisfern, dass ein Benutzer die Werte über die Registry anpasst. Worauf ich hinauswill, ist, dass iDate (möglicherweise) nicht mit 100%iger Sicherheit die tatsächliche Reihenfolge bei der Ausgabe des Datums liefert.
(Über ‹Systemsteuerung/Regions- und Sprachoptionen› werden natürlich alle Werte aneinander angepasst, sollten sie wenigstens.)
Ein Fehler in und ein oder zwei Fragen zu GetAllSystemDateTimeInfos_3.bat:
Anstatt
For %%i in (%AllDateTimeVars%) do @if defined %%i set %%i
For %%i in (%AllSystemDateTimeVars%) do @if defined %%i set %%i
In diesem Zusammenhang wüßte ich gerne, wozu das at-Zeichen vor dem if gut ist (weil echo ja schon ausgeschaltet ist). Wahrscheinlich wurde die Frage irgendwo im Forum schon mehr als einmal beantwortet. Ich
Du hast außerdem geschrieben, der Parameter "/W" sei undokumentiert im Gegensatz zu dem Parameter "/Wait". In GetAllSystemDateTimeInfos_3.bat hast du es trotzdem bei dem undokumentierten Parameter belassen. Absicht oder vergessen?
Editiert
In GetAllSystemDateTimeInfos_3.bat wird das Datum noch mit Hilfe von %date% ermittelt. Das ist in der letzten Version korrigiert:
:: Vers 0.09 11.7.2007: Windows NT kennt weder %date% noch %time%.
Lässt sich Code eigentlich als Zitat formatieren?
Editiert 2
Kürzlich habe ich gelesen, dass manche Leute den nativen Befehl Find durch den (Unix ?) Befehl Find ersetzen (Für Windows über cygwin erhältlich, soweit ich mich erinnere). Das Unix-Find scheint sogar recht beliebt bei Windows-Benutzern zu sein. Wäre es nicht gut, in GetAllSystemDateTimeInfos_3.bat den Befehl Find durch Findstr ersetzen? Dann würde es auch bei den Leuten funktionieren, die nicht mehr über den nativen Befehl Find verfügen. Wobei ich nicht weiß, ob es Findstr schon unter (frühen) Windows-NT-Versionen gab. Und kompatibel zu NT soll dein Script ja sein. Übrigens heißen doch auch XP und Vista intern NT. Das Echo
Läuft nur unter WinNT oder höher.Sorry.
ohne Versionsangabe ist also möglicherweise mißverständlich.Grüße
dolsch
Hallo Biber!
Wie gesagt, ich bin Anfänger. Dein Tutorial ist schon alleine aus folgenden Gründen interessant für mich.
1. weil ich gelernt habe, dass man Batch-Scripte mit Parametern aufrufen kann und den Benutzer z.B. über den Parameter /? zu einer Batch-internen Hilfe umleiten kann.
2. weil ich einiges über Tokens und Delims gelernt habe.
3. weil ich gelernt habe, wie man Variablen in Schleifen vordefiniert, individuell definiert, resettet u.s.w..
Danke dir ein weiteres Mal für die Beantwortung meiner Fragen.
An alle inkl. Biber
Hier ist die Basis für meinen Zeitstempler:
Ich habe das mit vielen (aber nicht allen) über das Panel "Regions- und Sprachoptionen" verfügbaren Voreinstellungen auf meinem Rechner getestet. Leider hat mir dann jemand, den ich gebeten hatte, das Script zu testen, geschrieben, auf seinem simplified-Chinese-Rechner hätte er den Wochentag (also z. B. Dienstag -- auf Chinesisch) mit im Output. Ich konnte das auf meinem Rechner nicht nachvollziehen, obwohl ich die entsprechenden regionalen Einstellungen nachinstalliert hatte. Jedenfalls wollte ich zur Sicherheit, noch eine Abfrage einbauen, die klärt, ob die Werte von TT, MM und JJ Zahlen sind und falls ja, ob z. B. JJ größer als 1900 ist.
Zu diesem Zweck, habe ich folgendes Hilfsscript geschrieben:
Das funktioniert ordentlich, allerdings nur solo. Denn als ich es in den Zeitstempler eingebaut habe, habe ich gemerkt, dass der Errorlevel nie 0 ist, wenn ich in der Registry sShortDate auf MM.yyyy setze. Die For-Schleife, in der JJ gesetzt wird, scheint einen Errorlevel ungleich 0 zurückzugeben, der permanent bestehen bleibt. Jetzt frage ich mich, ob es so eine Art Errorlevel-Hierarchie gibt oder aus welchen Gründen sonst, es keine Rolle mehr zu spielen scheint, ob set (zweites Script) erfolgreich abgearbeit wird.
Editiert
Errorlevel 1, weil eine der Variablen (TT, MM oder JJ) in der inneren der verschachtelten for-Schleifen kein Wert zugewiesen wird, da es ja nur noch zwei tokens gibt; einen hatte ich ja aus sShortDate entfernt. Aber ich versteh halt nicht, warum der errorlevel nicht beim nächsten erfolgreich abgearbeiteten set (oder irgend einem anderen erfolgreich abgearbeiteten Befehl, der einen Errorlevel zurückgibt,) wieder automatisch auf 0 gesetzt wird. Ich dachte, so würde errorlevel gehandhabt.
Editiert 2
Offenbar habe ich das Problem mit den Errorlevels nicht, wenn ich den Dateityp von bat zu cmd ändere. Alternativ könnte ich CD>NUL benutzen, um den Errorlevel zu resetten. Alles sehr merkwürdig.
Ein paar Links zu den Unterschieden zwischen Bat und CMD:
http://waynes-world-it.blogspot.com/2008/08/difference-between-bat-and- ...
http://www.msfn.org/board/index.php?showtopic=120599&mode=linearplu ...
http://www.msfn.org/board/CMD-vs-Bat-file-t91459.html&mode=linear
Irgendwo hatte ich außerdem gelesen, dass prompt $T $D etwas unterschiedlich behandelt wird, je nachdem, ob aufgerufen via COMMAND.COM oder CMD.EXE. Bin mir gerade nicht sicher, ob ich das im Zusammenhang mit der Ausgabe des Wochentages gelesen hatte -- in irgend einem Kommentar auf http://www.robvanderwoude.com. Ne, hier habe ich das gelesen:
http://windowsitpro.com/Articles/Index.cfm?ArticleID=9177&DisplayTa ...
»rem Modified for Windows 2003 server
rem The Date command does not display the Day of week anymore in the standard cmd.exe
rem The old command.com still does, so this command shell is used to create the date and time elements.)«
Merkwürdig finde ich auch, wie sich manche von mir verschachtelte if-Abfragen verhalten, besonders dann, wenn sich Sprungbefehle darin befinden, selbst wenn sich die Sprungziele außerhalb der Schachtel befinden.
Ich glaub’, ich sollte mir mal ein Buch über Batch-Scripting kaufen. Schon alleine, um mir die richtige Terminologie anzueignen.
Übrigens beschleunigt der Weg über die Dummy-Datei DateOrder….txt den Zeitstempler. Zweiter Grund ist die Möglichkeit, das ganze auf Rechnern zu verwenden, auf denen die Benutzerrechte keinen Zugriff auf Regedit erlauben.
Editiert 3
Das Problem mit dem resistenten Errorlevel habe ich, glaube ich, gelöst.
Dateityp .cmd!
Dass ich auf die Registry zugreife, gefällt mir nicht. Die finale Version mit dem VBS-Script muss ich erst noch nachvollziehen. Vielmehr werde ich versuchen, sie auf meine Erfordernisse zurückzustutzen. Ich möchte, dass das Script schnell abgearbeitet wird. Den ausgeschriebenen Wochentag oder die Kalenderwoche brauche ich nicht, um den Dateinamen meiner Logfiles zeitzustempeln.
Editiert 4
Es war nicht nötig, Bibers finale Version in allen Einzelheiten nachzuvollziehen, um festzustellen, dass an der Langsamkeit des Scripts nicht Biber bzw. die Komplexität seines Codes schuld ist. Die Einbindung von vbs fand ich überraschend einfach.
Hier meine aktuelle Version. Sie greift nur im Notfall auf vbs zurück, und zwar ausschließlich wegen der Geschwindigkeit. Auch (?) meine (an meine Erfordernisse angepasste) Version bietet keine 100%ige Sicherheit, dass Datum und Zeit tatsächlich im Format JJJJ-MM-TT @ hh;min;ss ausgegeben werden.
Muss als Dateityp CMD abgespeichert werden! Und sollte ab Windows 2000 funktionieren.
Schöne Grüße
dolsch
Vielen Dank für Deine Nachfragen... ich freue mich, wenn mein
Tutorial ernsthaft und natürlich auch kritisch gelesen wird.
Tutorial ernsthaft und natürlich auch kritisch gelesen wird.
Wie gesagt, ich bin Anfänger. Dein Tutorial ist schon alleine aus folgenden Gründen interessant für mich.
1. weil ich gelernt habe, dass man Batch-Scripte mit Parametern aufrufen kann und den Benutzer z.B. über den Parameter /? zu einer Batch-internen Hilfe umleiten kann.
2. weil ich einiges über Tokens und Delims gelernt habe.
3. weil ich gelernt habe, wie man Variablen in Schleifen vordefiniert, individuell definiert, resettet u.s.w..
Danke dir ein weiteres Mal für die Beantwortung meiner Fragen.
An alle inkl. Biber
Hier ist die Basis für meinen Zeitstempler:
@echo off
:: With the help of the tutorial
::
set "myDate=%date%"
for /f "tokens=2" %%i in ("%myDate%") do set "myDate=%%i"
if not exist DateOrder?.txt (
start /wait regedit /e SystemDateTimeInfo.reg "HKEY_CURRENT_USER\Control Panel\International"
for /f "tokens=1* delims==" %%i in ('type SystemDateTimeInfo.reg ^| findstr /i "iDate"') do set "iDate=%%j"
del SystemDateTimeInfo.reg
)
if defined iDate echo File represents order in date output. Delete it, if you change the regional settings on this computer. > DateOrder%iDate%.txt
for /f "tokens=1-3 delims=-/." %%a in ("%myDate%") do (
if exist "DateOrder0.txt" for %%i in ("JJ=%%c" "MM=%%a" "TT=%%b") do set %%i
if exist "DateOrder1.txt" for %%i in ("JJ=%%c" "MM=%%b" "TT=%%a") do set %%i
if exist "DateOrder2.txt" for %%i in ("JJ=%%a" "MM=%%b" "TT=%%c") do set %%i
)
for /f "tokens=1-3 delims=:,." %%a in ("%time%") do for %%i in ("hh=%%a" "min=%%b" "ss=%%c") do set %%i
set "hh=%hh: =0%"
echo Log %JJ%-%MM%-%TT% @ %hh%;%min%;%ss%
pause
Ich habe das mit vielen (aber nicht allen) über das Panel "Regions- und Sprachoptionen" verfügbaren Voreinstellungen auf meinem Rechner getestet. Leider hat mir dann jemand, den ich gebeten hatte, das Script zu testen, geschrieben, auf seinem simplified-Chinese-Rechner hätte er den Wochentag (also z. B. Dienstag -- auf Chinesisch) mit im Output. Ich konnte das auf meinem Rechner nicht nachvollziehen, obwohl ich die entsprechenden regionalen Einstellungen nachinstalliert hatte. Jedenfalls wollte ich zur Sicherheit, noch eine Abfrage einbauen, die klärt, ob die Werte von TT, MM und JJ Zahlen sind und falls ja, ob z. B. JJ größer als 1900 ist.
Zu diesem Zweck, habe ich folgendes Hilfsscript geschrieben:
@echo off
set "alpha=beliebig"
if not defined alpha echo alpha ist nicht definiert.
set /a "beta=1%alpha%" 2>NUL
if errorlevel 1 (
echo %alpha% ist weder Dezimal- noch Oktalzahl, aber m”glicherweise eine Hexadezimalzahl.
) else (
echo %alpha% ist eine Dezimal- oder Oktalzahl, keinesfalls aber eine Hexadezimalzahl.
)
pause
Das funktioniert ordentlich, allerdings nur solo. Denn als ich es in den Zeitstempler eingebaut habe, habe ich gemerkt, dass der Errorlevel nie 0 ist, wenn ich in der Registry sShortDate auf MM.yyyy setze. Die For-Schleife, in der JJ gesetzt wird, scheint einen Errorlevel ungleich 0 zurückzugeben, der permanent bestehen bleibt. Jetzt frage ich mich, ob es so eine Art Errorlevel-Hierarchie gibt oder aus welchen Gründen sonst, es keine Rolle mehr zu spielen scheint, ob set (zweites Script) erfolgreich abgearbeit wird.
Editiert
Errorlevel 1, weil eine der Variablen (TT, MM oder JJ) in der inneren der verschachtelten for-Schleifen kein Wert zugewiesen wird, da es ja nur noch zwei tokens gibt; einen hatte ich ja aus sShortDate entfernt. Aber ich versteh halt nicht, warum der errorlevel nicht beim nächsten erfolgreich abgearbeiteten set (oder irgend einem anderen erfolgreich abgearbeiteten Befehl, der einen Errorlevel zurückgibt,) wieder automatisch auf 0 gesetzt wird. Ich dachte, so würde errorlevel gehandhabt.
Editiert 2
Offenbar habe ich das Problem mit den Errorlevels nicht, wenn ich den Dateityp von bat zu cmd ändere. Alternativ könnte ich CD>NUL benutzen, um den Errorlevel zu resetten. Alles sehr merkwürdig.
Ein paar Links zu den Unterschieden zwischen Bat und CMD:
http://waynes-world-it.blogspot.com/2008/08/difference-between-bat-and- ...
http://www.msfn.org/board/index.php?showtopic=120599&mode=linearplu ...
http://www.msfn.org/board/CMD-vs-Bat-file-t91459.html&mode=linear
Irgendwo hatte ich außerdem gelesen, dass prompt $T $D etwas unterschiedlich behandelt wird, je nachdem, ob aufgerufen via COMMAND.COM oder CMD.EXE. Bin mir gerade nicht sicher, ob ich das im Zusammenhang mit der Ausgabe des Wochentages gelesen hatte -- in irgend einem Kommentar auf http://www.robvanderwoude.com. Ne, hier habe ich das gelesen:
http://windowsitpro.com/Articles/Index.cfm?ArticleID=9177&DisplayTa ...
»rem Modified for Windows 2003 server
rem The Date command does not display the Day of week anymore in the standard cmd.exe
rem The old command.com still does, so this command shell is used to create the date and time elements.)«
Merkwürdig finde ich auch, wie sich manche von mir verschachtelte if-Abfragen verhalten, besonders dann, wenn sich Sprungbefehle darin befinden, selbst wenn sich die Sprungziele außerhalb der Schachtel befinden.
Ich glaub’, ich sollte mir mal ein Buch über Batch-Scripting kaufen. Schon alleine, um mir die richtige Terminologie anzueignen.
Übrigens beschleunigt der Weg über die Dummy-Datei DateOrder….txt den Zeitstempler. Zweiter Grund ist die Möglichkeit, das ganze auf Rechnern zu verwenden, auf denen die Benutzerrechte keinen Zugriff auf Regedit erlauben.
Editiert 3
Das Problem mit dem resistenten Errorlevel habe ich, glaube ich, gelöst.
Dateityp .cmd!
Habe ich der Übersicht wegen gelöscht, da im Wesentlichen so wie in EDITIERT 4
Dass ich auf die Registry zugreife, gefällt mir nicht. Die finale Version mit dem VBS-Script muss ich erst noch nachvollziehen. Vielmehr werde ich versuchen, sie auf meine Erfordernisse zurückzustutzen. Ich möchte, dass das Script schnell abgearbeitet wird. Den ausgeschriebenen Wochentag oder die Kalenderwoche brauche ich nicht, um den Dateinamen meiner Logfiles zeitzustempeln.
Editiert 4
Es war nicht nötig, Bibers finale Version in allen Einzelheiten nachzuvollziehen, um festzustellen, dass an der Langsamkeit des Scripts nicht Biber bzw. die Komplexität seines Codes schuld ist. Die Einbindung von vbs fand ich überraschend einfach.
Hier meine aktuelle Version. Sie greift nur im Notfall auf vbs zurück, und zwar ausschließlich wegen der Geschwindigkeit. Auch (?) meine (an meine Erfordernisse angepasste) Version bietet keine 100%ige Sicherheit, dass Datum und Zeit tatsächlich im Format JJJJ-MM-TT @ hh;min;ss ausgegeben werden.
Muss als Dateityp CMD abgespeichert werden! Und sollte ab Windows 2000 funktionieren.
@echo off
:: With the help of the tutorial
::
set "myDate=%date%"
for /f "tokens=2" %%i in ("%myDate%") do set "myDate=%%i"
if not exist DateOrder?.txt (
start /wait regedit /e SystemDateTimeInfo.reg "HKEY_CURRENT_USER\Control Panel\International"
for /f "tokens=1* delims==" %%i in ('type SystemDateTimeInfo.reg ^| findstr /i "iDate"') do set "iDate=%%j"
del SystemDateTimeInfo.reg
)
if defined iDate echo File represents order in date output. Delete it, if you change the regional settings on this computer. > DateOrder%iDate%.txt
for /f "tokens=1-3 delims=-/." %%a in ("%myDate%") do (
if exist "DateOrder0.txt" for %%i in ("YY=%%c" "MM=%%a" "DD=%%b") do set %%i
if exist "DateOrder1.txt" for %%i in ("YY=%%c" "MM=%%b" "DD=%%a") do set %%i
if exist "DateOrder2.txt" for %%i in ("YY=%%a" "MM=%%b" "DD=%%c") do set %%i
)
for %%i in (YY MM DD) do if not defined %%i goto :ViaVBS
set /a "test=1%YY%" 2>NUL
if errorlevel 1 goto :ViaVBS
set /a "test=1%MM%" 2>NUL
if errorlevel 1 goto :ViaVBS
set /a "test=1%DD%" 2>NUL
if errorlevel 1 goto :ViaVBS
if 1000 GTR %YY% goto :ViaVBS
if 12 LSS %MM% goto :ViaVBS
if 31 LSS %DD% goto :ViaVBS
goto :output
:ViaVBS
echo Wscript.Echo Year(Now)^&"-"^&Month(Now)^&"-"^&Day(Now) > ComputeDateVia.vbs
for /f "tokens=1-3 delims=-" %%a in ('cscript //nologo ComputeDateVia.vbs') do (
for %%i in ("YY=%%a" "MM=%%b" "DD=%%c") do set %%i
)
if %MM% LSS 10 set "MM=0%MM%"
if %DD% LSS 10 set "DD=0%DD%"
del ComputeDateVia.vbs
:output
for /f "tokens=1-3 delims=:,." %%a in ("%time%") do for %%i in ("hh=%%a" "min=%%b" "ss=%%c") do set %%i
set "hh=%hh: =0%"
echo Log %YY%-%MM%-%DD% @ %hh%;%min%;%ss%
pause
Schöne Grüße
dolsch
Hallo Biber,
erstmal herzlichen Dank für Dein sehr ausführliches Tutorial. Ich wurde von einem anderen Nutzer auf dieses hingewiesen, da ich derzeit versuche, ein Backup-Skript mit Wochentag- und KW-Aufteilung zu erstellen.
Nach ein wenig ausprobieren habe ich bemerkt, daß Deine finale Version bei mir auf einem Win2k3 System keine Wochentage (also Mo, Di,...) ausgibt. Kann es sein, daß in den Zeilen 87-93 und 98-104 jeweils cDoW stehen müßte (der Code also casesensitv ist)?
Schönen Gruß
Noc06
erstmal herzlichen Dank für Dein sehr ausführliches Tutorial. Ich wurde von einem anderen Nutzer auf dieses hingewiesen, da ich derzeit versuche, ein Backup-Skript mit Wochentag- und KW-Aufteilung zu erstellen.
Nach ein wenig ausprobieren habe ich bemerkt, daß Deine finale Version bei mir auf einem Win2k3 System keine Wochentage (also Mo, Di,...) ausgibt. Kann es sein, daß in den Zeilen 87-93 und 98-104 jeweils cDoW stehen müßte (der Code also casesensitv ist)?
Schönen Gruß
Noc06
Hallo Biber,
Danke für Deine prompte Antwort!
Da ich, zumindest was das Skripten angeht, lediglich (wenn überhaupt) über rudimentäre Kenntnisse verfüge, hatte ich in der Zwischenzeit und aufgrund von Unwissenheit einfach mal die "w" gegen "W" ausgetauscht und siehe da, es funktioniert - MDoof (in diesem Fall Win2k3 R2 64-bit) läßt grüßen...
Die von Dir angesprochene Vorgehensweise werde ich aber auch nochmal überprüfen und entsprechendes Feedback geben.
Gruß
Noc06
EDIT 1:
So, ich habe gerade mal 2 Tests gemacht:
ad 1: Die von Dir angegebenen Werte bekomme ich ebenfalls zurückgemeldet (sieht bei mir also identisch aus), wenn ich mit Deinem vbs arbeite.
ad 2: Ich habe spaßeshalber in Deinem Originalskript meine Änderungen, also von "cDoW", wieder rückgängig gemacht ("cDow") - der Fehler ließ sich reproduzieren. Alle Werte werden exakt so ausgegeben, wie sie zu erwarten sind - eben bis auf den Klarnamen des Wochentages.
Nachvollziehbar ist das m.E. nicht wirklich, aber was an M$ ist das schon... Mit der Änderung der Groß-/ Kleinschreibung läßt sich das Phänomen jedenfalls beheben. Jetzt muß ich nur noch ein vernünftiges Robocopyskript gebastelt bekommen.
P.S.: (OT) Gibt es eigentlich über die Datumsfunktion auch eine Möglichkeit, den Monatsletzten zu ermitteln?
Danke für Deine prompte Antwort!
Da ich, zumindest was das Skripten angeht, lediglich (wenn überhaupt) über rudimentäre Kenntnisse verfüge, hatte ich in der Zwischenzeit und aufgrund von Unwissenheit einfach mal die "w" gegen "W" ausgetauscht und siehe da, es funktioniert - MDoof (in diesem Fall Win2k3 R2 64-bit) läßt grüßen...
Die von Dir angesprochene Vorgehensweise werde ich aber auch nochmal überprüfen und entsprechendes Feedback geben.
Gruß
Noc06
EDIT 1:
So, ich habe gerade mal 2 Tests gemacht:
ad 1: Die von Dir angegebenen Werte bekomme ich ebenfalls zurückgemeldet (sieht bei mir also identisch aus), wenn ich mit Deinem vbs arbeite.
ad 2: Ich habe spaßeshalber in Deinem Originalskript meine Änderungen, also von "cDoW", wieder rückgängig gemacht ("cDow") - der Fehler ließ sich reproduzieren. Alle Werte werden exakt so ausgegeben, wie sie zu erwarten sind - eben bis auf den Klarnamen des Wochentages.
Nachvollziehbar ist das m.E. nicht wirklich, aber was an M$ ist das schon... Mit der Änderung der Groß-/ Kleinschreibung läßt sich das Phänomen jedenfalls beheben. Jetzt muß ich nur noch ein vernünftiges Robocopyskript gebastelt bekommen.
P.S.: (OT) Gibt es eigentlich über die Datumsfunktion auch eine Möglichkeit, den Monatsletzten zu ermitteln?
Moin moin,
erstmal Danke für Deinen Tipp bzgl. des Monatsletzten. Stimmt schon, da hätte man eigentlich auch selbst den Geistesblitz haben können...
Bzgl. des fehlenden Schalters: wie gesagt, meine Skriptkenntnisse sind eher rudimentärer Natur, so daß mir ein fehlendes /i im Zweifelsfall auch nach dem x-ten Durchlesen nicht aufgefallen wäre - einfacher hätte ich es mir natürlich machen können, wenn ich das "w" in Deiner Definition einfach klein geschrieben hätte; so waren es halt ein paar mehr "w", die ich groß geschrieben habe. Aber so lernt man ja auch nie aus...
Gruß und schönes WE
Noc06
erstmal Danke für Deinen Tipp bzgl. des Monatsletzten. Stimmt schon, da hätte man eigentlich auch selbst den Geistesblitz haben können...
Bzgl. des fehlenden Schalters: wie gesagt, meine Skriptkenntnisse sind eher rudimentärer Natur, so daß mir ein fehlendes /i im Zweifelsfall auch nach dem x-ten Durchlesen nicht aufgefallen wäre - einfacher hätte ich es mir natürlich machen können, wenn ich das "w" in Deiner Definition einfach klein geschrieben hätte; so waren es halt ein paar mehr "w", die ich groß geschrieben habe. Aber so lernt man ja auch nie aus...
Gruß und schönes WE
Noc06
Hallo Biber. Zu Deinem Datums-Problem von oben, indem Du per %DATE% mal ein Datum mit Wochentag und mal ein Datum ohne erhältst, gibt es eine Lösung. Verwende
echo
Dann hast Du immer ein Datum ohne Wochentag.
Ich hatte nach einer Lösung gesucht, um _per Batch_ den Wochentag eines Datums zu ermitteln. Die Lösung, auf die Du verlinkst und hier als leicht veränderte Kopie darstellst, beinhaltet den folgenden Code (nur ein Ausschnitt):
Nicht nur, dass der Code seine Grenzen der Wochentagsberechnung nicht offenlegt und auch auf (Denk-)Fehler hin in dieser Form schwer überprüfbar ist, ist er für ein TUT total ungeeignet. Denn er ist für die meisten Leser sicher unverständlich. Das Forum soll doch keine Skriptkiddys heranziehen, die den Code kopieren, aber nicht verstehen, was er tut.
Daher meine Frage: Könntest Du den Code in Deinem TUT bitte derart aufschlüsseln, dass ihn jeder versteht (also erklären, was der Autor dort macht, wie er also auf den Wochentag kommt)? Oder - wen Du keine Zeit dafür hast - soll ich mich da mal dransetzen?
Wenn ich das tun soll, dann bitte unter der Voraussetzung, dass Du den angepassten (entwirrten/erklärenden) Code danach oben in Deinem TUT einfügst, weil er hier unten sicher unterginge, und dann lohnt sich der Aufwand nicht. Was meinst Du?
Bye, nz
echo
%DATE:* =%
Dann hast Du immer ein Datum ohne Wochentag.
Ich hatte nach einer Lösung gesucht, um _per Batch_ den Wochentag eines Datums zu ermitteln. Die Lösung, auf die Du verlinkst und hier als leicht veränderte Kopie darstellst, beinhaltet den folgenden Code (nur ein Ausschnitt):
:: Algorithmus frei nach [http://www.commandline.co.uk/lib/treeview/index.php]
:: '-->Klick: Batch Function Library/Date and Time Functions/DateToDOW
...
set yy=42 & set mm=05 & set dd=23 & set TwoDigitYearMax=70
if 1%yy% LSS 200 if 1%yy% LSS 1%TwoDigitYearMax% (set yy=20%yy%) else (set yy=19%yy%)
...
set /a dd=100%dd%%%100,mm=100%mm%%%100
set /a z=14-mm,z/=12,y=yy+4800-z,m=mm+12*z-3,dow=153*m+2
set /a dow=dow/5+dd+y*365+y/4-y/100+y/400-2472630,dow%%=7,dow+=1
...
Nicht nur, dass der Code seine Grenzen der Wochentagsberechnung nicht offenlegt und auch auf (Denk-)Fehler hin in dieser Form schwer überprüfbar ist, ist er für ein TUT total ungeeignet. Denn er ist für die meisten Leser sicher unverständlich. Das Forum soll doch keine Skriptkiddys heranziehen, die den Code kopieren, aber nicht verstehen, was er tut.
Daher meine Frage: Könntest Du den Code in Deinem TUT bitte derart aufschlüsseln, dass ihn jeder versteht (also erklären, was der Autor dort macht, wie er also auf den Wochentag kommt)? Oder - wen Du keine Zeit dafür hast - soll ich mich da mal dransetzen?
Wenn ich das tun soll, dann bitte unter der Voraussetzung, dass Du den angepassten (entwirrten/erklärenden) Code danach oben in Deinem TUT einfügst, weil er hier unten sicher unterginge, und dann lohnt sich der Aufwand nicht. Was meinst Du?
Bye, nz
In Bearbeitung... (fertig)
Ich bekomme den Code nicht mehr aus meinem Kopf. Jetzt muss ich ihn knacken, egal ob der entwirrte Code danach oben im TUT eingefügt wird, oder nicht.Diesen Beitrag hier nutze ich als Protokoll und zur stückweisen Erklärung des Codes von Ritchie Lawrence. Bis ich damit fertig bin, bleibt der Hinweis "In Bearbeitung" bestehen.
Quelle des Codes: http://www.commandline.co.uk/lib/treeview/index.php, klick: Batch Function Library/Date and Time Functions/DateToDOW
Autor: Ritchie Lawrence
Hier eine angepasste Batch, die den Code von Ritchie Lawrence als Batch-Funktion startet, erweitert um die Funktionalität den Wochentag nicht als numerischen Wert sondern als Text auszugeben:
@echo off & setlocal EnableExtensions
::Das Datum "tag.monat.jahr" in seine Bestandteile zerlegen:
if "%~1" == "" ( ::kein Parameter angegeben; das aktuelle Datum %DATE% soll verwendet werden...
for /f "tokens=1-3 delims=." %%a in ("%DATE:* =%") do set _dd=%%a & set _mm=%%b & set _yy=%%c
) else ( ::das übergebene Datum verwenden...
for /f "tokens=1-3 delims=." %%a in ("%~1") do set _dd=%%a & set _mm=%%b & set _yy=%%c
)
::Rufen wir den Code von Ritchie Lawrence auf, um den Wochentag des Datums zu berechnen:
call :DateToDOW %_yy% %_mm% %_dd% _WoTgNr
::Die Wochentagsnummer (1 bis 7) in den Namen des Wochentags umwandeln:
for /f "tokens=%_WoTgNr%" %%a in ("Montag Dienstag Mittwoch Donnerstag Freitag Samstag Sonntag") do set _Wochentag=%%a
::Wochentag ausgeben
echo Der gesuchte Wochentag ist ein: %_Wochentag%
goto :EOF ::Springe an das Ende der Datei, also verlasse die Batch (weil fertig)
:DateToDOW %yy% %mm% %dd% dow
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: By: Ritchie Lawrence, 2003-04-29. Version 1.1
:: Func: Creates a day of week number from a calendar date, where 1 = Mon
:: and 7 = Sun. For NT4/2000/XP/2003.
:: Args: %1 year component to be converted, 2 or 4 digits (by val)
:: %2 month component to be converted, leading zero ok (by val)
:: %3 day of month to be converted, leading zero ok (by val)
:: %4 var to receive day of week number, 1 to 7 (by ref)
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
set yy=%1&set mm=%2&set dd=%3
if 1%yy% LSS 200 if 1%yy% LSS 170 (set yy=20%yy%) else (set yy=19%yy%)
set /a dd=100%dd%%%100,mm=100%mm%%%100
set /a z=14-mm,z/=12,y=yy+4800-z,m=mm+12*z-3,dow=153*m+2
set /a dow=dow/5+dd+y*365+y/4-y/100+y/400-2472630,dow%%=7,dow+=1
set %4=%dow%
exit /b 0
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
c:\>MyBatch.cmd 05.05.2005
-------------------------------
Ausgabe: "Der gesuchte Wochentag ist ein: Donnerstag"
Stichproben zufolge scheint Ritchie Lawrences Funktion irgendwie zu funktionieren. Nur wie?
Die Beantwortung der Frage ist wichtig, um zu erkennen, wo die Grenzen der Funktion liegen und ob sie womöglich Fehler enthält. Zudem möchte zuminest ich keinen Quellcode verwenden, von dem ich nicht weiß, was er tut. Also dann:
Die erste Codezeile...
set yy=%1&set mm=%2&set dd=%3
...füttert die Variablen yy (Jahr), mm (Monat) und dd (Tag) mit den Werten der entsprechenden Parameter.
Dann geht es zur nächsten Codezeile:
if 1%yy% LSS 200 if 1%yy% LSS 170 (set yy=20%yy%) else (set yy=19%yy%)
Wurde das Jahr nur zweistellig (xx) angegeben (if 1xx kleiner als 2xx, was bei einer vierstelligen Zahl, also 1xxxx, nicht erfüllt sein würde), dann macht die Funktion daraus eine vierstellige Zahl. Dabei wird hier die Grenze auf 1970 gesetzt. Gibt jemand also 11 an, dann wird wohl, davon geht die Funktion aus, 2011 gemeint sein. Gibt jemand 70 (oder höher) ein, dann wird wohl 1970 gemeint sein, so die Funktion:
Mache aus x.x.00 bis x.x.69 ein x.x.2000 bis x.x.2069; mache aus x.x.70 bis x.x.99 ein x.x.1970 bis x.x.1999.
Hier haben wir eine mögliche Fehlerquelle: Was passiert wohl wenn jemand die führende Null wegläßt?: Statt 2001 wird daraus 201. Betrachtet von dem Standpunkt, das dies kein gültiges Datumsformat wäre, ist das allerdings ein Fehler des Anwenders, nicht der Funktion.
Jetzt geht es in die nächste Codezeile
set /a dd=100%dd%%%100,mm=100%mm%%%100
Er macht beispielsweise aus den Tag "05" die Zahl 10005 und teilt dies dann durch 100. Er verwendet eine besondere Art der Division (% und nicht /), die den Restwert zurück gibt. Eine Restwert-Division xyz % 10 (auch xyz mod 10) liefert z zurück. Eine Restwert-Division xyz % 100 liefert yz zurück (also die letzten beiden Stellen der Zahl). Anmerkung zur in der Funktion verwendeten Schreibweise: Da es sich bei dem %-Zeichen um ein Sonderzeichen handelt, musste dieses Zeichen durch die doppelte Schreibweise entwertet werden (also %% statt %). Also: Er macht aus 05 eine 10005 und will davon die letzten beiden Ziffern haben: 05. In dieser Zeile macht er eigentlich gar nichts, ausser den Effekt zu nutzen, dass set /a die führenden Nullen eliminiert.
set /a dd"=dd", mm"=mm"
hätte denselben Effekt (und wäre verständlicher).
Jetzt nehmen wir uns den ersten Teil seiner nächsten Codezeile vor:
set /a
z=14-mm,z/=12
,y=yy+4800-z,m=mm+12*z-3,dow=153*m+2Das ist nichts weiter als eine mathematische Klausel für
Wenn mm kleiner oder gleich 2, dann z=1, sonst z=0
Wenn uns der Autor so etwas gänzlich einfaches sagen möchte, warum schreibt er es nicht auch so hin?:
if mm LEQ 2 ( set "z=1" ) else ( set "z=0" )
Weiter geht's mit dem Rest der zuvor schon betrachteten Codezeile, die im Zusammenhang mit Teilen der darauf folgenden Codezeile betrachtet werden muss
set /a z=14-mm,z/=12,y=yy+4800-z,
m=mm+12*z-3,dow=153*m+2
set /a
dow=dow/5+dd
+y*365+y/4-y/100+y/400-2472630,dow%%=7,dow+=1Klarer Fall von selbsterklärendem Code. Kommentare im Quelltext werden sowas von überbewertet...
Der Quellcode hat zwar das Potential, als abschreckendes Beispiel in Lehrbücher aufgenommen zu werden, aber Ritchie Lawrences Idee, wie er den Wochentag mit einfachen Batch-Mitteln berechnet, ist echt pfiffig: Er arbeitet offensichtlich mit einem März-bis-Februar-Jahresmodel. Darauf muss man erst einmal kommen. Mit
set /a m=mm + 12*z - 3
baut der Autor einen Montasfaktor auf. Da z nur im Jan oder Feb == 1 ist, sonst 0, fällt die Rechnung 12*z für alle anderen Monate weg (sie kürzt sich aus der Rechnung heraus). Das läuft auf das Folgende hinaus:set m im März=0 (=Jahresbeginn), Apr=1, Mai=2 … Dez=9, Jan=10, Feb=11 (Jahresende)
Dazu passt die Anweisung
set /a dow=(153*m +2)/5
. Er muss ja, um den Wochentag zu berechnen, später auf ein bestimmtes Datum zurückgehen, bei dem ihm der Wochentag bekannt ist. Dann braucht er nur noch die Tage von diesem Datum an bis zum gesuchten Zeitpunkt berechen und durch die Wochentage teilen (aber dazu später mehr). Um die verstrichenen Tage zu ermitteln, betrachtet er zunächst das aktuelle Jahr des angegebenen Datums. Das besteht aus vergangenen Monaten (mm) und Monats-Tagen (dd). Hier wendet er sich dem ersten Teil zu und stellt die Frage, wie viele Tage in dem Jahr bereits verstrichen sind, wenn beispielsweise der Monat April angegeben wurde. Die Antwort liefert ihm die obige Formel (set /a dow=(153*m +2)/5), die im Klartext bedeutet:set dow im Mär=0, Apr=31, Mai=61, Jun=92, Jul=122, Aug=153, Sep=184, Okt=214, Nov=245, Dez=275, Jan=306, Feb=337
Das nenne ich eine pfiffige Lösung eines nicht trivialen Problems. Hut ab. Warum ist seine Grundidee mit dem März-bis-Februar-Jahresmodel so gut? Das Jahr beginnt in diesem Modell nicht im Januar, sondern im März. Alle Monate haben dann hintereinander weg mal 31 bzw. 30 Tage, wobei nur noch die Sonderstellung Jul/Aug und Dez/Jan mit zweimal hintereinander 31 Tagen beachtet werden muss, was seine mathematische Formel von oben vortrefflich löst. Der schwierige Monat Feb gelangt so an die letzte Stelle mit seinen 28 bzw. 29 Tagen, steht also nicht mehr mittendrin. Es braucht in diesem Fall nicht mehr beachtet zu werden, ob das aktuelle Jahr womöglich ein Schaltjahr ist. Diese Frage wird bereits durch die Angabe des Tages (dd) gelöst, genau dann nämlich, wenn man im Monat Feb des gesuchten Datums den 29. Tag angibt, was in diesem Fall der letzte Tag im Jahr wäre. Anders formuliert: Die Frage nach den verstrichenen Tagen innerhalb des gesuchten Jahres ist jetzt mit dow+dd gelöst (
set /a dow=dow + dd
).Aus den Codezeilen eins drüber bleibt noch die Berechnung der verstrichenen Tage aus der angegebenen Jahreszahl übrig. Also die Differenz in Tagen hin zu einem Datum, bei dem uns (oder vielmehr dem Autor) der Wochentag bekannt ist. Aus dieser Differenz + der verstrichenen Tage innerhalb des gesuchten Jahres ließe sich der gesuchte Wochentag berechnen. Wir müssen uns jetzt also der folgenden Berechnung zuwenden:
set /a
y=yy+4800-z
,m=mm+12*z-3,dow=153*m+2set /a dow=dow/5+dd+
y*365+y/4-y/100+y/400
-2472630,dow%%=7,dow+=1y=yy-z
ist klar, denn z ist im Jan/Feb == 1, sonst 0, und in dem zugrunde liegenden März-bis-Februar-Jahresmodel liegen diese beiden Monate nicht am Jahresanfang sondern am Ende des vergangenen Jahres (hier muss also die Jahreszahl um 1 reduziert werden). Aber: Warum nur schickt er uns 4800 Jahre in die Vergangenheit? Soll heißen: In seiner Berechnung sind 4800 Jahre mehr vergangen, als wir im Datum angegeben haben. *grübel*Na gut, schauen wir uns mal an, was der Code da macht:
set /a y"+=4800"
- Das rechnerische Jahr 0000 beginnt in diesem Modell also nicht am 1. Januar des Jahres 0000, sondern am 1. März im Jahre -4800. Nun gilt es die verstrichenen Tage bis zum angegebenen Jahr zu berechnen (inklusive der Schaltjahresberechnung, da pro Schaltjahr ein Tag hinzukommt): dow=dow + y+365
/*klar, das Jahr hat 365 Tage*/ + y/4
/*durch vier teilbare Jahre sind Schaltjahre*/ - y/100
/*Jahrhunderjahre wieder abziehen, da sie nicht zwangsläufig Schaltjahre sind*/ + y/400
/*nur Jahrhundertjahre die durch 400 teilbar sind, sind Schaltjahre*/.Die Variable dow enthält jetzt alle Tage seit dem 1. März im Jahre -4800. Nun verlegt der Autor den Tag 1 auf den 1. März im Jahre -4800 + 2.472.630 Tage. So kommt er auf ein Datum, wo ihm der Wochentag bekannt ist:
set /a dow=dow/5+dd +y*365+y/4-y/100+y/400
-2472630
,dow%%=7,dow+=1Damit wir das später (möglicherweise) herausrechnen können, rechne ich erst einmal, was uns die zusätzlichen 4800 Jahre an Tage eingebrockt haben: 4800 * 365=1.752.000 Tage, + 1.164 Schalttage=1.753.164 Tage gesamt, die durch das obige "y+=4800" hinzugekommen sind. Nun ziehe ich diese von der magischen Nummer des Autors ab: 2.472.630 - 1.753.164=719.466 Tage ab dem rechnerischen 01. März 0000. Dann verbleiben 1969 Jahre (=719.162 Tage inkl. Schalttage) und 304 Tage. Das sind 275 Tage bis Dez 1969 im März-bis-Feb-Jahresmodell, Rest 29 Tage.
Das gesuchte Datum, auf das diese magische Zahl zurückrechnet, ist der 29.12.1969, ein Montag (vermutlich der Geburtstag des Autors?)
Das weist auf eine Schwachstelle des Codes hin, auf die ich später zu sprechen kommen werde. Zunächst einmal sehen wir uns an, wie dieser Code daraus den gesuchten Wochentag des angegebenen Datums errechnet:
set /a dow=dow/5+dd+y*365+y/4 -y/100+y/400-2472630,
dow%%=7,dow+=1
Die Tage vom 29.12.1969 bis zum angegebenen Datum geteilt durch 7 ergibt einen Rest, deren erste Stelle hinter dem Komma 0=Mo, 1=Di bis 6=So lautet. Diese Restwert-Division (mathematisch dow=dow mod 7; das entspricht dow%%=7, was im Klartext dow=dow %% 7 bedeutet) wird für die Berechnung des gesuchten Wochentages verwendet. Damit das Ergebnis nicht 0 bis 6 lautet, wird das Ergebnis noch um eins erhöht. Fertig.
Da wir nun das magische Ursprungsdatum kennen: Was passiert wohl, wenn wir mit seiner Funktion den Wochentag vom 28.12.1969 oder früher erfragen?
Bevor ich auf Ritchie Lawrences Code weiter eingehe, versuche ich zunächst einmal meine Theorien mit Hilfe einiger quick-and-dirty-Hacks zu überprüfen:
@echo off & setlocal EnableExtensions
call :FncPartDate -f DD/MM/YY -0 _Year _Month _Day %1 &::Das übergebene Datum in seine Bestandteile zerlegen
echo ------------------------------------------------------------------------------
echo # Wochentagsberechnung stur nach dem Gregorianischen Kalendersystem: #
echo ------------------------------------------------------------------------------
set /a _WDNr=0
call :DateToDOW %_Year% %_Month% %_Day% _WDNr
call :FncWeekdayNrToName %_WDNr% _WDName
echo Der gesuchte Wochentag ist ein: %_WDName% ^(laut DateToDOW^)
set /a _WDNr=0
call :FncDateToWeekdayNr_Hack_00 %_Year% %_Month% %_Day% _WDNr
call :FncWeekdayNrToName %_WDNr% _WDName
echo Der gesuchte Wochentag ist ein: %_WDName% ^(laut FncDateToWeekdayNr_Hack_00^)
set /a _WDNr=0
call :FncDateToWeekdayNr_Hack_01 %_Year% %_Month% %_Day% _WDNr
call :FncWeekdayNrToName %_WDNr% _WDName
echo Der gesuchte Wochentag ist ein: %_WDName% ^(laut FncDateToWeekdayNr_Hack_01^)
set /a _WDNr=0
call :FncDateToWeekdayNr_Hack_10 %_Year% %_Month% %_Day% _WDNr
call :FncWeekdayNrToName %_WDNr% _WDName
echo Der gesuchte Wochentag ist ein: %_WDName% ^(laut FncDateToWeekdayNr_Hack_10^)
set /a _WDNr=0
call :FncDateToWeekdayNr_Hack_11 %_Year% %_Month% %_Day% _WDNr
call :FncWeekdayNrToName %_WDNr% _WDName
echo Der gesuchte Wochentag ist ein: %_WDName% ^(laut FncDateToWeekdayNr_Hack_11^)
echo.
echo ------------------------------------------------------------------------------
echo # Berechnung des Julianischen Tages stur nach dem Gregorian. Kalendersystem: #
echo ------------------------------------------------------------------------------
set /a _JDay=0
call :FncDateToJulianDay_Hack_00 %_Year% %_Month% %_Day% _JDay
echo Umrechnung Datum nach JulianDay: %_JDay% ^(laut FncDateToJulianDay_Hack_00^)
set /a _JDay=0
call :FncDateToJulianDay_Hack_01 %_Year% %_Month% %_Day% _JDay
echo Umrechnung Datum nach JulianDay: %_JDay% ^(laut FncDateToJulianDay_Hack_01^)
set /a _JDay=0
call :FncDateToJulianDay_Hack_10 %_Year% %_Month% %_Day% _JDay
echo Umrechnung Datum nach JulianDay: %_JDay% ^(laut FncDateToJulianDay_Hack_10^)
echo.
set /a _WDNr=0
call :FncJulianDayToWeekdayNr %_JDay% _WDNr
call :FncWeekdayNrToName %_WDNr% _WDName
echo Berechneter Wochentag aus JulianDay %_JDay%: %_WDName%
echo.
echo ------------------------------------------------------------------------------
echo # Julian Day bis 04.10.1582 nach dem Julianischen, dann Gregorian. Kalender: #
echo ------------------------------------------------------------------------------
set /a _JDay=0
call :FncDateToJulianDay_Hack_11 %_Year% %_Month% %_Day% _JDay
echo.
echo Umrechnung Datum nach JulianDay: %_JDay% ^(laut FncDateToJulianDay_Hack_11^)
echo.
set /a _WDNr=0
call :FncJulianDayToWeekdayNr %_JDay% _WDNr
call :FncWeekdayNrToName %_WDNr% _WDName
echo Berechneter Wochentag aus JulianDay %_JDay%: %_WDName%
goto :EOF ::Springe an das Ende der Datei, also verlasse die Batch (weil fertig)
:FncPartDate {{comment_single_line_remark:2}}
::Options: -f DD/MM/YY or YY/MM/DD or MM/DD/YY /*Input-Date-Format by YY=Year, MM=Month, DD=Day*/
:: -yy <SplitYear> /*if e.g. SplitYaer==70 then double-digit-year form 00 to 69 make to 20xx, else 19xx*/
:: -0 /* remove leading zeros by returns; on this option the 0xxxx-year can have no more than 5 digits */
::Parameters: <VarReturnsYear> <VarReturnsMonth> <VarReturnsDay> [date or nothing for current date]
::Example: call :FncPartDate -f DD/MM/YY -yy 70 -0 _Year _Month _Day "05.05.55" /*returns _Year=2055, _Day=5 */
:: call :FncPartDate -f DD/MM/YY _Year _Month _Day "05.05.55" /*returns _Year=55, _Day=05*/
:: call :FncPartDate -f YY/MM/DD -yy 70 _Year _Month _Day "84.05.05" /*returns _Year=1984, _Day=05*/
:: call :FncPartDate -f YY/MM/DD -0 _Year _Month _Day "84.05.05" /*returns _Year=84, _Day=5 */
::###################################################################################################################
setlocal EnableDelayedExpansion
if "%~1" == "-f" ( set _#2=%~2 &set "_F1=_!_#2:~0,2!" &set "_F2=_!_#2:~3,2!" &set "_F3=_!_#2:~6,2!" &shift &shift
) else ( set "_F1=_DD" &set "_F2=_MM" &set "_F3=_YY" )
if "%~1" == "-yy" ( set "_SpYY=%~2" &shift &shift ) else ( set "_SpYY=" )
if "%~1" == "-0" ( set "_RLZ=on" &shift ) else ( set "_RLZ=" )
if "%~4" == "" ( set "_MyDate=%DATE:* =%" ) else ( set "_MyDate=%~4" )
for /f "tokens=1-3 delims=./ " %%a in ("%_MyDate%") do set "%_F1%=%%a" & set "%_F2%=%%b" & set "%_F3%=%%c"
if "%_YY:~0,1%" == "-" (set "_YY=%_YY:~1,100%" &set "_NS=-") else (set "_NS=") &::Vorzeichen entfernen
if defined _RLZ ( ::führende Nullen entfernen
if "%_YY:~0,1%" == "0" set /a _YY"=(100000%_YY%)%%100000"
if "%_MM:~0,1%" == "0" set /a _MM"=(100000%_MM%)%%100000"
if "%_DD:~0,1%" == "0" set /a _DD"=(100000%_DD%)%%100000"
)
set "_YY=%_NS%%_YY%" &::Vorzeichen wieder einfügen
if not defined _NS if defined _SpYY if %_YY% LSS 100 if 1%_YY% LSS 1%_SpYY% (set _YY=20%_YY%) else (set _YY=19%_YY%)
endlocal & set "%~1=%_YY%" & set "%~2=%_MM%" & set "%~3=%_DD%"
exit /b 0
:FncWeekdayNrToName {{comment_single_line_remark:15}}
::Options: -s "Monday Tuesday Wednesday Thursday Friday Saturday Sunday unknown" /*use my own weekdayname-string*/
::Parameters: <weekday-number form 1(=Monday) to 7(=Sunday)> <VarReturnsWeekdayName>
::Example: call :FncWeekdayNrToName -s "Mo Tu We Th Fr Sa Su unknown" 5 _Name /*returns _Name="Fr" */
:: call :FncWeekdayNrToName 5 _Name /*returns _Name="Freitag"*/
::###################################################################################################################
setlocal EnableDelayedExpansion
if "%~1" == "-s" ( set "_WNS=%~2" &shift &shift
) else ( set "_WNS=Montag Dienstag Mittwoch Donnerstag Freitag Samstag Sonntag unbekannt" )
set /a _WeekdayNumber"=%~1"
if %_WeekdayNumber% LSS 1 set /a _WeekdayNumber"=8"
if %_WeekdayNumber% GTR 7 set /a _WeekdayNumber"=8"
for /f "tokens=%_WeekdayNumber%" %%a in ("%_WNS%") do set _WeekdayName=%%a
endlocal & set "%~2=%_WeekdayName%"
exit /b 0
:FncDateToWeekdayNr_Hack_00 {{comment_single_line_remark:21}}
::Parameters: <Year> <Month> <Day> <VarNameToReturnWeekdayNr>
::Note: The date less than 01/01/1970 is invalid
::Example: call :FncDateToWeekdayNr 5555 05 05 _DayOfWeekNr
::#################### Berechnung des Wochentages vom dd.mm des Jahres 1970 bis 5881579 #######################
::Nicht fuer den produktiven Einsatz gedacht und geeignet; nur zum Testen.
::Algorithmus frei nach http://www.commandline.co.uk/lib/treeview/index.php, Autor: Ritchie Lawrence
set _MyYear=%1&set _MyMonth=%2&set _MyDay=%3
if %_MyYear% LSS 1970 exit /b 1 &::Berechnung nur bis 29.12.1969 möglich
::Mit den vorhandenen Daten frei nach dem Algorithmus von Ritchie Lawrence den Wochentag berechnen:
if %_MyMonth% LEQ 2 ( set _bJanOrFeb=1 ) else ( set _bJanOrFeb=0 ) &::Jan or Feb = 1, sonst 0
set /a _MonthsFactor"=(12*_bJanOrFeb)+(_MyMonth-3)" &::im Mär=0, Apr=1 ... Feb=11
set /a _ElapsedDaysUntilMyMonths"=(153*_MonthsFactor+2)/5" &::im Mär=0, Apr=31 ... Feb=337
set /a _ElapsedDaysOfMyYear"=_ElapsedDaysUntilMyMonths+_MyDay" &::+ verstrichene Tage des akt. Monats
set /a _MyYear"-=_bJanOrFeb" &::Jan und Feb liegen hier im verg. Jahr
set /a _ElapsedDaysUntilMyYear"=_MyYear*365 + (_MyYear/4 - _MyYear/100 + _MyYear/400)"
set /a _Weekday"=(_ElapsedDaysUntilMyYear+_ElapsedDaysOfMyYear - 719466)%%7 + 1"
set %4=%_Weekday%
exit /b 0
:FncDateToWeekdayNr_Hack_01 {{comment_single_line_remark:35}}
::Parameters: <Year> <Month> <Day> <VarNameToReturnWeekdayNr>
::Example: call :FncDateToWeekdayNr 5555 05 05 _DayOfWeekNr
::################ Berechnung des Wochentages vom dd.mm des Jahres -2147483648 bis 5879609 ####################
::Nicht fuer den produktiven Einsatz gedacht und geeignet; nur zum Testen.
set _MyYear=%1&set _MyMonth=%2&set _MyDay=%3
if %_MyYear% EQU 0 ( ::Jahr 0000 wurde angegeben; ungültige Jahreszahl...
echo FncDateToWeekdayNr_Hack01: Error^^!
echo On 31.12.0001 before Christ ^(BC^) immediately follows the 01.01.0001 AD ^(CE^).
echo The year 0000 does not exist. Use -0001 do you mean the year 1 before Christ.
exit /b 1
) 1>&2
if %_MyYear% LSS 0 set /a _MyYear"+=1" &::Das Jahr -1 liegt rechnerisch im Jahr 0, -2 im Jahr -1, etc.
:FncDateToWeekdayNr_Hack01_YearLoop &::negative Jahreszahl in eine gültige positive Zahl umwandeln...
if %_MyYear% LSS 1 set /a _MyYear"+=4000000" &::...alle 400 J. wiederh. sich die WoTage (*10000 ist schneller)
if %_MyYear% LSS 1 goto :FncDateToWeekdayNr_Hack01_YearLoop &::LSS 1 (statt 0) weil Jahr im JanOrFeb sonst -1
::Im Folgenden gilt es die bereits verstrichenen Tage des Jahres im März-bis-Februar-Jahresmodell zu berechnen.
if %_MyMonth% LEQ 2 ( set _bJanOrFeb=1 ) else ( set _bJanOrFeb=0 ) &::Jan or Feb = 1, sonst 0
::Algorithmus frei nach http://www.commandline.co.uk/lib/treeview/index.php, Autor: Ritchie Lawrence
set /a _MonthsFactor"=(12*_bJanOrFeb)+(_MyMonth-3)" &::im Mär=0, Apr=1 ... Feb=11
set /a _ElapsedDaysUntilMyMonths"=(153*_MonthsFactor+2)/5" &::im Mär=0, Apr=31 ... Feb=337
set /a _ElapsedDaysOfMyYear"=_ElapsedDaysUntilMyMonths+_MyDay" &::+ verstrichene Tage des akt. Monats
::Nun gilt es die Tage der vergangenen Jahre bis zum rechnerischen Jahr 0000 zurückzuberechenen.
set /a _MyYear"-=_bJanOrFeb" &::Jan und Feb liegen hier im verg. Jahr
set /a _ElapsedDaysUntilMyYear"=_MyYear*365 + (_MyYear/4 - _MyYear/100 + _MyYear/400)"
::Wochentag=(verstrichene Tage + 1 Tag /*damit der Ursprungstag der Berechnung ein Montag ist*/) mod 7 + 1
set /a _Weekday"=(_ElapsedDaysUntilMyYear+_ElapsedDaysOfMyYear + 1)%%7 + 1"
set %4=%_Weekday%
exit /b 0
:FncDateToWeekdayNr_Hack_10 {{comment_single_line_remark:54}}
::Parameters: <Year> <Month> <Day> <VarNameToReturnWeekdayNr>
::Example: call :FncDateToWeekdayNr 5555 05 05 _DayOfWeekNr
::############## Berechnung des Wochentages vom dd.mm des Jahres -2147483648 bis 2147483641 ###################
::Nicht fuer den produktiven Einsatz gedacht und geeignet; nur zum Testen.
::Algorithmus frei nach http://de.wikipedia.org/w/index.php?title=Wochentagsberechnung&oldid=75828222
set _MyYear=%1&set _MyMonth=%2&set _MyDay=%3
if %_MyYear% EQU 0 ( ::Jahr 0000 wurde angegeben; ungültige Jahreszahl...
echo FncDateToWeekdayNr_Hack10: Error^^!
echo On 31.12.0001 before Christ ^(BC^) immediately follows the 01.01.0001 AD ^(CE^).
echo The year 0000 does not exist. Use -0001 do you mean the year 1 before Christ.
exit /b 1
) 1>&2
if %_MyYear% LSS 0 set /a _MyYear"+=1" &::Das Jahr -1 liegt rechnerisch im Jahr 0, -2 im Jahr -1, etc.
:FncDateToWeekdayNr_Hack10_YearLoop &::negative Jahreszahl in eine gültige positive Zahl umwandeln...
if %_MyYear% LSS 1 set /a _MyYear"+=4000000" &::...alle 400 J. wiederh. sich die WoTage (*10000 ist schneller)
if %_MyYear% LSS 1 goto :FncDateToWeekdayNr_Hack10_YearLoop &::LSS 1 (statt 0) weil Jahr im JanOrFeb sonst -1
set /a _MyDayID"=_MyDay%%7" &::Tageskennziffer ermitteln
for /f "tokens=%_MyMonth%" %%a in ("0 3 3 6 1 4 6 2 5 0 3 5") do set _MyMonthID=%%a
if %_MyMonth% LEQ 2 ( set _bJanOrFeb=1 ) else ( set _bJanOrFeb=0 )
set /a _MyYear"-=_bJanOrFeb" &::Im Jan or Feb Schaltjahr nur bis zum verganenen Jahr berechnen
set /a _MyLeapYearID"=(_MyYear/4 - _MyYear/100 + _MyYear/400)%%7" &::Schaltjahreskennziffer ermitteln
set /a _Weekday"=(_MyDayID + _MyMonthID + _MyYear+_bJanOrFeb + _MyLeapYearID -2)%%7 + 1" &::Wochentag berechnen
set %4=%_Weekday%
exit /b 0
:FncDateToWeekdayNr_Hack_11 {{comment_single_line_remark:69}}
::Parameters: <Year> <Month> <Day> <VarNameToReturnWeekdayNr>
::Example: call :FncDateToWeekdayNr 5555 05 05 _DayOfWeekNr
::############## Berechnung des Wochentages vom dd.mm des Jahres -2147483648 bis 1728356768 ###################
::Nicht fuer den produktiven Einsatz gedacht und geeignet; nur zum Testen.
set _MyYear=%1&set _MyMonth=%2&set _MyDay=%3
if %_MyYear% EQU 0 ( ::Jahr 0000 wurde angegeben; ungültige Jahreszahl...
echo FncDateToWeekdayNr_Hack10: Error^^!
echo On 31.12.0001 before Christ ^(BC^) immediately follows the 01.01.0001 AD ^(CE^).
echo The year 0000 does not exist. Use -0001 do you mean the year 1 before Christ.
exit /b 1
) 1>&2
if %_MyYear% LSS 0 set /a _MyYear"+=1" &::Das Jahr -1 liegt rechnerisch im Jahr 0, -2 im Jahr -1, etc.
:FncDateToWeekdayNr_Hack11_YearLoop &::negative Jahreszahl in eine gültige positive Zahl umwandeln...
if %_MyYear% LSS 1 set /a _MyYear"+=4000000" &::...alle 400 J. wiederh. sich die WoTage (*10000 ist schneller)
if %_MyYear% LSS 1 goto :FncDateToWeekdayNr_Hack11_YearLoop &::LSS 1 (statt 0) weil Jahr im JanOrFeb sonst -1
::Verstrichene Monatstage des Jahres mit einem Algorithmus eines März-bis-Februar-Jahresmodells berechnen...
if %_MyMonth% LEQ 2 ( set _bJanOrFeb=1 ) else ( set _bJanOrFeb=0 ) &::Jan or Feb = 1, sonst 0
::Algorithmus frei nach http://www.commandline.co.uk/lib/treeview/index.php, Autor: Ritchie Lawrence
set /a _MonthsFactor"=(12*_bJanOrFeb)+(_MyMonth-3)" &::im Mär=0, Apr=1 ... Jan=10, Feb=11
set /a _ElapsedDaysUntilMyMonths"=(153*_MonthsFactor+2)/5" &::im Mär=0, Apr=31 ... Jan=306, Feb=337
set /a _ElapsedDaysUntilMyMonths"+=59 - 365*_bJanOrFeb" &::zurückrechnen in das gängige Jahresmodell
:: ab März+=59, die Tage Jan+Feb<--' '-->nur im Jan or Feb: - (59 + 306_MärzBisJanTage_des_März-bis-Feb-Modells)
set /a _MyYear"-=_bJanOrFeb" &::im Jan/Feb Schaltjahr nur bis Jahr-1 berechnen
set /a _MyLeapYears"=(_MyYear/4 - _MyYear/100 + _MyYear/400)" &::Schaltjahre ermitteln
::Das rechnerische Jahr 0 beginnt an einem Samstag. Jedes darauf folgende Jahr erhöht den Tag des Jahresbeginns
::um 1 Tag. Jedes Schaltjahr erhöht ihn um 1 weiteren Tag. Daher: (Tage+Monatstage + Jahre + Schaltjahre) mod 7
::ergibt 0=Sa, 1=So, 2=Mo, etc. Dank -2 steht die 0 für Mo, 1=Di, etc. +1 macht aus 0bis6 ein 1bis7. Fertig.
set /a _Weekday"=(_MyDay+_ElapsedDaysUntilMyMonths + _MyYear+_bJanOrFeb + _MyLeapYears -2)%%7 + 1"
set %4=%_Weekday%
exit /b 0
:FncJulianDayToWeekdayNr
::Parameters: <JulianDayNr> <VarNameToReturnWeekdayNr>
::#############################################################################################################
setlocal EnableDelayedExpansion
set _JD=%~1
set /a _WDNr"=_JD%%7+1"
if %_WDNr% LSS 1 set /a _WDNr"+=7" &::für Tage vor dem ersten JulianDay
endlocal & set "%~2=%_WDNr%"
exit /b 0
:FncDateToJulianDay_Hack_00 {{comment_single_line_remark:94}}
::Parameters: <Year> <Month> <Day> <VarNameToReturnJulianDayNr>
::Example: call :FncDateToJulianDay 5555 05 05 _JulianDay
::#############################################################################################################
::Nicht fuer den produktiven Einsatz gedacht und geeignet; nur zum Testen.
::Algorithmus frei nach http://docs.kde.org/stable/de/kdeedu/kstars/ai-julianday.html; hier umgesetzt auf batch
set _MyYear=%1&set _MyMonth=%2&set _MyDay=%3
if %_MyYear% EQU 0 ( ::Jahr 0000 wurde angegeben; ungültige Jahreszahl...
echo FncDateToJulianDay_Hack00: Error^^!
echo On 31.12.0001 before Christ ^(BC^) immediately follows the 01.01.0001 AD ^(CE^).
echo The year 0000 does not exist. Use -0001 do you mean the year 1 before Christ.
exit /b 1
) 1>&2
if %_MyYear% LSS 0 set /a _MyYear"+=1" &::Das Jahr -1 liegt rechnerisch im Jahr 0, -2 im Jahr -1, etc.
::das Datum auf den Julianischen Tag umrechnen:
set /a _JD"=_MyDay-32075 + 1461*(_MyYear+4800 + (_MyMonth-14)/12)/4"
set /a _JD"+=367*(_MyMonth-2 - (_MyMonth-14)/12*12)/12"
set /a _JD"-=3*((_MyYear + 4900 + (_MyMonth - 14)/12)/100)/4"
set /a %~4"=%_JD%" &::Hinweis: JulianDay 0 == 1. Jan. 4713 v.u.Z. julianisch == 24. Nov. 4714 v.u.Z. greogorianisch
exit /b 0
:FncDateToJulianDay_Hack_01 {{comment_single_line_remark:94}}
::Parameters: <Year> <Month> <Day> <VarNameToReturnJulianDayNr>
::Example: call :FncDateToJulianDay 5555 05 05 _JulianDay
::#############################################################################################################
::Nicht fuer den produktiven Einsatz gedacht und geeignet; nur zum Testen.
::Algorithmus frei nach http://www.commandline.co.uk/lib/treeview/index.php, Autor: Ritchie Lawrence
set _MyYear=%1&set _MyMonth=%2&set _MyDay=%3
if %_MyYear% EQU 0 ( ::Jahr 0000 wurde angegeben; ungültige Jahreszahl...
echo FncDateToJulianDay_Hack01: Error^^!
echo On 31.12.0001 before Christ ^(BC^) immediately follows the 01.01.0001 AD ^(CE^).
echo The year 0000 does not exist. Use -0001 do you mean the year 1 before Christ.
exit /b 1
) 1>&2
if %_MyYear% LSS 0 set /a _MyYear"+=1" &::Das Jahr -1 liegt rechnerisch im Jahr 0, -2 im Jahr -1, etc.
::Im Folgenden gilt es die bereits verstrichenen Tage des Jahres im März-bis-Februar-Jahresmodell zu berechnen.
if %_MyMonth% LEQ 2 ( set _bJanOrFeb=1 ) else ( set _bJanOrFeb=0 ) &::Jan or Feb = 1, sonst 0
set /a _MonthsFactor"=(12*_bJanOrFeb)+(_MyMonth-3)" &::im Mär=0, Apr=1 ... Feb=11
set /a _ElapsedDaysUntilMyMonths"=(153*_MonthsFactor+2)/5" &::im Mär=0, Apr=31 ... Feb=337
set /a _ElapsedDaysOfMyYear"=_ElapsedDaysUntilMyMonths+_MyDay" &::+ verstrichene Tage des akt. Monats
::Nun gilt es die Tage der vergangenen Jahre bis zum Jahr 0000 zurückzuberechenen.
set /a _MyYear"-=_bJanOrFeb" &::Jan und Feb liegen hier im verg. Jahr
if %_MyYear% LSS 0 set /a _ElapsedDaysOfMyYear"-=1"
set /a _ElapsedDaysUntilMyYear"=_MyYear*365 + (_MyYear/4 - _MyYear/100 + _MyYear/400)"
set /a _JD"=(_ElapsedDaysUntilMyYear+_ElapsedDaysOfMyYear+1721119)" &::+Tage vom 01. März 0000 bis JulianDay 0
set /a %~4"=%_JD%" &::Hinweis: JulianDay 0 == 1. Jan. 4713 v.u.Z. julianisch == 24. Nov. 4714 v.u.Z. greogorianisch
exit /b 0
:FncDateToJulianDay_Hack_10 {{comment_single_line_remark:121}}
::Parameters: <Year> <Month> <Day> <VarNameToReturnJulianDayNr>
::Example: call :FncDateToJulianDay 5555 05 05 _JulianDay
::#############################################################################################################
::Nicht fuer den produktiven Einsatz gedacht und geeignet; nur zum Testen.
::Algorithmus frei nach http://de.wikipedia.org/w/index.php?title=Julianisches_Datum&oldid=76256118#Berechnung_aus_dem_Kalenderdatum
setlocal EnableDelayedExpansion
set _MyYear=%1&set _MyMonth=%2&set _MyDay=%3
if %_MyYear% EQU 0 ( ::Jahr 0000 wurde angegeben; ungültige Jahreszahl...
echo FncDateToJulianDay_Hack01: Error^^!
echo On 31.12.0001 before Christ ^(BC^) immediately follows the 01.01.0001 AD ^(CE^).
echo The year 0000 does not exist. Use -0001 do you mean the year 1 before Christ.
exit /b 1
) 1>&2
if %_MyYear% LSS 0 set /a _MyYear"+=1" &::Das Jahr -1 liegt rechnerisch im Jahr 0, -2 im Jahr -1, etc.
if %_MyMonth% LEQ 2 ( set _bJanOrFeb=1 ) else ( set _bJanOrFeb=0 )
set /a _Y"=_MyYear-_bJanOrFeb"
set /a _M"=_MyMonth + (12*_bJanOrFeb) + 1"
set /a _JD"=365*(_Y+4716) + (_Y+4716)/4 + 30*_M + 6001*_M/10000 - 1524 + _MyDay + 2 - _Y/100 + _Y/400"
endlocal &set "%~4=%_JD%" &::Hinweis: JulianDay 0 == 1. Jan. 4713 v.u.Z. julianisch == 24. Nov. 4714 v.u.Z. greogorianisch
exit /b 0
:FncDateToJulianDay_Hack_11 {{comment_single_line_remark:130}}
::Parameters: <Year> <Month> <Day> <VarNameToReturnJulianDayNr>
::Example: call :FncDateToJulianDay 5555 05 05 _JulianDay
::#############################################################################################################
::Nicht fuer den produktiven Einsatz gedacht und geeignet; nur zum Testen.
::Algorithmus frei nach http://de.wikipedia.org/w/index.php?title=Julianisches_Datum&oldid=76256118#Berechnung_aus_dem_Kalenderdatum
setlocal EnableDelayedExpansion
set _MyYear=%1&set _MyMonth=%2&set _MyDay=%3
if %_MyYear% EQU 0 ( ::Jahr 0000 wurde angegeben; ungültige Jahreszahl...
echo FncDateToJulianDay_Hack01: Error^^!
echo On 31.12.0001 before Christ ^(BC^) immediately follows the 01.01.0001 AD ^(CE^).
echo The year 0000 does not exist. Use -0001 do you mean the year 1 before Christ.
exit /b 1
) 1>&2
if %_MyYear% LSS 0 set /a _MyYear"+=1" &::Das Jahr -1 liegt rechnerisch im Jahr 0, -2 im Jahr -1, etc.
if %_MyMonth% LEQ 2 ( set _bJanOrFeb=1 ) else ( set _bJanOrFeb=0 )
set /a _Y"=_MyYear-_bJanOrFeb"
set /a _M"=_MyMonth + (12*_bJanOrFeb) + 1"
set /a _MyCalendar"=_MyYear*100 + _MyMonth*10 + _MyDay"
set /a _GregorianCalendar"= 1582*100 + 10*10 + 15"
set /a _JulianCalendar"= 1582*100 + 10*10 + 4"
if %_MyCalendar% GEQ %_GregorianCalendar% ( ::ab 15.10.1582 Schaltjahresberechnung nach dem Gregorian. Kal.
echo Berechnung nach dem Gregorianischen Kalender...
set /a _JD"=365*(_Y+4716) + (_Y+4716)/4 + 30*_M + 6001*_M/10000 - 1524 + _MyDay + 2 - _Y/100 + _Y/400"
)
if %_MyCalendar% LSS %_GregorianCalendar% if %_MyCalendar% GTR %_JulianCalendar% (
echo FncDateToJulianDay_Hack_11: Error^^!
echo Historically the days between 05-14 in October 1582 does not exist.
exit /b 1
) 1>&2
if %_MyCalendar% LEQ %_JulianCalendar% ( ::bis 04.10.1582 Schaltjahresberechnung nach dem Julian. Kalender
echo Berechnung nach dem Julianischen Kalender...
set /a _JD"=365*(_Y+4716) + (_Y+4716)/4 + 30*_M + 6001*_M/10000 + _MyDay - 1524"
)
endlocal &set "%~4=%_JD%"
exit /b 0
:DateToDOW %yy% %mm% %dd% dow
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: By: Ritchie Lawrence, 2003-04-29. Version 1.1
:: Func: Creates a day of week number from a calendar date, where 1 = Mon
:: and 7 = Sun. For NT4/2000/XP/2003.
:: Args: %1 year component to be converted, 2 or 4 digits (by val)
:: %2 month component to be converted, leading zero ok (by val)
:: %3 day of month to be converted, leading zero ok (by val)
:: %4 var to receive day of week number, 1 to 7 (by ref)
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
set yy=%1&set mm=%2&set dd=%3
::if 1%yy% LSS 200 if 1%yy% LSS 170 (set yy=20%yy%) else (set yy=19%yy%)
set /a dd=100%dd%%%100,mm=100%mm%%%100
set /a z=14-mm,z/=12,y=yy+4800-z,m=mm+12*z-3,dow=153*m+2
set /a dow=dow/5+dd+y*365+y/4-y/100+y/400-2472630,dow%%=7,dow+=1
set %4=%dow%
exit /b 0
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
c:\>MyBatch.cmd 05.05.5555
-------------------------------
Ausgabe:
------------------------------------------------------------------------------
# Wochentagsberechnung stur nach dem Gregorianischen Kalendersystem: #
------------------------------------------------------------------------------
Der gesuchte Wochentag ist ein: Donnerstag (laut DateToDOW)
Der gesuchte Wochentag ist ein: Donnerstag (laut FncDateToWeekdayNr_Hack_00)
Der gesuchte Wochentag ist ein: Donnerstag (laut FncDateToWeekdayNr_Hack_01)
Der gesuchte Wochentag ist ein: Donnerstag (laut FncDateToWeekdayNr_Hack_10)
Der gesuchte Wochentag ist ein: Donnerstag (laut FncDateToWeekdayNr_Hack_11)
------------------------------------------------------------------------------
# Berechnung des Julianischen Tages stur nach dem Gregorian. Kalendersystem: #
------------------------------------------------------------------------------
Umrechnung Datum nach JulianDay: 3750106 (laut FncDateToJulianDay_Hack_00)
Umrechnung Datum nach JulianDay: 3750106 (laut FncDateToJulianDay_Hack_01)
Umrechnung Datum nach JulianDay: 3750106 (laut FncDateToJulianDay_Hack_10)
Berechneter Wochentag aus JulianDay 3750106: Donnerstag
------------------------------------------------------------------------------
# Julian Day bis 04.10.1582 nach dem Julianischen, dann Gregorian. Kalender: #
------------------------------------------------------------------------------
Berechnung nach dem Gregorianischen Kalender...
Umrechnung Datum nach JulianDay: 3750106 (laut FncDateToJulianDay_Hack_11)
Berechneter Wochentag aus JulianDay 3750106: Donnerstag
Damit bin ich zwar nicht mehr 100% kompatibel zur ursprünglichen Schnittstelle von Lawrences Funktion, aber in einem quick-and-dirty-Hack darf ich das.
Der Unterschied zwischen den Funktionen:
DateToDOW
- Originalalgorithmus von Ritchie Lawrence
FncDateToWeekdayNr_Hack_00
- kommt ohne den y+=4800'er Umweg aus dem Originalalgorithmus aus
FncDateToWeekdayNr_Hack_01
- kommt zudem ohne die Datumsgrenze 29.12.1969 aus; die Funktion verwendet einen anderen Ansatz bei der Rückrechnung, bei dem nun die Eigenschaft des Gregorianischem Kalenders genutzt wird, dass der 1. Januar eines jeden geraden 10-Jahrtausendjahres (x.x.2000, x.x.4000, etc.) auf einen Samstag fällt (die ungeraden fallen auf einen Mittwoch). Im Klartext: Es können Wochentage ab dem 01.01.0000 damit ermittelt werden. Aber Achtung!: Der Algorithmus rechnet stur nach unserer Zeitrechnung in die Vergangenheit und Zukunft. Historisch gesehen gilt der Gregorianische Kalender aber erst seit dem 15. Oktober 1582. Für sämtliche historische Kalendersysteme gilt zudem der Umstand, dass es kein Jahr 0000 gibt (auf den 31.12.0001 vor unserer Zeitrechnung folgt der 01.01.0001 unserer Zeitrechnung). Der verwendete Algorithmus ignoriert diese Feinheiten bewusst und liefert keine historischen Daten, sondern beantwortet die Frage, welchen Wochentag man erhält, wenn man nach unserer Zeitrechnung einfach immer weiter in die Vergangenheit rechnet. Das Ergebnis einer solchen Funktion ist für Daten vor dem 15.10.1852 also als technisches Umrechnungsergebnis zu betrachten.
- Update: Ein Teil der Feinheiten wird jetzt doch beachtet. Gibt jemand das Jahr 0 an, wird er darauf hingewiesen, dass es das Jahr 0 nicht gibt. Dafür kann der Algorithmus nun auch ein technisches Umrechnungsergebnis von den Jahren vor unserer Zeitrechnung berechnen (z.B. 05.05. -555).
- Der Wertebereich der Jahre liegt zwischen -2.147.483.648 bis 5.879.609 (bedingt durch den 32-Bit-Speicherbereich der Variablen und der Art, wie der Algorithmus ihn nutzt).
FncDateToWeekdayNr_Hack_10
- wie zuvor, jedoch mit einem gänzlich anderen Algorithmus, frei nach Wikipedia (Wochentagsberechnung), umgesetzt auf batch
- Update: Deren Schaltjahresproblem habe ich jetzt anders gelöst. Das Jahr wird nun einfach nur bis zum Vorjahr auf Schaltjahre hin untersucht, wenn der Monat==Jan or Feb ist.
- Wertebereich der Jahre: -2.147.483.648 bis 2.147.483.641
FncDateToWeekdayNr_Hack_11
- Ein eigener Weg. Die Idee ist aus den anderen Ansätzen heraus entstanden
- Wertebereich der Jahre: -2.147.483.648 bis 1.728.356.768
FncDateToJulianDay_Hack_00
- Das wird die Astronomen unter euch freuen: Eine Batch-Funktion, die das Datum umrechnet auf den fortlaufenden Julianischen Tag (auch Julianisches Datum; nicht zu verwechseln mit dem Julianischen Kalender), der sich (das passt zu unserem Projekt) leicht in den Wochentag umrechnen läßt (siehe FncJulianDayToWeekdayNr). Frei nach einem Algorithmus von kde.org, aus dem "AstroInfo Projekt", hier umgesetzt auf Batch. Die Seite weist darauf hin, dass ihre Formel nur für Daten zwischen den Jahren 1801 und 2099 funktioniert, aber ich konnte - zumindest in der Batch-Variante - keine Fehler erkennen. Bei den Stichproben lag die Funktion auch weit vor und nach dieser Zeitgrenze absolut richtig (gemessen an dem technischen Umrechnungsergebnis des Gregorianischen Kalenders; will damit nochmals unterstreichen, dass das Ergebnis vor dem 15.10.1582 historisch gesehen nicht mehr korrekt ist). Nur bei negativen Jahreswerten hat sie mitunter Probleme.
FncDateToJulianDay_Hack_01
- wie zuvor, nur mit einer abgewandelten Form des Algorithmus von Ritchie Lawrence
FncDateToJulianDay_Hack_10
- wie zuvor, nur mit einem Algorithmus der Wikipedia (Julian Day - Berechnung aus dem Kalenderdatum), umgesetzt auf batch
FncDateToJulianDay_Hack_11
- Was bedeutet das genau, wenn ich schreibe, dass die bisherigen Funktionen keine historischen Daten liefern?: Der Gregorianische Kalender hat damals eine Zeitdifferenz von 10 Tagen korrigiert (auf den 4. Oktober 1582 - julianisch, Donnerstag - folgte unmittelbar der 15. Oktober 1582 - gregorianisch, Freitag), was bedeutet, dass der 14.10.1582 gregorianisch (Do) rechnerisch auf den 04.10.1582 julianisch (Do) fällt, der 13.10 g. (Mi) fällt auf den 03.10 j. (Mi), der 12.10 g. (Di) fällt auf den 02.10 j. (Di) … der 04.10.1582 gregorianisch (Mo) fällt rechnerisch auf den 24.09.1582 julianisch (Mo)...
- Das Problem: Der 04.10.1582 gregorianisch ist ein Montag, während der 04.10.1582 julianisch ein Donnerstag ist. Die Antwort nach dem Wochentag vom historischen Datum 04.10.1582 und davor ist laut technischem Umrechnungsergebnis also falsch. Zudem ändert sich die Differenz mit den Jahren, weil die Schaltjahresberechnung im Julianischen Kalendersystem eine andere ist, als im Gregorianischen Kalendersystem. Die Differenz hat natürlich nicht nur eine Auswirkung auf den Wochentag. Der Tag 0 des Julianischen Tages zeigt nach dem gregorianischen System beispielsweise nicht auf den 1.1.4713 v.u.Z., sondern auf das technische Umrechnungsergebnis 24. Nov. 4714 v.u.Z.
- Man kann, wenn man will, ja auf diese Weise in die Vergangenheit rechnen, aber bezogen auf den Julianischen Tag ist das unüblich und das Ergebnis somit falsch. Hier ist es üblich, bis zum 04. Oktober 1582 nach dem julianischen System zu rechnen und ausgehend von diesen Daten ab dem 15. Oktober 1582 nach dem gregorianischen System fortzufahren (Schaltjahresberechnung, etc.). Die Tage 05. bis 14. Oktober 1582 existieren dort nicht. Diese Funktion hier berücksichtigt die Besonderheiten und berechnet den korrekten Julianischen Tag auch für ein Datum, dass vor dem 04. Oktober 1582 liegt.
FncJulianDayToWeekdayNr
- Umrechnungsfunktion die den Wochentag zum Julianischen Tag ausgibt, und zwar auch dann, wenn man den Julianischen Tag 0 unterschreitet (z.B. -42).
Thesen zur Jahr+=4800’er Operation:
Da Lawrence keine Quellen im Code angegeben hat, gehe ich davon aus, dass es seine Algorithmen sind. Hier stellt sich die Frage, was er mit der Jahr+=4800’er Operation bewirken wollte: Alle 400 Jahre wiederholt sich die Abfolge des Wochentags im Jahr. 400 x 12 = 4800 Monate. Doch er hat die 4800 zum Jahr dazu addiert, nicht zum Monat. Das kann also nicht der Grund seiner Handlung sein. Die 4800 kann andererseits unter bestimmten Umständen auch eine Rolle bei der Berechnung des Julianischen Datums (Julian Day) spielen. Siehe beispielsweise hier. Nur passt der Rest seiner Berechnung nicht dazu. Auch läßt sich die 4800-Berechnung problemlos aus seinem Algorithmus herauskürzen. Könnte es sein, dass er hier etwas durcheinander gebracht hat? Schwer vorstellbar; wer in der Lage ist, solche Algorithmen zu entwickeln (siehe sein Jahresmodell und die Monatstageberechung), der weiß, was er tut. Bleibt noch die Möglichkeit, dass er die 4800 hinzugezogen hat, um den Algorithmus konfuser zu gestalten und somit den Weg, wie er auf den Wochentag kommt, zu verschleiern. Das passt auch beispielsweise zur Berechnung von z und dem allgemeinen Aufbau (oder besser der irritierenden Zerstückelung) seiner Rechenwege.
Fazit zu Lawrences Algorithmus:
Quellcode ist Prosa, manchmal sogar Lyrik, die uns eine mal mehr und mal weniger spannende Geschichte erzählt. Lawrences Geschichte hätte das Zeug dazu, richtig spannend zu werden. Ein cooler Hack als einfache und elegante Lösung eines nichttrivialen Problems. Doch was macht Lawrence stattdessen? Er zerschneidet den roten Faden seiner Geschichte, wo er nur kann. Sie wird nicht nur unattraktiv zu lesen, sie enthält auch für den Anwender wichtige Grenzen, die der Autor vor ihm verschweigt; schlimmer noch setzt er alles daran, um diese Grenzen seines Codes zu verschleiern.
Einmal abgesehen davon, dass sein Quellcode an entscheidenden Stellen undokumentiert ist, wurde er so verfasst, dass zusammenhängende Operationen verstreut hinterlegt wurden. Spätestens hier fragt man sich frei nach fefe, was der Programmierer eigentlich beruflich macht. Denn selbst wenn Lawrence ein Freund von kurzem Code ist, hätte er ihn wenigstens lesbar formatieren können. Ein Beispiel soll verdeutlichen, was ich meine:
Original-Code:
set /a z=14-mm,z/=12,y=yy+4800-z,m=mm+12*z-3,dow=153*m+2
set /a dow=dow/5+dd+y*365+y/4-y/100+y/400-2472630,dow%%=7,dow+=1
Dieser Code nur anders formatiert:
set /a z=14-mm, z/=12, m"=(12*z) + (mm-3)", dow"=(153*m + 2)/5"
set /a y=yy-z + 4800, dow"=(dow + dd + y*365 + (y/4 - y/100 + y/400) -2472630)%%7 + 1"
Möglich dass er damit Coolness demonstrieren wollte, aber der Preis war hoch und das Ziel verfehlt. Denn aus solch einem Code kann niemand etwas lernen, weil ihn (das ist ja von dem Autor so beabsichtigt) schlicht niemand versteht. So gut sein Lösungsansatz auch ist (davor ziehe ich meinen Hut), der Code ist grottenschlecht. Der darin enthaltene 1969'er-Fehler rührt _vermutlich_ genau daher, dass er den Code extra unverständlich geschrieben hat. So hat er wohl in der Version 1.1 (?) unter den Argumenten der Funktion angegeben, dass man das Jahr nicht mehr nur zweistellig sondern nun auch vierstellig übergeben kann. Hier wirkt seine 1970’er Grenze der zweistelligen Jahreszahl nicht mehr. Vermutlich hat er es nicht mehr gewusst und seinen Code nach kurzer Zeit auch selbst nicht mehr verstanden, so dass diese Grenze von ihm übersehen wurde (die alternative Vorstellung, dass dies schon seit Version 1.0 so gewesen könnte, ist schlimmer).
Es gibt Wettbewerbe für möglichst unverständlichen Code. Das mache ich auch gerne. Das ist eine Art Knobelspiel für Programmierer und dient der Entspannung. Kein Programmierer würde ein solches Knobelspiel in eine Funktion packen, die er dem Anwender ernsthaft als produktive Variante für die Wochentagsberechnung anbietet. Schon gar nicht ohne die Grenzen seiner Funktion zu benennen. WTF? Es kann durchaus Gründe für unverständlichen Code geben. Steve Wozniak (The Woz) beispielsweise hat Code geschrieben, der die Eigenheiten der Hardware in besonderer Weise ausnutzt, um effizient zu sein. Für jemanden ohne diese intimen Kenntnisse ist der Code von Woz schlicht unverständlich und somit schwer zu pflegen. Im Vergleich dazu kann ich bei dem Algorithmus von Lawrence keinen rationalen Grund erkennen, warum der Code derart unverständlich sein muss. Hätte er den Code als Aufgabe präsentiert, frei nach dem Motto "finde heraus wann ich Geburtstag habe", oder ähnliches, wäre ich hellauf begeistert davon. Aber so liefert uns sein Code ein abschreckendes Beispiel dafür, wie man es nicht machen sollte.
Wenn wir seine Routine so lassen, wie er es sich vorgestellt hat, dann ist das selbst in der entwirrten Form keine gute Lösung für das Wochentagsproblem. Eine andere Umsetzung, zumindest für die Rückrechnung, muss her, die keine Fehler produziert, wenn das Datum vor dem 29.12.1969 liegt. Hier liefert die Funktion FncDateToWeekdayNr_Hack_11 den besten Ansatz unter den Hacks, nicht weil sie den beiden vorhergehenden Funktionen gegenüber technisch überlegen wäre, sondern weil der Lösungsweg hier für den Leser gut nachvollziehbar ist.
In Bearbeitung... (fertig)
Ja, klar, man mulitpliziert die Jahre und erhält alle 4 Jahre einen Tag dazu. Viele Wege führen nach Rom; die Schaltjahre lassen sich ebenso gut mit einer Ganzzahlenberechnung erfassen. Das sollte hier also keine große Rolle spielen.
Zitat von @Biber:
Aber bei jeder Vereinfachung auf "Rechnen nur mit Ganzzahlen" ergibt sich zwangsläufig dieser merkwürdige Wert
"4800 Jahre" aus der Zeile
> set /a y=yy+4800-z ....
Aber bei jeder Vereinfachung auf "Rechnen nur mit Ganzzahlen" ergibt sich zwangsläufig dieser merkwürdige Wert
"4800 Jahre" aus der Zeile
> set /a y=yy+4800-z ....
Zwangsläufig? Weshlab? Läuft doch auch ohne die 4800 Jahre alles im 32-Bit-Wertebereich der Ganzzahlen ab. Ausserdem wird der genutzte Wertebereich durch diese Aktion größer und nicht kleiner. Womöglich sehe ich jetzt nicht was Du meinst und begebe mich auf einen Holzweg? Wäre nett, wenn Du das näher ausführen könntest.
Glaube ich erst, wenn ich ihn auseinandergenommen und überprüft habe. ;)
Zitat von @Biber:
- die Codezeile "set /a dd=100%dd%%%100,mm=100%mm%%%100" ist NICHT ersetzbar durch deine Alternative (set /a dd=dd), da R.L. auch
Mist. Mein Fehler. Verdammter Schnellschuss. Nicht richtig überlegt. Du meinst, dass set Zahlen mit führender 0 als oktale Werte interpretiert, die bei 08 und 09 ungültig wären. Daran hatte ich nicht gedacht. Danke für den Hinweis.
Bye, nz
Danke für Dein Feedback.
Habe ich mir auch schon überlegt. Denn es genügt nicht, wie ürsprünglich vorgesehen, Ritchie Lawrences Code ein wenig zu entwirren, um ihn allgemeinverständlich umzusetzen. Wenn wir die Routine so lassen, wie er es sich vorgestellt hat, dann ist das keine gute Lösung für das Wochentagsproblem. Ein anderer Ansatz, zumindest für die Rückrechnung, muss her. In diesem Fall passt das natürlcih besser in ein eigenes TUT zum Thema "Wochentagsberechnung unter Batch" oder ähnlichem. Zudem lassen sich dann auch die alternativen Lösungswege besser zusammenfassen und das Thema über das Wochentagsproblem hinaus ausbauen (JulianDay, etc.).
Wenn es Dir recht ist, beende ich mein Protokoll erst einmal in aller Ruhe hier in diesem Thread, wo ich es angefangen hatte, und mache dann erst ein eigenes TUT dazu auf. Das Thema wird dann zwar zum Teil doppelt behandelt, aber einfach jetzt hier aufzuhören oder das Protokoll gar zu löschen, macht diesen Thread hier unsauber. Dann versteht ja keiner mehr, worüber wir uns hier eigentlch unterhalten...
Bye, nz
Habe ich mir auch schon überlegt. Denn es genügt nicht, wie ürsprünglich vorgesehen, Ritchie Lawrences Code ein wenig zu entwirren, um ihn allgemeinverständlich umzusetzen. Wenn wir die Routine so lassen, wie er es sich vorgestellt hat, dann ist das keine gute Lösung für das Wochentagsproblem. Ein anderer Ansatz, zumindest für die Rückrechnung, muss her. In diesem Fall passt das natürlcih besser in ein eigenes TUT zum Thema "Wochentagsberechnung unter Batch" oder ähnlichem. Zudem lassen sich dann auch die alternativen Lösungswege besser zusammenfassen und das Thema über das Wochentagsproblem hinaus ausbauen (JulianDay, etc.).
Wenn es Dir recht ist, beende ich mein Protokoll erst einmal in aller Ruhe hier in diesem Thread, wo ich es angefangen hatte, und mache dann erst ein eigenes TUT dazu auf. Das Thema wird dann zwar zum Teil doppelt behandelt, aber einfach jetzt hier aufzuhören oder das Protokoll gar zu löschen, macht diesen Thread hier unsauber. Dann versteht ja keiner mehr, worüber wir uns hier eigentlch unterhalten...
Bye, nz
moin Biber,
es sind zwar schon einige Jahreszeiten bisher vergangen seit diesem Beitrag: Batch am Monatsende ausführen,
wo es unter anderem um diese Ausgabe ging.
[OT]
Da bin ich mir aber ziemlich sicher, der TE hat einen copy&paste Fehler Fabriziert, der Punkt war nacher mit drin.
[/OT]
aber nun wollte ich mal ein klein wenig Optimum für die GetAllDateTimeInfos.bat loswerden.
warum eigentlich .bat und nicht .CMD? Bat ist zwar als Abkürzung für Batch besser zu verstehen, aber da der Batch eh nur ab OS Windows_NT läuft wäre doch die Endung .CMD passender. Vor und in 98SE gabs doch keine *.CMD.
So nun mal zu den Kleinigkeiten.
Zeile 51.
da ist hinter dem Echo kein PlatzhalterZeichen und führt Praktisch zu der Ausgabe:
ist zwar nicht weiter Tragisch, aber die Variablen werden so zweimal gesetzt.
Und oben die Ausgabe hat ja die Punkte im Datumsformat. Dieser müsste dann bei delims auch hinein in Zeile 51:
Und weil dieses DatumsFormat keinen Wert für YY oder für JJ liefert in den meisten Spracheinstellungen MM und DD oder TT gefunden werden aber der Wert fürs Jahr irgendetwas anderes ist und am Ende Trotzdem nicht ausgegeben werden, sind mir 3 Zeilen zur Verbesserung eingefallen:
als neue zusätzliche Zeile 55:
Hiermit wird Dir ein Wert für JJ aus einer Bestehenden unbekannten Variablen ertmal Bekannt gemacht (Other) und als JJ, falls noch nicht gesetzt, gesetzt.
JJ aus dem Grund: In Zeile 120. wird es ausgeschlossen dieses JJ zu verwenden wenn schon YY besteht.
In Zeile 127. wird dazu auch diese jetzt bekannte Variable abgerufen:
Sowie für den cleanUp zum löschen in Zeile 130:
Gruß Phil
es sind zwar schon einige Jahreszeiten bisher vergangen seit diesem Beitrag: Batch am Monatsende ausführen,
wo es unter anderem um diese Ausgabe ging.
Gjeldende dato er: 04.03.2011
Skriv ny dato: (dd.mm.åå)
---
04.03.2011
Da bin ich mir aber ziemlich sicher, der TE hat einen copy&paste Fehler Fabriziert, der Punkt war nacher mit drin.
[/OT]
aber nun wollte ich mal ein klein wenig Optimum für die GetAllDateTimeInfos.bat loswerden.
warum eigentlich .bat und nicht .CMD? Bat ist zwar als Abkürzung für Batch besser zu verstehen, aber da der Batch eh nur ab OS Windows_NT läuft wäre doch die Endung .CMD passender. Vor und in 98SE gabs doch keine *.CMD.
So nun mal zu den Kleinigkeiten.
Zeile 51.
FOR /F "tokens=2-4 delims=/-,() skip=1" %%a in ('echo ^|date') do (
Geben Sie das neue Datum ein: (TT-MM-JJ) ECHO ist eingeschaltet (ON).
Eingegebenes Datum kann nicht übernommen werden.
Geben Sie das neue Datum ein: (TT-MM-JJ)
Und oben die Ausgabe hat ja die Punkte im Datumsformat. Dieser müsste dann bei delims auch hinein in Zeile 51:
FOR /F "tokens=2-4 delims=./-,() skip=1" %%a in ('echo(^|date') do (
Und weil dieses DatumsFormat keinen Wert für YY oder für JJ liefert in den meisten Spracheinstellungen MM und DD oder TT gefunden werden aber der Wert fürs Jahr irgendetwas anderes ist und am Ende Trotzdem nicht ausgegeben werden, sind mir 3 Zeilen zur Verbesserung eingefallen:
als neue zusätzliche Zeile 55:
FOR /F "delims=DTMYJ-dtmyj" %%i in ("%DateOrder%") do set "Other=%%i"&if not defined JJ call set "JJ=%%%%i%%"
JJ aus dem Grund: In Zeile 120. wird es ausgeschlossen dieses JJ zu verwenden wenn schon YY besteht.
In Zeile 127. wird dazu auch diese jetzt bekannte Variable abgerufen:
For %%i in (INDate INTime %Other% %AllDateTimeVars%) do @if defined %%i set %%i|find /i "%%i="
For %%i in (vbssnippet INTime INDate %Other% Other) Do Set "%%i="
Gruß Phil
Ja eigentlich hatte ich gestern Nachmittag nur nichts zu tun.
wie immer - kurz und knackig
Gruß Phil
.. in der zweiten Zeile die TTs und MMs und JJs mit Punkten getrennt angezeigt.
Das kann ich mir nicht vorstellen.
wollt ich auch erst nicht, doch ich hab mir Testhalber die Sprache:Das kann ich mir nicht vorstellen.
norsk (bokmål)
installiert.date^<nul
Gruß Phil
Hallo Biber,
ich habe etwas rumgespielt und den Code auch auf den chinesischen PCs ziemlich umkonventionell (bin auch nicht so fit in Catch Programmierung) zu Laufen gebracht. Ich habe die Zeile
durch folgendes ersetzt:
Gruß RobSei
ich habe etwas rumgespielt und den Code auch auf den chinesischen PCs ziemlich umkonventionell (bin auch nicht so fit in Catch Programmierung) zu Laufen gebracht. Ich habe die Zeile
FOR /F "tokens=2" %%i in ("%INDate%") do Set "INDate=%%i"
REM Datumsformat “Sa 01.10.2005“
If "%indate:~5,1%" == ":" FOR /F "tokens=2" %%i in ("%INDate%") do Set "INDate=%%i"
If "%indate:~5,1%" == "/" FOR /F "tokens=2" %%i in ("%INDate%") do Set "INDate=%%i"
If "%indate:~5,1%" == "." FOR /F "tokens=2" %%i in ("%INDate%") do Set "INDate=%%i"
If "%indate:~5,1%" == "-" FOR /F "tokens=2" %%i in ("%INDate%") do Set "INDate=%%i"
If "%indate:~5,1%" == "," FOR /F "tokens=2" %%i in ("%INDate%") do Set "INDate=%%i"
REM Datumsformat “Fri 10/11/2013"
If "%indate:~6,1%" == ":" FOR /F "tokens=2" %%i in ("%INDate%") do Set "INDate=%%i"
If "%indate:~6,1%" == "/" FOR /F "tokens=2" %%i in ("%INDate%") do Set "INDate=%%i"
If "%indate:~6,1%" == "." FOR /F "tokens=2" %%i in ("%INDate%") do Set "INDate=%%i"
If "%indate:~6,1%" == "-" FOR /F "tokens=2" %%i in ("%INDate%") do Set "INDate=%%i"
If "%indate:~6,1%" == "," FOR /F "tokens=2" %%i in ("%INDate%") do Set "INDate=%%i"
REM Datumsformat “2013-10-10 ???“ (??? sind 3 chinesische Zeichen)
If "%indate:~4,1%" == ":" FOR /F "tokens=1" %%i in ("%INDate%") do Set "INDate=%%i"
If "%indate:~4,1%" == "/" FOR /F "tokens=1" %%i in ("%INDate%") do Set "INDate=%%i"
If "%indate:~4,1%" == "." FOR /F "tokens=1" %%i in ("%INDate%") do Set "INDate=%%i"
If "%indate:~4,1%" == "-" FOR /F "tokens=1" %%i in ("%INDate%") do Set "INDate=%%i"
If "%indate:~4,1%" == "," FOR /F "tokens=1" %%i in ("%INDate%") do Set "INDate=%%i"