Workshop Batch for Runaways - Part III - Datums- und Zeitvariablen im Batch
03.10.2005
08:57:20 Uhr85357 Aufrufe
66 Antworten
08:57:20 Uhr
66 Antworten
Hilfreich +8
Immer wieder gern gefragt.. wie kann ich im CMD-Batch Datums- und Zeitvariablen bilden und nutzen.
Ein paar Anregungen dazu hier im Workshop.
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
HKCU\Control Panel\International
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_USER\Control Panel\International\Calendars\TwoDigitYearMax (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)
>getDow 2005 10 2 nWochentag
nWochentag=7
----------
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
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
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
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:
01.
02.
>date 03.
Aktuelles Datum: Sa 01.10.2005 04.
Geben Sie das neue Datum ein: (TT-MM-JJ) 05.
06.
>time 07.
Aktuelle Zeit: 12:43:14,96 08.
Geben Sie die neue Zeit ein: 09.
10.
>date /t & time /t 11.
Sa 01.10.2005 12.
12:43 13.
14.
>echo %date% %time% 15.
Sa 01.10.2005 12:44:00,82 16.
17.
echo exit|cmd /q /k"prompt $D $T" 18.
Sa 01.10.2005 12:45:03,29Ich ändere mal in den Systemsteuerung->"Ländereinstellungen"/"Regional Settings" das Datumsformat auf das angebotene "JJJJ-MM-TT" und erhalte in einem neuen CMD-Fenster:
01.
>date 02.
Aktuelles Datum: Sa 2005-10-01 03.
Geben Sie das neue Datum ein: (JJ-MM-TT) 04.
>date /t 05.
Sa 2005-10-01 06.
>echo %date% 07.
Sa 2005-10-01Ist aber auch nicht immer so... manchmal fehlt der Wochentag auch. Wunderwelt Windows.
Auch die DIR-Anzeige übernimmt das Datumsformat:
01.
>dir *.reg 02.
2005-08-12 21:51 1.272 MyCommandPrompt.reg 03.
2005-09-19 00:16 920 RegDLL_Restore.reg 04.
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.
01.
>reg query "HKCU\Control Panel\International" /s 02.
HKEY_CURRENT_USER\Control Panel\International 03.
iCountry REG_SZ 49 04.
iCurrDigits REG_SZ 2 05.
iCurrency REG_SZ 3 06.
iDate REG_SZ 2 07.
iDigits REG_SZ 2 08.
iLZero REG_SZ 1 09.
iMeasure REG_SZ 0 10.
iNegCurr REG_SZ 8 11.
iTime REG_SZ 1 12.
iTLZero REG_SZ 1 13.
Locale REG_SZ 00000407 14.
s1159 REG_SZ 15.
s2359 REG_SZ 16.
sCountry REG_SZ Deutschland 17.
sCurrency REG_SZ 18.
sDate REG_SZ - 19.
sDecimal REG_SZ , 20.
sLanguage REG_SZ DEU 21.
sList REG_SZ ; 22.
sLongDate REG_SZ dddd, d. MMMM yyyy 23.
sShortDate REG_SZ yyyy-MM-dd 24.
sThousand REG_SZ . 25.
sTime REG_SZ : 26.
sTimeFormat REG_SZ HH:mm:ss 27.
iTimePrefix REG_SZ 0 28.
sMonDecimalSep REG_SZ , 29.
sMonThousandSep REG_SZ . 30.
iNegNumber REG_SZ 1 31.
sNativeDigits REG_SZ 0123456789 32.
NumShape REG_SZ 1 33.
iCalendarType REG_SZ 1 34.
iFirstDayOfWeek REG_SZ 0 35.
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
HKCU\Control Panel\International
| 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):
01.
>reg add "HKCU\Control Panel\International" /v idate /t REG_SZ /d 1 /f 02.
>date 03.
Aktuelles Datum: Sa 01-10-2005 04.
Geben Sie das neue Datum ein: (TT-MM-JJ) 05.
06.
>date /t 07.
Sa 01-10-2005 08.
>reg add "HKCU\Control Panel\International" /v idate /t REG_SZ /d 0 /f 09.
>date /t 10.
Sa 10-01-2005 11.
12.
>date 13.
Aktuelles Datum: Sa 10-01-2005 14.
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):
01.
>echo exit|cmd /q /k"prompt $D $T" 02.
Sa 01.10.2005 11:38:26,79 03.
04.
>echo.|date 05.
Aktuelles Datum: Sa 01.10.2005 06.
Geben Sie das neue Datum ein: (TT-MM-JJ)01.
---snipp Codefragment GetAllSystemDateTimeInfos_1.bat----- 02.
For /f "tokens=1-7 delims=:/.-, " %%i in ('echo exit^|cmd /q /k"prompt $D $T"') do ( 03.
For /f "tokens=2-4 delims=/-,() skip=1" %%a in ('echo.^|date') do ( 04.
for %%@ in ("dow=%%i" "DateOrder=%%a-%%b-%%c" "%%a=%%j" "%%b=%%k" "%%c=%%l" "hh=%%m" "min=%%n" "ss=%%o") do set %%@ 05.
) 06.
) 07.
::---snipp Codefragment GetAllSystemDateTimeInfos_1.bat-----01.
>GetAllSystemDateTimeInfos_1 >nul 02.
For %i in (DateOrder DoW DD TT MM JJ YY hh min ss) do @if defined %i set %i 03.
DateOrder=TT-MM-JJ 04.
DoW=Sa 05.
TT=01 06.
MM=10 07.
JJ=2005 08.
hh=11 09.
min=39 10.
ss=0301.
DateOrder=YY-MM-DD 02.
DoW=Sa 03.
DD=01 04.
MM=10 05.
YY=2005 06.
hh=11 07.
min=39 08.
ss=03Beispiel: Aufgabe sei, das Logfile SQL.Log unzubenennen in 2005-10-01_11h39_SQL.Log
01.
>if defined TT if defined JJ ren SQL.Log %JJ%-%MM%-%TT%_%hh%h%min%_SQL.Log 02.
>if defined DD if defined YY ren SQL.Log %YY%-%MM%-%DD%_%hh%h%min%_SQL.LogProblem 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)
01.
::--------kurzes Codebeispiel zum "schnellen" Bilden von Datums/Zeitstempeln; passt meistens. 02.
... 03.
:CopyWithRename 04.
Set "DatePrefix=%date%" & Set "TimeSuffix=%time%" & REM Namenserweiterungen für die zu kopierende Datei 05.
FOR /f "tokens=2" %%i in ("%datePrefix%") do Set DatePrefix=%%i 06.
FOR /f "tokens=1-3 delims=." %%i in ("%datePrefix%") do Set Dateprefix=%%k%%j%%i 07.
for /F "tokens=1-3 delims=:," %%i in ("%time%") do Set "TimeSuffix=%%i%%j%%k" 08.
Set "TimeSuffix=%TimeSuffix: =0%" 09.
..01.
::-------snipp GetAllSystemDateTimeInfos_2.bat ----- 02.
@echo off & setlocal 03.
:: (c) Biberware 2005 Placed in the Public Domain Oct 2005 for Educational Purposes 04.
:: Ermittelt ein paar Datums/Zeitvariable aus dem CMD-Environment (Systemdatum/Systemzeit) OHNE REG-Abfragen 05.
:: Einschränkung: Sollte schon NT oder höher sein, Deshalb die nächte Zeile 06.
IF NOT "%OS%"=="Windows_NT" echo "%0 läuft nur unter WinNT oder höher. Sorry." && GOTO :eof 07.
SET "AllDateTimeVars=DateOrder KW DoW DoY DD TT MM JJ YY hh min ss ms" 08.
FOR %%i in (%AllDateTimeVars%) do @if defined %%i set %%i= 09.
:: Datum will ich OHNE Wochentag haben. Zwischenschritt mit MyDateOhneDoW 10.
Set MyDateOhneDoW=%date% 11.
:: Die nächste Code-Zeile ändert nur dann etwas, wenn ein Wochentag mitgeliefert wird. 12.
:: Aus "Sa 01.10.2005" wird dann "01.10.2005" 13.
FOR /F "tokens=2" %%i in ("%MyDateOhneDoW%") do Set MyDateOhneDoW=%%i 14.
FOR /F "tokens=1-7 delims=:/.-, " %%i in ("%MyDateOhneDow% %time%") do ( 15.
For /f "tokens=2-4 delims=/-,() skip=1" %%a in ('echo.^|date') do ( 16.
for %%@ in ("DateOrder=%%a-%%b-%%c" "%%a=%%i" "%%b=%%j" "%%c=%%k" "hh=%%l" "min=%%m" "ss=%%n" "ms=%%o") do set %%@ 17.
) 18.
) 19.
:: Lass sehen, was wir haben.... 20.
For %%i in (%AllDateTimeVars%) do @if defined %%i set %%i 21.
::-------snapp GetAllSystemDateTimeInfos_2.bat01.
>GetAllSystemDateTimeInfos_2 02.
DateOrder=TT-MM-JJ 03.
TT=01 04.
MM=10 05.
JJ=2005 06.
hh=13 07.
min=36 08.
ss=30 09.
ms=02Ich turn das mal exemplarisch vor für das System-Datum (System-Zeit läuft analog. Schenk ich mir.)
01.
::--------snapp GetAllSystemDateTimeInfos_3.bat 02.
@ECHO OFF 03.
:: (c) Biberware 2005 Placed in the Public Domain Oct 2005 for Educational Purposes 04.
:: Ermittelt ein paar Datumsvariablen aus dem CMD-Environment (Systemdatum) <b>MIT </b>REG-Abfragen 05.
06.
IF NOT "%OS%"=="Windows_NT" echo "%0 läuft nur unter WinNT oder höher.Sorry." && GOTO :eof 07.
Setlocal 08.
SET "AllSystemDateTimeVars=DateOrder KW DoW DoY DD TT MM JJ YY hh min ss ms" 09.
:: Systemdatum abgreifen in lokale Variable, erstmal so wie geliefert 10.
Set MyDateOhneDoW=%date% 11.
:: Die nächste Code-Zeile ändert nur dann etwas, wenn ein Wochentag mitgeliefert wird. 12.
:: Aus "Sa 01.10.2005" wird dann "01.10.2005" 13.
FOR /F "tokens=2" %%i in ("%MyDateOhneDoW%") do Set MyDateOhneDoW=%%i 14.
ECHO Heute ist %MyDateOhneDoW% 15.
16.
:: Registry-Werte in ein Temp-File auslesen mit RegEdit.exe 17.
:: <b>Nicht </b>mit REG.exe wegen der Reg.exe-Syntaxunterschiede je nach Version! 18.
Set RegFile=%temp%\%random%.reg 19.
START /W REGEDIT /E %Regfile% "HKEY_CURRENT_USER\Control Panel\International" 20.
:: [Anmerkung 13.2.2006 - Uuups, war mir damals gar nicht bewusst, dass der Parameter "/W" undokumentiert ist] 21.
:: [ Laut Hilfe mit "Start /?" heißt es "Start /Wait"... ich hatte echt nicht drüber nachgedacht. ] 22.
:: Auswerten der Werte iDate (0,1,2) und sDate (Datumstrennzeichen) 23.
FOR /F "tokens=1* delims==" %%i IN ('Type %RegFile% ^| FIND /I "iDate"') DO SET iDate=%%j 24.
FOR /F "tokens=1* delims==" %%i IN ('Type %RegFile% ^| FIND /I "sDate"') DO SET sDate=%%j 25.
DEL %RegFile% 26.
27.
:: RegWerte weiterbehandeln... Anführungszeichen entfernen 28.
SET iDate=%iDate:"=% 29.
SET sDate=%sDate:"=% 30.
31.
:: Und nun in TT, MM, JJ sortieren 32.
FOR /F "TOKENS=1-3 DELIMS=%sDate%" %%a IN ("%MyDateOhneDoW%") DO echo %%a %%b %%c 33.
34.
FOR /F "TOKENS=1-3 DELIMS=%sDate%" %%a IN ("%MyDateOhneDoW%") DO ( 35.
IF %iDate%==0 For %%i in ("JJ=%%c" "MM=%%a" "TT=%%b" "DateOrder=MM-TT-JJ") DO SET %%i 36.
IF %iDate%==1 For %%i in ("JJ=%%c" "MM=%%b" "TT=%%a" "DateOrder=TT-MM-JJ") DO SET %%i 37.
IF %iDate%==2 For %%i in ("JJ=%%a" "MM=%%b" "TT=%%c" "DateOrder=JJ-MM-TT") DO SET %%i 38.
) 39.
:: Lass sehen, was wir haben.... 40.
For %%i in (%AllSystemDateTimeVars%) do @if defined %%i set %%i 41.
42.
ENDLOCAL 43.
GOTO:EOF 44.
:: --------snapp GetAllSystemDateTimeInfos_3.batDateOrder=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_USER\Control Panel\International\Calendars\TwoDigitYearMax (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:
01.
:: --- snipp GetDoW-Codeschnipsel.bat 02.
:: Berechnet den DoW / Tag der Woche als numerischen Wert 1=Montag...7=Sonntag 03.
:: IN-Parameter: Para 1-3 yy, mm, dd ( Jahr 2 oder 4stellig, Monat, Tag (mit/ohne führende "0" egal) 04.
:: ..............Para 4 ist ein Variablennamen für den DoW/TachDerWoche 05.
:: ..............Optional: Para 5 die Datumsgrenze (z.B. TwoDigitYearMax aus der REG). 06.
::...............Mein Default (vollkommen willkürlich) 2038 07.
:: ich mach hier <b>KEINE </b> Parameterüberprüfung und ähnliches, soll ja später nicht als eigenständiger Batch verwendet werden. 08.
:: Algorithmus frei nach [http://www.commandline.co.uk/lib/treeview/index.php Batch Function Library for Windows NT4/2000/XP/2003] 09.
@echo off & Setlocal 10.
IF [%5]==[] (set /a "TwoDigitYearMax=2038%%1000") Else set /a TwoDigitYearMax=%5%%1000 11.
set yy=%1 & set mm=%2 & set dd=%3 12.
if 1%yy% LSS 200 if 1%yy% LSS 1%TwoDigitYearMax% (set yy=20%yy%) else (set yy=19%yy%) 13.
set /a dd=100%dd%%%100,mm=100%mm%%%100 14.
set /a z=14-mm,z/=12,y=yy+4800-z,m=mm+12*z-3,dow=153*m+2 15.
set /a dow=dow/5+dd+y*365+y/4-y/100+y/400-2472630,dow%%=7,dow+=1 16.
endlocal&Set %4=%dow%&goto :EOF 17.
:: --- snipp GetDoW-Codeschnipsel.bat >getDow 2005 10 2 nWochentag
nWochentag=7
----------
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:
01.
'-------snipp DateStrings.vbs 02.
If wscript.arguments.count = 1 Then 03.
MyDate=wscript.arguments.item(0) 04.
Else 05.
Mydate=Date 06.
End If 07.
wScript.echo "Ausgangsdatum der Berechnungen : " & Mydate 08.
wScript.echo "DoY/Tag des Jahres : datepart('y' ,Date): " & datepart("y" ,MyDate) 09.
wScript.echo "Kalenderwoche : datepart('ww',Date): " & datepart("ww",MyDate) 10.
wScript.echo "DoW/Wochentag 1=So : datepart('w',Date) : " & datepart("w" ,MyDate) 11.
'--------Snapp DateStrings.vbs 01.
>cscript //nologo Datestrings.vbs 02.
Ausgangsdatum der Berechnungen : 03.10.2005 03.
DoY/Tag des Jahres : datepart('y' ,Date): 276 04.
Kalenderwoche : datepart('ww',Date): 41 05.
DoW/Wochentag 1=So : datepart('w',Date) : 2 06.
07.
>cscript //nologo Datestrings.vbs 01.10.2005 08.
Ausgangsdatum der Berechnungen : 01.10.2005 09.
DoY/Tag des Jahres : datepart('y' ,Date): 274 10.
Kalenderwoche : datepart('ww',Date): 40 11.
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:
01.
'----snipp DateKrams.vbs 02.
Wscript.Echo " " & DatePart("ww",Date,vbSunday,vbFirstFourDays) & " " &_ 03.
DatePart("ww",Date) & " " & DatePart("w",Date) & " " & DatePart("y",Date) 04.
'------snapp DateKrams.vbs 01.
>for /f "tokens=2-5" %a in ('cscript //nologo DateKrams.vbs') do @echo KW=%a,KWOS=%b,DoW=%c,DoY=%d 02.
KW=40,KWOS=41,DoW=2,DoY=276Zum 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
01.
::-------snipp GetAllDateTimeInfos.cmd ----- 02.
@echo off & setlocal 03.
:: (c) Biberware 2005 Placed in the Public Domain Oct 2005 for Educational Purposes 04.
:: Ermittelt Datums/Zeitvariable aus dem CMD-Environment und stellt sie als Variablen bereit 05.
:: Einschränkung: Sollte schon NT oder höher sein. Deshalb die erste Zeile 06.
:: Vers. 0.02 Minor Bugfix; siehe zweiten Kommentar unten. 14.12.2005 by Biber 07.
:: Vers. 0.06a Bugfix/Workarounds für Formfeed-Bug W2K und "Set /a 09"-Bug 08.
:: -------------- Und alle SETs in Anführungszeichen. Siehe unten. 13.2.2006 09.
:: Vers. 0.06b Aus Kompat-Gründen jetzt ohne erwartete "DelayedExpansion"-Reg-Voreinstellung 10.
:: Vers. 0.07 Aufrufe mit Parameter/? bzw /h NACH dem Setzen der %AllDateTimeVar%s verschoben 11.
:: Vers. 0.08 Windows NT scheint die Variablen %date% und %time% nicht zu kennen 12.
:: Vers. 0.09 undokumentierten Befehl "echo." durch undokumentierten "echo\" ersetzt 13.
:: Ausgabe nur der "eigenen" Variablen ---> set "eigenevar"|find "eigenevar=" 14.
:: Vers. 010 Bugfix Variable AlldateTimeVars wurde nicht gelöscht, siehe srmerlins Kommentar unten 15.
:: Vers. 011 Erweiterung und Feinschliff, s.u. pieh-ejdsch schreibt am 19.02.2012, 17:24:36 Uhr 16.
IF NOT "%OS%"=="Windows_NT" echo "%0 läuft nur unter WinNT oder höher. Sorry." && GOTO :eof 17.
18.
For %%i in ( %1 %2 %3 %4) Do ( 19.
If /i [%%i]==[/s] Endlocal 20.
If /i [%%i]==[/u] Endlocal 21.
If /i [%%i]==[/h] %0 /? 22.
) 23.
24.
SET "AllDateTimeVars=DateOrder KW OSKW DoW DoY cDoW DD TT MM JJ YY hh min ss ms" 25.
If /i [%1]==[/?] goto Syntax 26.
27.
FOR %%i in (%AllDateTimeVars%) do @if defined %%i set "%%i=" 28.
:: Datum will ich OHNE Wochentag haben. Zwischenschritt mit INDate 29.
30.
:: erweitert, Parameter erlaubt.. Param1=Datumswert;Param2=Zeit 31.
For %%i in (%1 %2 %3) Do If /i %%i==/u Set "AllDateTimeVars=" & goto :Cleanup 32.
:: Vers 0.09 11.7.2007: Windows NT kennt weder %date% noch %time%. 33.
:: Deshalb lieber folgende Syntax wählen statt der beiden Zeilen darunter: 34.
FOR /F "delims=" %%i in ('date/T') do Set "INDate=%%i" 35.
:: Vers. 0.10 20.9.2007: time/T hat Format "hh:mm" ; %time% dagegen "hh:mm:ss, nn" 36.
:: ----> Time /t nur im Notfall - wenn %time% nicht definiert ist - verwenden. 37.
IF defined time set "INTime=%time%" 38.
IF not defined INtime FOR /F "delims=" %%i in ('time/T') do Set "InTime=%%i" 39.
:: --- ersetzt durch Vers. 010 FOR /F "delims=" %%i in ('time/T') do Set "INTime=%%i" 40.
:: -- ersetzt Vers. 0.09 Set "INDate=%date%" 41.
:: -- ersetzt Vers. 0.09 Set "INTime=%time%" 42.
43.
If NOT [%1]==[] If /i [%1] NEQ [/q] If /i [%1] NEQ [/s] set "INDate=%1" 44.
If NOT [%2]==[] If /i [%2] NEQ [/q] If /i [%2] NEQ [/s] set "INTime=%2" 45.
46.
:: Die nächste Code-Zeile ändert nur dann etwas, wenn ein Wochentag mitgeliefert wird. 47.
:: Aus "Sa 01.10.2005" wird dann "01.10.2005" 48.
FOR /F "tokens=2" %%i in ("%INDate%") do Set "INDate=%%i" 49.
:: Beschränkung auf existierende Datumsformate siehe Posting mit CAT unten. 50.
:: Das Format "Mo, 13. Februar 2006" mit zwei Leerzeichen würde NICHT funktionieren! 51.
FOR /F "tokens=1-7 delims=:/.-, " %%i in ("%INDate% %INTime%") do ( 52.
FOR /F "tokens=2-4 delims=./-,() skip=1" %%a in ('date^<nul') do ( 53.
for %%@ in ("DateOrder=%%a-%%b-%%c" "%%a=%%i" "%%b=%%j" "%%c=%%k" "hh=%%l" "min=%%m" "ss=%%n" "ms=%%o") do set %%@ 54.
) 55.
) 56.
FOR /F "delims=DTMYJ-dtmyj" %%i in ("%DateOrder%") do set "Other=%%i"&if not defined JJ call set "JJ=%%%%i%%" 57.
For %%i in (ss ms) do if not defined %%i set "%%i=00" 58.
:: ----- v005 Workaround wegen W2K-Formfeed-Bug: Kommata als Delimiter im VBS-Schnipsel-Output 59.
SET "vbsSnippet=%temp%\%random%.vbs" 60.
echo If wscript.arguments.count = 1 Then dDate=wscript.arguments.item(0) Else dDate=Date>%vbssnippet% 61.
echo Wscript.Echo "x," ^& DatePart("ww",dDate,vbSunday,vbFirstFourDays) ^& "," ^&_>>%vbsSnippet% 62.
echo DatePart("ww",dDate) ^& "," ^& DatePart("w",dDate) ^& "," ^& DatePart("y",dDate)>>%vbsSnippet% 63.
64.
for /F "delims=, tokens=2-5" %%a in ('cscript //nologo %vbsSnippet% %INDate%') do ( 65.
(Set "KW=%%a" ) && Rem Kalenderwoche nach verbreiteter Berechnung 66.
(Set "OSKW=%%b" ) && Rem Kalenderwoche nach Betriebssystemvorgaben nicht über GUI änderbar! *lacht 67.
(Set "DoW=%%c" ) && Rem Day of Week 1=Sonntag, 2= Montag... bei meinen REG-Settings 68.
(Set "DoY=%%d" ) && Rem Day of Year, Kalendertag 69.
) 70.
del %vbssnippet% 71.
72.
:: Tag, Monat und Stunde möchte ich immer zweistellig haben, also mit führender "0" 73.
:: v006-Fix<s>For %%i in (DD TT MM hh) DO IF DEFINED %%i Set /a %%i+=100 </s> 74.
:: v006-Fix wg. Set /A-Bug. THX an superfrog für den Bugreport 75.
:: v006b-Fix-Fix <s>For %%i in (DD TT MM hh) DO IF DEFINED %%i Set "%%i=10!%%i!"</s> 76.
:: --- für die beiden Fixes siehe die Kommentare von superfrog unten -- 14.2.2006 77.
IF defined DD Set "DD=10%DD%" 78.
IF defined TT Set "TT=10%TT%" 79.
IF defined MM Set "MM=10%MM%" 80.
IF defined hh Set "hh=10%hh%" 81.
:: -v006b ----Vier Zeilen ohne DelayedExpansion statt eine FOR..IN..DO-Anweisung 82.
83.
set "hh=%hh:~-2,2%" 84.
set "MM=%MM:~-2,2%" 85.
:: ... und den Wochentag will ich auch, wenigstens in zwei Sprachen. 86.
IF defined DD ( 87.
set "DD=%DD:~-2,2%" 88.
IF %DoW%==1 Set "cDoW=Sun" 89.
IF %DoW%==2 Set "cDoW=Mon" 90.
IF %DoW%==3 Set "cDoW=Tue" 91.
IF %DoW%==4 Set "cDoW=Wed" 92.
IF %DoW%==5 Set "cDoW=Thu" 93.
IF %DoW%==6 Set "cDoW=Fri" 94.
IF %DoW%==7 Set "cDoW=Sat" 95.
) 96.
97.
IF defined TT ( 98.
set "TT=%TT:~-2,2%" 99.
IF %DoW%==1 Set "cDoW=So" 100.
IF %DoW%==2 Set "cDoW=Mo" 101.
IF %DoW%==3 Set "cDoW=Di" 102.
IF %DoW%==4 Set "cDoW=Mi" 103.
IF %DoW%==5 Set "cDoW=Do" 104.
IF %DoW%==6 Set "cDoW=Fr" 105.
IF %DoW%==7 Set "cDoW=Sa" 106.
107.
) 108.
:: so.. hier schlampe ich mal.. 109.
:: alle 2-stelligen Jahre kleiner 39 werden zu 2001...2038 110.
:: alle 2-stelligen Jahre größer gleich 39 und kleiner gleich 99 werden zu 1939 bis 1999 111.
112.
IF not defined YY goto YYskip 113.
IF %YY% LSS 39 set "YY=20%YY%" 114.
IF %YY% LEQ 99 set "YY=19%YY%" 115.
:YYskip 116.
If not defined JJ goto JJskip 117.
IF %JJ% LSS 39 set "JJ=20%JJ%" 118.
IF %JJ% LEQ 99 set "JJ=19%JJ%" 119.
:JJskip 120.
121.
IF defined YY set "JJ=%YY%" 122.
IF defined JJ set "YY=%JJ%" 123.
IF defined DD Set "TT=%DD%" 124.
IF defined TT Set "DD=%TT%" 125.
:: Lass sehen, was wir haben....falls kein Parameter /q 126.
For %%i in (%1 %2 %3 %4) Do If /i %%i==/q goto cleanUp 127.
128.
For %%i in (INDate INTime %Other% %AllDateTimeVars%) do @if defined %%i set %%i|find /i "%%i=" 129.
130.
:cleanUp 131.
For %%i in (vbssnippet INTime INDate %Other% Other) Do Set "%%i=" 132.
goto :eof 133.
134.
:Syntax 135.
ECHO\ 136.
ECHO %~nx0 By Frank / dem Biber aus Bremen 2005 137.
ECHO\ 138.
ECHO Ermittelt strukturierte Informationen über Datum und Zeit 139.
ECHO Angezeigt oder optional in Variablen gesetzt werden: 140.
ECHO %AllDateTimeVars% 141.
ECHO\ 142.
Echo Syntax: 143.
ECHO %~nx0 [Datum] [Zeit] [/s^|/u] [/q] [/?] 144.
ECHO\ 145.
ECHO Datum Datumswert wie vom System oder der Dir-Ausgabe geliefert. 146.
ECHO Default Systemdatum. 147.
ECHO Zeit Zeit wie vom System oder der Dir-Ausgabe geliefert. Default Systemzeit. 148.
ECHO /s SET Setzt die oben genannten Umgebungsvariablen 149.
ECHO /u UNSET Löscht die gesetzten Umgebungsvariablen 150.
ECHO /q QUIET Unterdrückt die Bildschirmanzeige der ermittelten Werte 151.
ECHO\/^? Zeigt diese schöne Hilfe 152.
Goto :eof 153.
::-------snapp GetAllDateTimeInfos.cmd01.
GetAllDateTimeInfos /? 02.
03.
GetAllDateTimeInfos.bat By Frank / dem Biber aus Bremen 2005 04.
05.
Ermittelt strukturierte Informationen über Datum und Zeit 06.
Angezeigt oder optional in Variablen gesetzt werden: 07.
DateOrder KW OSKW DoW DoY cDoW DD TT MM JJ YY hh min ss ms 08.
09.
Syntax: 10.
GetAllDateTimeInfos.bat [Datum] [Zeit] [/s|/u] [/q] [/?] 11.
12.
Datum Datumswert wie vom System oder der Dir-Ausgabe geliefert. 13.
Default Systemdatum. 14.
Zeit Zeit wie vom System oder der Dir-Ausgabe geliefert. Default Systemzeit 15.
/s SET Setzt die oben genannten Umgebungsvariablen 16.
/u UNSET Löscht die gesetzten Umgebungsvariablen 17.
/q QUIET Unterdrückt die Bildschirmanzeige der ermittelten Werte 18.
/? Zeigt diese schöne Hilfe 19.
20.
>GetAllDateTimeInfos 01.10.2005 12:33:44 21.
INDate=01.10.2005 22.
INTime=12:33:44 23.
DateOrder=TT-MM-JJ 24.
KW=39 25.
OSKW=40 26.
DoW=7 27.
DoY=274 28.
cDoW=Sa 29.
DD=01 30.
TT=01 31.
MM=10 32.
JJ=2005 33.
YY=2005 34.
hh=12 35.
min=33 36.
ss=44 37.
ms=00 38.
39.
>GetAllDateTimeInfos 01.11.2002 00:00:44 40.
INDate=01.11.2002 41.
INTime=00:00:44 42.
DateOrder=TT-MM-JJ 43.
KW=44 44.
OSKW=44 45.
DoW=6 46.
DoY=305 47.
cDoW=Fr 48.
DD=01 49.
TT=01 50.
MM=11 51.
JJ=2002 52.
YY=2002 53.
hh=00 54.
min=00 55.
ss=44 56.
ms=00 57.
58.
(---hier mal ein zweistelliges Datum aus dem letztem Jahrhundert--) 59.
>GetAllDateTimeInfos 01.04.99 12:47 60.
INDate=01.04.99 61.
INTime=12:47 62.
DateOrder=TT-MM-JJ 63.
KW=13 64.
OSKW=14 65.
DoW=5 66.
DoY=91 67.
cDoW=Do 68.
DD=01 69.
TT=01 70.
MM=04 71.
JJ=1999 72.
YY=1999 73.
hh=12 74.
min=47 75.
ss=00 76.
ms=00 77.
78.
>GetAllDateTimeInfos 01.11.2002 00:00:44 /q /s 79.
(keine Bildschirmausgabe, aber alle Variablen sind gesetzt) 80.
81.
>GetAllDateTimeInfos /u 82.
(keine Bildschirmausgabe, und alle Variablen sind gelöscht) 83.
84.
>GetAllDateTimeInfos 85.
INDate=03.10.2005 86.
INTime= 6:43:02,31 87.
DateOrder=TT-MM-JJ 88.
KW=40 89.
OSKW=41 90.
DoW=2 91.
DoY=276 92.
cDoW=Mo 93.
DD=03 94.
TT=03 95.
MM=10 96.
JJ=2005 97.
YY=2005 98.
hh=06 99.
min=43 100.
ss=02 101.
ms=31 102.
103.
>GetAllDateTimeInfos /q 104.
(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.
01.
Call GetAllDateTimeInfos /s 02.
(alle Variablen sind gesetzt) 03.
set logfilename=%JJ%-%MM%-%TT%_%hh%$%min%.log 04.
Call GetAllDateTimeInfos /u 05.
..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.)
01.
>for %i in (d:\temp\*.vbs) do @for /f "tokens=2 delims==" %a in ('GetAllDateTimeInfos.bat %~ti^|find "DoY"')do @echo ren %~dpnxi %a_%~nxi 02.
ren d:\temp\Getips.vbs 223_Getips.vbs 03.
ren d:\temp\TemplatesPath.vbs 225_TemplatesPath.vbs 04.
ren d:\temp\TemplatesPathHf.vbs 225_TemplatesPathHf.vbs 05.
ren d:\temp\SpecialFolders.vbs 225_SpecialFolders.vbs 06.
ren d:\temp\TemplatesPathHffull.vbs 225_TemplatesPathHffull.vbs 07.
ren d:\temp\Run BatchHiddenwith.Vbs 227_Run BatchHiddenwith.Vbs 08.
ren d:\temp\MonatsOrdnerAnlegen.vbs 246_MonatsOrdnerAnlegen.vbs 09.
ren d:\temp\ListLocalUsers.vbs 259_ListLocalUsers.vbsKeep 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
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
Biber schreibt am 19.10.2005 um 15:59:01 Uhr
Ich wurde gerade darauf aufmerksam gemacht, dass mein Englisch vielleicht doch nicht so gut ist, wie ich immer gehofft habe. Ich werde also eventuelle weitere Teile meiner kleinen Reihe wieder auf Deutsch übertiteln.
Das nächste Tutorial heißt dann also statt "Batch for Runaways Part IV" wieder allgemein verständlich "Stapel für Fortgeschrittene Teil IV".
Danke für die Rückmeldung @Engelstaub
Biber
Das nächste Tutorial heißt dann also statt "Batch for Runaways Part IV" wieder allgemein verständlich "Stapel für Fortgeschrittene Teil IV".
Danke für die Rückmeldung @Engelstaub
Biber
Biber schreibt am 14.12.2005 um 18:24:46 Uhr
Moin alle,
ich wurde in einem anderen Thread darauf hingewiesen, dass die oben gepostete Version des Beispiel-Batches "GetAllDateTimeInfos.bat" Version 0.01 nicht robust genug für ein Copy & Paste ist, wenn ich mich aus Versehen an die dokumentierte M$-Syntax halte. (wird nicht wieder vorkommen, sorry... *fg)
Der Fehler liegt bei mir bzw. in folgenden Blöckchen (dokumentierte MS-Syntax):
... ...(in den endlosen Weiten des GetAllDateTimeInfo.Bat 0.01).....
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%
...
Da sollten, damit der Sinn auch nach dem Cut & Paste erhalten bleibt, alle "SET"-Anweisungen auch auf die immer von mir beschworene undokumentierte Art in Anführungszeichen gesetzt werden.
Also so:
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%"
Das war das Problem. In meinem Original-Batch waren natürlich keine trailing blanks am Ende der "If defined"-Zeilen.
Beim Cut & Paste kommen aber offensichtlich wieder welche rein bzw können reinkommen.
Hoffe nicht, dass weiterhin in so kurzen Abständen Bugs gemeldet werden...
!!! Ist oben im Tutorial korrigiert !!!
Danke an f.e.dorr für die Rückmeldung!!
Grüße Biber
[Edit 3.2.2006]
Bugfix des Bugfixes vom 14.12.2005
Nun waren Anführungszeichen beim Setzen von TT, MM, HH an der falschen Stelle. Sorry.
[/Edit]
ich wurde in einem anderen Thread darauf hingewiesen, dass die oben gepostete Version des Beispiel-Batches "GetAllDateTimeInfos.bat" Version 0.01 nicht robust genug für ein Copy & Paste ist, wenn ich mich aus Versehen an die dokumentierte M$-Syntax halte. (wird nicht wieder vorkommen, sorry... *fg)
Der Fehler liegt bei mir bzw. in folgenden Blöckchen (dokumentierte MS-Syntax):
... ...(in den endlosen Weiten des GetAllDateTimeInfo.Bat 0.01).....
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%
...
Da sollten, damit der Sinn auch nach dem Cut & Paste erhalten bleibt, alle "SET"-Anweisungen auch auf die immer von mir beschworene undokumentierte Art in Anführungszeichen gesetzt werden.
Also so:
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%"
Das war das Problem. In meinem Original-Batch waren natürlich keine trailing blanks am Ende der "If defined"-Zeilen.
Beim Cut & Paste kommen aber offensichtlich wieder welche rein bzw können reinkommen.
Hoffe nicht, dass weiterhin in so kurzen Abständen Bugs gemeldet werden...
!!! Ist oben im Tutorial korrigiert !!!
Danke an f.e.dorr für die Rückmeldung!!
Grüße Biber
[Edit 3.2.2006]
Bugfix des Bugfixes vom 14.12.2005
Nun waren Anführungszeichen beim Setzen von TT, MM, HH an der falschen Stelle. Sorry.
[/Edit]
cat1510 schreibt am 06.02.2006 um 18:50:02 Uhr
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
Biber schreibt am 06.02.2006 um 21:28:27 Uhr
Na, vielen Dank Cat1510,
endlich mal jemand, der mein Tutorial etwas genauer liest...
Gerade rechtzeitig - am Wochenende war ich so gefrustet, weil ein anderer User im Bereich "Batch & Shell" gepostet hatte, er würde kein Wort in meinem Tutorial verstehen.. da wollte ich schon die Brocken hinschmeißen (im Moment wird ziemlich nachdrücklich von zwei Mitgliedern ein Generationenwechsel eingefordert, das wäre der zweite Grund).
Aber bis zur endgültigen Beantwortung Deiner frage bleib ich noch.. *g
Ich hatte es ja damals im Tutorial schon geschrieben: ich habe keinen vorgesehenen Weg gefunden, in Windows eine "lange" Datumsanzeige zu erreichen/zu erzwingen.
Über den Klicki-Bunti-Weg ("Start"-"Einstellungen"-"Systemsteuerung"->"Regions- und Sprachoptionen") lassen sich zwar sowohl "kurze Datumsformate" ("06.02.2006" und Variationen) wie auch "lange Datumsformate" ("Mo, 06. Februar 2006" und Varianten) einstellen.
Aber angezeigt wird immer das "kurze Datum". Egal, welches Format ich für das "lange Datumsformat" nehme.
Nach "legaler" Bearbeitung über die GUI sieht es in der Registry ungefähr so aus:
[HKEY_CURRENT_USER\Control Panel\International]
"sShortDate"="dd.MM.yyyy"
"sDate"="."
"iDate"="1"
"sLongDate"="ddd, dd. MMM yyyy"
...nur nach "Registry-Hacking", also brutales Überschreiben des sShortDate mit dem Wert von sLongDate bekomme ich sowas hin:
[HKEY_CURRENT_USER\Control Panel\International]
"sShortDate"="ddd, dd. MMM yyyy"
"sDate"="."
"iDate"="1"
"sLongDate"="ddd, dd. MMM yyyy"
Über die GUI darf ich das gar nicht...
Hab ich natürlich damals auch gemacht... und ganz schnell wieder zurückgedreht, als ich bemerkt habe, dass sich bei mir diverse Excel-Dateien (mit Makros; Zeiterfassungssysteme etc.) nicht mehr öffnen ließen. Bei M$ schlägt öffensichtlich ein Datumsanzeigeformat bis auf hinterlegte Office-Datums-Berechnungsformeln durch..
*kopfschüttel* *kopfschüttel* *kopfschüttel*
Na ja... wegen dieser Seiteneffekte hab ich es ganz schnell wieder begradigt.
Aber ich will ja Deiner Frage nicht ewig ausweichen: wenn am CMD-Prompt tatsächlich ein "langes Datumsformat" zurückkommen könnte (ich meine ohne Registry-Vergewaltigung), dann wäre es ein Haufen Mehrarbeit, diese Fälle abzufangen.
Denn: ein langes Datumsformat könnte sein:
"ddd, dd. MMM yyyy" ------->Anzeige: Mo, 06.Jan 2006
"dddd, d. MMMM yyyy" ----->Anzeige: Montag, 6. Januar 2006
"ddd, dd. MMMM yyyy" ----->Anzeige: Mo, 06.Januar 2006
...usw. usw.., Spiel ohne Grenzen..
Nicht zu vergessen die
- Variationen mit Wochentags- und Monatsnamen in anderen Sprachen
- und, absolut lumpig, die nicht herleitbaren Abkürzungen ("Januar"=="Jan";"Februar"=="Feb"; "März"=="Mrz" ??!?)
Für diese im Deutschen noch denkbaren drei Beispiel-Fälle eines Langdatums kann ich relativ schnell noch eine kleine Ergänzung liefern.
Für Tages- und Monatsnamen auf Englisch, Französisch, Spanisch etc bitte ich Interessierte, es selber auszutüfteln.
(Ist natürlich ein Scherz - ich würde dann naturlich das Datum komplett über vorhandene Datumsfunktionen in VB- oder JScript ermitteln..)
Aber nur aus sportlichen Gründen
In einem geänderten Batch muss ergänzt/ersetzt werden:
Ergebnis:
Schönen Abend
Biber
endlich mal jemand, der mein Tutorial etwas genauer liest...
Gerade rechtzeitig - am Wochenende war ich so gefrustet, weil ein anderer User im Bereich "Batch & Shell" gepostet hatte, er würde kein Wort in meinem Tutorial verstehen.. da wollte ich schon die Brocken hinschmeißen (im Moment wird ziemlich nachdrücklich von zwei Mitgliedern ein Generationenwechsel eingefordert, das wäre der zweite Grund).
Aber bis zur endgültigen Beantwortung Deiner frage bleib ich noch.. *g
Ich hatte es ja damals im Tutorial schon geschrieben: ich habe keinen vorgesehenen Weg gefunden, in Windows eine "lange" Datumsanzeige zu erreichen/zu erzwingen.
Über den Klicki-Bunti-Weg ("Start"-"Einstellungen"-"Systemsteuerung"->"Regions- und Sprachoptionen") lassen sich zwar sowohl "kurze Datumsformate" ("06.02.2006" und Variationen) wie auch "lange Datumsformate" ("Mo, 06. Februar 2006" und Varianten) einstellen.
Aber angezeigt wird immer das "kurze Datum". Egal, welches Format ich für das "lange Datumsformat" nehme.
Nach "legaler" Bearbeitung über die GUI sieht es in der Registry ungefähr so aus:
[HKEY_CURRENT_USER\Control Panel\International]
"sShortDate"="dd.MM.yyyy"
"sDate"="."
"iDate"="1"
"sLongDate"="ddd, dd. MMM yyyy"
...nur nach "Registry-Hacking", also brutales Überschreiben des sShortDate mit dem Wert von sLongDate bekomme ich sowas hin:
[HKEY_CURRENT_USER\Control Panel\International]
"sShortDate"="ddd, dd. MMM yyyy"
"sDate"="."
"iDate"="1"
"sLongDate"="ddd, dd. MMM yyyy"
Über die GUI darf ich das gar nicht...
Hab ich natürlich damals auch gemacht... und ganz schnell wieder zurückgedreht, als ich bemerkt habe, dass sich bei mir diverse Excel-Dateien (mit Makros; Zeiterfassungssysteme etc.) nicht mehr öffnen ließen. Bei M$ schlägt öffensichtlich ein Datumsanzeigeformat bis auf hinterlegte Office-Datums-Berechnungsformeln durch..
*kopfschüttel* *kopfschüttel* *kopfschüttel*
Na ja... wegen dieser Seiteneffekte hab ich es ganz schnell wieder begradigt.
Aber ich will ja Deiner Frage nicht ewig ausweichen: wenn am CMD-Prompt tatsächlich ein "langes Datumsformat" zurückkommen könnte (ich meine ohne Registry-Vergewaltigung), dann wäre es ein Haufen Mehrarbeit, diese Fälle abzufangen.
Denn: ein langes Datumsformat könnte sein:
"ddd, dd. MMM yyyy" ------->Anzeige: Mo, 06.Jan 2006
"dddd, d. MMMM yyyy" ----->Anzeige: Montag, 6. Januar 2006
"ddd, dd. MMMM yyyy" ----->Anzeige: Mo, 06.Januar 2006
...usw. usw.., Spiel ohne Grenzen..
Nicht zu vergessen die
- Variationen mit Wochentags- und Monatsnamen in anderen Sprachen
- und, absolut lumpig, die nicht herleitbaren Abkürzungen ("Januar"=="Jan";"Februar"=="Feb"; "März"=="Mrz" ??!?)
Für diese im Deutschen noch denkbaren drei Beispiel-Fälle eines Langdatums kann ich relativ schnell noch eine kleine Ergänzung liefern.
Für Tages- und Monatsnamen auf Englisch, Französisch, Spanisch etc bitte ich Interessierte, es selber auszutüfteln.
(Ist natürlich ein Scherz - ich würde dann naturlich das Datum komplett über vorhandene Datumsfunktionen in VB- oder JScript ermitteln..)
Aber nur aus sportlichen Gründen
In einem geänderten Batch muss ergänzt/ersetzt werden:
01.
::..... 02.
If NOT [%1]==[] If /i [%1] NEQ [/q] If /i [%1] NEQ [/s] set "INDate=%1" 03.
If NOT [%2]==[] If /i [%2] NEQ [/q] If /i [%2] NEQ [/s] set "INTime=%2" 04.
05.
:: Die nächste Code-Zeile ändert nur dann etwas, wenn ein Wochentag mitgeliefert wird. 06.
:: Aus "Sa 01.10.2005" wird dann "01.10.2005" ##red| 07.
REM FOR /F "tokens=2" %%i in ("%INDate%") do Set INDate=%%i 08.
FOR /F "delims=, tokens=2" %%i in ("%INDate%") do Set "INDate=%%i" 09.
REM 10.
REM Echo Wochentag und Komma von [%date%] sind entfernt.. [%Indate%] 11.
(echo "%INDate%"|find " ">nul)|| goto NoSpacesInDate 12.
Set "Indate=%Indate: =%" 13.
Set "Indate=%INDate:Januar=.01.%" 14.
Set "Indate=%INDate:Februar=.02.%" 15.
Set "Indate=%INDate:März=.03.%" 16.
Set "Indate=%INDate:April=.04.%" 17.
Set "Indate=%INDate:Mai=.05.%" 18.
Set "Indate=%INDate:Juni=.06.%" 19.
Set "Indate=%INDate:Juli=.07.%" 20.
Set "Indate=%INDate:August=.08%" 21.
Set "Indate=%INDate:September=.09.%" 22.
Set "Indate=%INDate:Oktober=.10.%" 23.
Set "Indate=%INDate:November=.11.%" 24.
Set "Indate=%INDate:Dezember=.12.%" 25.
26.
Set "Indate=%INDate:Jan=.01.%" 27.
Set "Indate=%INDate:Feb=.02.%" 28.
Set "Indate=%INDate:Mrz=.03.%" 29.
Set "Indate=%INDate:Apr=.04.%" 30.
Set "Indate=%INDate:Mai=.05.%" 31.
Set "Indate=%INDate:Jun=.06.%" 32.
Set "Indate=%INDate:Jul=.07.%" 33.
Set "Indate=%INDate:Aug=.08%" 34.
Set "Indate=%INDate:Sep=.09.%" 35.
Set "Indate=%INDate:Okt=.10.%" 36.
Set "Indate=%INDate:Nov=.11.%" 37.
Set "Indate=%INDate:Dez=.12.%" 38.
Set "Indate=%Indate:..=.%" 39.
40.
:NoSpacesInDate ## 41.
REM ab hier alles unverändert. 42.
FOR /F "tokens=1-7 del............. 43.
......Ergebnis:
01.
>date /t 02.
Mo, 06. Feb 2006 03.
04.
<=21:26:43 C:\Dokumente und Einstellungen\Biber=> 05.
>e:\GetAllDateTimeInfos.bat 06.
INDate=06.02.2006 07.
INTime=21:26:46,80 08.
DateOrder=TT-MM-JJ 09.
KW=6 10.
OSKW=2 11.
DoW=37 12.
DD=06 13.
TT=06 14.
MM=02 15.
JJ=2006 16.
YY=2006 17.
hh=21 18.
min=26 19.
ss=46 20.
ms=80Biber
cat1510 schreibt am 06.02.2006 um 22:15:52 Uhr
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 schreibt am 07.02.2006 um 13:53:01 Uhr
So, CAT,
ich habe recherchiert.
Mit dieser lustigen "Parameter 2 bis 5-Auswahl" in der Zeile, in der der VBS-Schnipsel aufgerufen wird:
... wollte ich eigentlich einen W2K-Bug umgehen... da wird in der ersten Zeile einer Ausgabe ein Steuerzeichen (FormFeed/Seitenvorschub, ^L) mitgeliefert.
Und dieses erste Zeichen habe ich übersprungen. Passt natürlich nicht mehr bei den Versionen, bei denen M$ diesen Bug gefixt hat.
Habe es grad unter XP SP2 probiert, da hilft mir der Bugfix nix.
Richtige Syntax für beide Win-Versionen (bau ich auch im Tutorial ein):
BESSER:
[[Delims ist das Zeichen für weiblich gefolgt von einem Leerzeichen. Siehe im Tut. und das P.S.]]
HTH Biber
[Edit] P.S.
Ich glaube, der Obertroll hat doch recht.. ich bin irgendwie zu blöd.. *gg
Ich bekomme es hier unten im Kommentar nicht hin, das richtige Delimiterzeichen hier anzuzeigen. Richtig wäre das Zeichen für "weiblich" == chr(012) ==^L .
Sobald ich das hier eintippe, werden alle Umlaute umcodiert und auch das Zeichen "weiblich" selbst erscheint nicht -statt dessen zwei Buchstaben aus einem anderen Zeichensatz.
Oben im Beitrag selbst erscheint es "richtig", auch Umlaute bleiben oben erhalten.
Falls jemand weiß, wie ich dieses Formatierungsproblem in den Griff bekomme, bitte posten.
Danke.
[/Edit]
ich habe recherchiert.
Mit dieser lustigen "Parameter 2 bis 5-Auswahl" in der Zeile, in der der VBS-Schnipsel aufgerufen wird:
01.
BUGGY: for /F "tokens=2-5" %%a in ('cscript //nologo %vbsSnippet% %INDate%') do ( Und dieses erste Zeichen habe ich übersprungen. Passt natürlich nicht mehr bei den Versionen, bei denen M$ diesen Bug gefixt hat.
Habe es grad unter XP SP2 probiert, da hilft mir der Bugfix nix.
Richtige Syntax für beide Win-Versionen (bau ich auch im Tutorial ein):
BESSER:
01.
for /F "delims=^L tokens=1-4" %%a in ('cscript //nologo %vbsnippet.vbs% %InDate%') do (HTH Biber
[Edit] P.S.
Ich glaube, der Obertroll hat doch recht.. ich bin irgendwie zu blöd.. *gg
Ich bekomme es hier unten im Kommentar nicht hin, das richtige Delimiterzeichen hier anzuzeigen. Richtig wäre das Zeichen für "weiblich" == chr(012) ==^L .
Sobald ich das hier eintippe, werden alle Umlaute umcodiert und auch das Zeichen "weiblich" selbst erscheint nicht -statt dessen zwei Buchstaben aus einem anderen Zeichensatz.
Oben im Beitrag selbst erscheint es "richtig", auch Umlaute bleiben oben erhalten.
Falls jemand weiß, wie ich dieses Formatierungsproblem in den Griff bekomme, bitte posten.
Danke.
[/Edit]
Biber schreibt am 11.02.2006 um 22:41:19 Uhr
...weil sie nicht hilfreich für Dein Problem waren???
Irgendwann erwisch ich Dich auf frischer Tat, Du Möchtegern-TopUser.
So, was ich eigentlich wollte... ich hatte rausgefunden, wie ich das Zeichen für "weiblich" in HTML-Nomenklatur schreiben kann, sonst hätte ich gar nicht hier reingeschaut...
Aber das teste ich wenigstens, ob das klappt:
for /F "tokens=1-4 delims=♀" ..... sollte das Zeichen für weiblich bringen.. geschrieben habe ich
for /F "tokens=1-4 delims=&_#_9792_;" ....ohne Unterstriche... nur zur Verdeutlichung.
Und ich habe einen besseren Workaround für den genannten W2K-Bug gefunden und oben im Tutorial eingebaut.
(ich nehme jetzt im VBSSnippet Kommata als Trennzeichen für die Output... da ist es mir egal, ob das erste Zeichen ein FormFeed ist.
Manno, bin ich jetzt stinkig wegen dieses Trolls....so stinkig... und traurig
Biber
[Edit] 12.02.2006
So um keinen weiteren Kommentar und keine neue Angriffsfläche für eine Minusbewertung zu bieten, editier ich den vorhandenen Kommentar.
Habe einen weiteren M$-Bug abgefangen und zwei Sourcecode-Zeilen geändert.
Aktuelle Version ist jetzt v0.06. Danke an die User Cat1510 und superfrog für das Bugtracking und die hilfreichen Rückmeldungen.
Wegen Benutzern wie Euch bin ich gerne hier!
[/Edit]
superfrog schreibt am 12.02.2006 um 19:43:16 Uhr
@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
cat1510 schreibt am 13.02.2006 um 15:15:31 Uhr
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/S ...
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/S ...
MFG
CAT
Biber schreibt am 13.02.2006 um 19:15:54 Uhr
Danke, CAT,
für die Blumen - ich muss allerdings auch sagen, so eine Art von Dialog, wie ich ihn die letzten Tage mit superfrog und Dir geführt habe, finde ich um Welten besser als die sinnfreie Chatterei, die wir im Forum in den letzten zwei Monaten so oft hatten.
Hier (in diesem unbedeutenden Seitenarm des Forums *gg) war für mich wieder etwas von dem ursprünglichen community-Gedanken, dem gemeinsamen (Weiter-)Entwickeln und Verbessern von Lösungen spürbar. Hat mir gut getan.
Zu den WinScript XP 3.0 Sachen....hmm ja... nicht schlecht, aber...
In dieser Beziehung gehöre ich doch eher zu den Batch-Puristen. Ich setze ja meistens dann Batches ein, wenn ich keine Dialoge und keine Aktivitäten mit XP-konformen abgerundeten Ecken sehen will. Batches sind für mich das Werkzeug, um still und unauffällig im Hintergrund zu arbeiten - schlimmstenfalls eine Fehlerzeile in ein Logfile zu schreiben.
Und mich eben nicht vor meinem ersten Kaffee schon mit Fragen zu belästigen wie "Sind Sie sicher, dass Sie die Datei löschen wollen?" oder mir ein Fenster hochzupoppen mit "Sicherung wurde ohne Fehler durchgeführt. Laufzeit 2 min 13sek. Drücken Sie OK, wenn Sie das wissen wollten."
Und der zweite Grund, weshalb mir Batches so lieb sind... ich kann mir auf jedem Rechner schnell was zusammenschroten... brauche keine installierten Komponenten und registrierte *.DLLs... nur eine Tastatur und einen Editor.
Aber das sind persönliche Vorlieben... grundsätzlich kommt es immer auf die Aufgabe für die Auswahl der Werkzeuge an... und es kann auch sinnvoll sein, solche GUI-Komponenten zu nutzen.
@All wg. v006a
ich habe noch ein paar Zeilen nachdokumentiert und noch zwei übersehene [SET var=Wert]-Anweisungen in Anführungszeichen gesetzt.
Durch das Copy & Pasten des Batches aus dem Artikel oben hatte ich plötzlich bei mir trailing blanks und Fehler im Sourcecode...deshalb habe ich (wo nötig) jetzt ersetzt:
ALT: Set var=wert
NEU: Set "var=wert"
Hintergrund: An einer Stelle wurde meine gewollte Zeile:
Set %%i=
....wegen eines Leerzeichens am Ende interpretiert als
Set %%i=_ (als ein Leerzeichen).
Und so etwas ist natürlich ein fast nicht zu findender Fehler.
Schönen Abend noch
Grüße Biber
für die Blumen - ich muss allerdings auch sagen, so eine Art von Dialog, wie ich ihn die letzten Tage mit superfrog und Dir geführt habe, finde ich um Welten besser als die sinnfreie Chatterei, die wir im Forum in den letzten zwei Monaten so oft hatten.
Hier (in diesem unbedeutenden Seitenarm des Forums *gg) war für mich wieder etwas von dem ursprünglichen community-Gedanken, dem gemeinsamen (Weiter-)Entwickeln und Verbessern von Lösungen spürbar. Hat mir gut getan.
Zu den WinScript XP 3.0 Sachen....hmm ja... nicht schlecht, aber...
In dieser Beziehung gehöre ich doch eher zu den Batch-Puristen. Ich setze ja meistens dann Batches ein, wenn ich keine Dialoge und keine Aktivitäten mit XP-konformen abgerundeten Ecken sehen will. Batches sind für mich das Werkzeug, um still und unauffällig im Hintergrund zu arbeiten - schlimmstenfalls eine Fehlerzeile in ein Logfile zu schreiben.
Und mich eben nicht vor meinem ersten Kaffee schon mit Fragen zu belästigen wie "Sind Sie sicher, dass Sie die Datei löschen wollen?" oder mir ein Fenster hochzupoppen mit "Sicherung wurde ohne Fehler durchgeführt. Laufzeit 2 min 13sek. Drücken Sie OK, wenn Sie das wissen wollten."
Und der zweite Grund, weshalb mir Batches so lieb sind... ich kann mir auf jedem Rechner schnell was zusammenschroten... brauche keine installierten Komponenten und registrierte *.DLLs... nur eine Tastatur und einen Editor.
Aber das sind persönliche Vorlieben... grundsätzlich kommt es immer auf die Aufgabe für die Auswahl der Werkzeuge an... und es kann auch sinnvoll sein, solche GUI-Komponenten zu nutzen.
@All wg. v006a
ich habe noch ein paar Zeilen nachdokumentiert und noch zwei übersehene [SET var=Wert]-Anweisungen in Anführungszeichen gesetzt.
Durch das Copy & Pasten des Batches aus dem Artikel oben hatte ich plötzlich bei mir trailing blanks und Fehler im Sourcecode...deshalb habe ich (wo nötig) jetzt ersetzt:
ALT: Set var=wert
NEU: Set "var=wert"
Hintergrund: An einer Stelle wurde meine gewollte Zeile:
Set %%i=
....wegen eines Leerzeichens am Ende interpretiert als
Set %%i=_ (als ein Leerzeichen).
Und so etwas ist natürlich ein fast nicht zu findender Fehler.
Schönen Abend noch
Grüße Biber
superfrog schreibt am 13.02.2006 um 23:59:55 Uhr
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
Biber schreibt am 14.02.2006 um 09:36:36 Uhr
Hallo superfrog,
merkwürdig, ich habe mit sicherheitshalber noch mal die Version, die ich Dir gemailt habe bei mir (Win XP Pro SP29 laufen lassen.
Ich habe den Effekt nicht. *ratlos guck*
::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%" --------->Tippfehler
::IF defined hh Set "hh=10%hh%"
Doch. Dann machen wir das so.. denn diese FOR..Zeile hat ja den gleichen Effekt wie die 4 Einzelzeilen OHNE DelayedExpansion.
Stimmt...das war einer meiner üblichen Tippfehler.
Ja, da hast Du recht. Ändere ich oben.
Ich versuche mal den Fehler zu reproduzieren bei mir (aber ändere oben erstmal nichts im Tut.)
Bei mir läuft es..
Bei Dir: mach es ohne "EnableDelayedExpansion"
a) die erste Zeile ändern in "@echo off & setlocal"
b) statt der FOR..IN..DO-Anweisung die aufgelösten 4 (tippfehlerbereinigten) Zeilen.
Solche nicht-reproduzierbaren Bugs liebe ich... *ggg
nette Grüße zurück
Biber
leider hat sich an meinem Problem mit der neuen (zugemailten) Version nichts geändert.
Ich kriege damit immer noch diese Ausgabe:
Ich kriege damit immer noch diese Ausgabe:
merkwürdig, ich habe mit sicherheitshalber noch mal die Version, die ich Dir gemailt habe bei mir (Win XP Pro SP29 laufen lassen.
Ich habe den Effekt nicht. *ratlos guck*
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.
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.
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%" --------->Tippfehler
::IF defined hh Set "hh=10%hh%"
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.
In der 4. Zeile vermute ich, meintest du aber warscheinlich hh, nicht DD.
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.
Könnte ne Fehlerquelle für andere sein.
Ja, da hast Du recht. Ändere ich oben.
Ich versuche mal den Fehler zu reproduzieren bei mir (aber ändere oben erstmal nichts im Tut.)
Bei mir läuft es..
Bei Dir: mach es ohne "EnableDelayedExpansion"
a) die erste Zeile ändern in "@echo off & setlocal"
b) statt der FOR..IN..DO-Anweisung die aufgelösten 4 (tippfehlerbereinigten) Zeilen.
Solche nicht-reproduzierbaren Bugs liebe ich... *ggg
nette Grüße zurück
Biber
Biber schreibt am 14.02.2006 um 11:35:15 Uhr
@superfrog
Hat doch alles eine logische Erklärung... war mein Fehler
Da ich ja nicht davor zurückschrecke, auch weniger dokumentierte Einstellungen und Schalter zu verwenden, habe ich bei mir ein paar Grundeinstellungen für die CMD-Umgebung in die Registry eingetragen.
Sieht bei mir so aus:
>reg query "HKEY_CURRENT_USER\Software\Microsoft\Command Processor"
! REG.EXE VERSION 3.0
HKEY_CURRENT_USER\Software\Microsoft\Command Processor
CompletionChar REG_DWORD 0x9
DefaultColor REG_DWORD 0x74
PathCompletionChar REG_DWORD 0x9
DisableUNCCheck REG_DWORD 0x1
EnableExtensions REG_DWORD 0x1
DelayedExpansion REG_DWORD 0x1
Der zweite (nicht oder kaum dokumentierte) fette Eintrag bewirkt bei mir, dass die DelayedExpansion, die verzögerte Variablenauflösung standardmäßig aktiviert ist.
Bei "Auslieferung ab Werk" ist das auf Windowsrechnern nicht so.
Also, wie immer im Leben zwei Möglichkeiten für Dich
a) entweder den Batch OHNE "EnableDelayedExpansion" laufen lassen (denn mit den Schaltern /u und /s wird ja wieder auf den Standardzustand zurückgesetzt). Und der ist bei Dir "DisableDelayedExpansion"...
Daher bleibt Dir nur der Weg der vier Zeilen statt der einen FOR-Zeile...
IF defined DD Set "DD=10%DD%"
IF defined TT Set "TT=10%TT%"
....
b) oder die beiden fett gedruckten Registry-Einträge übernehmen für Deinen USER oder für den ganzen Rechner
(=HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor)
Aus Kompatibilitätsgründen, wenn Du den Batch auf verschiedenen, "unbekannten" Rechnern einsetzen willst, empfehle ich die Variante a)
Die Variante b), DelayedExpansion als Default zu setzen, ist halt undokumentiert und, wie eben bewiesen, macht die Benutzung solcher undocumented features nur Ärger...
Grüße
Frank / der Biber aus Bremen
[Edit 14.2.2006]
Habe es oben in der Tut-Version auf die "kompatible Version" zurückgedreht.
Sollte jetzt (v006b) also auf jedem W2K++-Rechner laufen.
Aber das habe ich auch schon bei der v001 gedacht *gg.
[/Edit]
Hat doch alles eine logische Erklärung... war mein Fehler
Da ich ja nicht davor zurückschrecke, auch weniger dokumentierte Einstellungen und Schalter zu verwenden, habe ich bei mir ein paar Grundeinstellungen für die CMD-Umgebung in die Registry eingetragen.
Sieht bei mir so aus:
>reg query "HKEY_CURRENT_USER\Software\Microsoft\Command Processor"
! REG.EXE VERSION 3.0
HKEY_CURRENT_USER\Software\Microsoft\Command Processor
CompletionChar REG_DWORD 0x9
DefaultColor REG_DWORD 0x74
PathCompletionChar REG_DWORD 0x9
DisableUNCCheck REG_DWORD 0x1
EnableExtensions REG_DWORD 0x1
DelayedExpansion REG_DWORD 0x1
Der zweite (nicht oder kaum dokumentierte) fette Eintrag bewirkt bei mir, dass die DelayedExpansion, die verzögerte Variablenauflösung standardmäßig aktiviert ist.
Bei "Auslieferung ab Werk" ist das auf Windowsrechnern nicht so.
Also, wie immer im Leben zwei Möglichkeiten für Dich
a) entweder den Batch OHNE "EnableDelayedExpansion" laufen lassen (denn mit den Schaltern /u und /s wird ja wieder auf den Standardzustand zurückgesetzt). Und der ist bei Dir "DisableDelayedExpansion"...
Daher bleibt Dir nur der Weg der vier Zeilen statt der einen FOR-Zeile...
IF defined DD Set "DD=10%DD%"
IF defined TT Set "TT=10%TT%"
....
b) oder die beiden fett gedruckten Registry-Einträge übernehmen für Deinen USER oder für den ganzen Rechner
(=HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor)
Aus Kompatibilitätsgründen, wenn Du den Batch auf verschiedenen, "unbekannten" Rechnern einsetzen willst, empfehle ich die Variante a)
Die Variante b), DelayedExpansion als Default zu setzen, ist halt undokumentiert und, wie eben bewiesen, macht die Benutzung solcher undocumented features nur Ärger...
Grüße
Frank / der Biber aus Bremen
[Edit 14.2.2006]
Habe es oben in der Tut-Version auf die "kompatible Version" zurückgedreht.
Sollte jetzt (v006b) also auf jedem W2K++-Rechner laufen.
Aber das habe ich auch schon bei der v001 gedacht *gg.
[/Edit]
superfrog schreibt am 14.02.2006 um 14:05:50 Uhr
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
as-net schreibt am 17.02.2006 um 12:05:19 Uhr
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 schreibt am 17.02.2006 um 13:04:23 Uhr
@as-net
Mea culpa, mea culpa, Andreas...
Tippfehler...
Vorhin stand oben:
Sorry für den Stress und ich mach das nicht, um diesen Beitrag am Leben zu erhalten... war pure Dussligkeit..
Schönes Wochenende
Biber
-------- Aktuelles Ergebnis mit dem Copy & Paste von oben:
>h:\tmp\v006bGetDatetimeInfos.bat /s
INDate=17.02.2006
INTime=13:06:26,83
DateOrder=TT-MM-JJ
KW=7
OSKW=7
DoW=6
DoY=48
cDow=Fr
DD=17
TT=17
MM=02
JJ=2006
YY=2006
hh=13
min=06
ss=26
ms=83
[Edit]
So, nochmal in Ruhe:
Grund für diese merkwürdige FOR /F..IN.DO-Klausel "tokens=2-5" war ja ein M$-Bug in den frühen W2000-Versionen.
Da kommt vom VB-Schnipsel statt
(Erwartet laut Doku: KW OSKW DoW DoY) = 7 7 6 48
zurück:
(Real Win2000: KW OSKW DoW DoY) =♀7 7 6 48
...also dieses unsägliche FormFeed-Zeichen.
Wenn ich das umgehen will, muss ich schon bei "tokens 2-5" bleiben, ABER einen ersten DUMMY-Wert mit zurückgeben.
Rückgabe VBS neu:
(Win2000: KW OSKW DoW DoY) ♀x,7,7,6,48
(WinXP: KW OSKW DoW DoY) x,7,7,6,48
Deshalb: ich ändere es oben wieder auf "tokens 2-5", ABER führe einen DUMMY-Parameter#1 mit dem Wert "x" ein. Und den ersten Token, egal ob "♀x" oder nur "x" lasse ich außen vor.
Sorry für das Geeiere... jetzt sollte es unter Win2000(first editions) und W2000fixed und WinXP ff laufen... flehend gen Himmel blick
[/Edit]
Mea culpa, mea culpa, Andreas...
Tippfehler...
Vorhin stand oben:
01.
for /F "delims=, tokens=2-5" %%a in ('cscript //nologo %vbsSnippet% %INDate%') do ( 02.
03.
...Jetzt richtig, wie <i>eigentlich</i> auch im vorangegangenen Bugfix verbal beschrieben: 04.
05.
for /F "delims=, tokens=1-4" %%a in ('cscript //nologo %vbsSnippet% %INDate%') do ( Schönes Wochenende
Biber
-------- Aktuelles Ergebnis mit dem Copy & Paste von oben:
>h:\tmp\v006bGetDatetimeInfos.bat /s
INDate=17.02.2006
INTime=13:06:26,83
DateOrder=TT-MM-JJ
KW=7
OSKW=7
DoW=6
DoY=48
cDow=Fr
DD=17
TT=17
MM=02
JJ=2006
YY=2006
hh=13
min=06
ss=26
ms=83
[Edit]
So, nochmal in Ruhe:
Grund für diese merkwürdige FOR /F..IN.DO-Klausel "tokens=2-5" war ja ein M$-Bug in den frühen W2000-Versionen.
Da kommt vom VB-Schnipsel statt
(Erwartet laut Doku: KW OSKW DoW DoY) = 7 7 6 48
zurück:
(Real Win2000: KW OSKW DoW DoY) =♀7 7 6 48
...also dieses unsägliche FormFeed-Zeichen.
Wenn ich das umgehen will, muss ich schon bei "tokens 2-5" bleiben, ABER einen ersten DUMMY-Wert mit zurückgeben.
Rückgabe VBS neu:
(Win2000: KW OSKW DoW DoY) ♀x,7,7,6,48
(WinXP: KW OSKW DoW DoY) x,7,7,6,48
Deshalb: ich ändere es oben wieder auf "tokens 2-5", ABER führe einen DUMMY-Parameter#1 mit dem Wert "x" ein. Und den ersten Token, egal ob "♀x" oder nur "x" lasse ich außen vor.
Sorry für das Geeiere... jetzt sollte es unter Win2000(first editions) und W2000fixed und WinXP ff laufen... flehend gen Himmel blick
[/Edit]
as-net schreibt am 17.02.2006 um 14:29:00 Uhr
Hi Biber,
Yepp, das war es.
Kleiner Fehler, große Wirkung.
Danke für die schnelle Hilfe, und wegen deiner "Dussligkeit"
dank ich dir für das Script, und Fehler können nun mal,
und vor allem in der Heutigen Zeit schnell Passieren.
Ich wünsch dir Ebenfalls ein schönes Wochenende
Gruß
AS-Net
Yepp, das war es.
Kleiner Fehler, große Wirkung.
Danke für die schnelle Hilfe, und wegen deiner "Dussligkeit"
dank ich dir für das Script, und Fehler können nun mal,
und vor allem in der Heutigen Zeit schnell Passieren.
Ich wünsch dir Ebenfalls ein schönes Wochenende
Gruß
AS-Net
perry6 schreibt am 21.04.2007 um 13:25:39 Uhr
@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
Biber schreibt am 22.04.2007 um 17:26:14 Uhr
Moin perry6,
willkommen um Forum und danke für das Auseinandersetzen mit dem Thema.
Mal sehen, ob ich die Unklarheiten ausräumen kann.
Zu Deiner Frage "Wie kann ich erreichen, dass die gesetzten Variablen auch in nachfolgend geöffneten CMD-Sessions verfügbar sind"..
Schlechte Nachricht: Gar nicht.
Gute Nachricht: Ist auch nicht erstrebenswert.
Die Umgebungsvariablen einer CMD-Session gelten grundsätzlich immer nur in einer Session,
d.h. solange das Fenster, in der Batch (oder die Kommandozeilenbefehle) ablaufen nicht geschlossen wird.
Oder exakter gesagt, innerhalb dieser Instanz der CMD.exe.
Anders wäre es aus mehreren Gründen auch nicht handelbar.
Stell Dir vor, jede in einem Batch/jede am CMD-Prompt gesetzte Variable wäre für alle nachfolgend geöffneten CMD-Instanzen gültig.
Du würdest raschelig werden. Sobald Du dann in einem Batch den aktuellen Pfad ändern würdest mit CD,
würden alle nachfolgend CMD/Batchaufrufe sich in diesem Verzeichnis befinden.
Denn die Variable %CD% ("aktuelles Verzeichnis") würde ja für alle gelten.
Wenn Du in einem Batch die Farbenauf gelb auf blau einstellst oder die Variable %logFile% auf "x:\logs\my.log" setzt, würde es für jeden hinterher gestarteten Batch inclusive der im Taskplaner hinterlegten gelten etc etc.
Diese Art von "globalen" Variablen meinte ich nicht - diese wären für mich "sessionübergreifende Systemvariable".
Diese gibt es auch unter Windows - Variable, die für alle CMD-Sessions als Anfangsumgebung gelten werden über die Registry gesteuert (%username%, %computername%, %userprofile% oder,
da M$ ja immer im Laufe der Implementierung Angst vor der eigenen Courage bzw. der eingeschlagenen Programmierstrategie bekommt, zum Teil auch beiläufigt bei DLL-Aufrufen (%APPDATA% durch die shell.dll; %LOGONSERVER%...).
Was dann zu so lustigen Effekten führt wie "%APPDATA% nicht gesetzt" (Hatten wir neulich gerade im Forum).
Was M$ aber nicht tut oder nur SEHR verhalten ist: Variablen zu definieren, die sich zur Laufzeit selbst aktualisieren.
Es existieren einige wenige Variablen, die "dynamischen" Charakter haben, also zu unterschiedlichen Zeiten auch jeweils die Gerade-Jetzt-Werte haben.
Dazu gehören %date%, %time%, %cd% - aber alle Vaariablen, die Du über den Befehl SET angezeigt bekommst, sind statisch.
Bedeutet, die bekommen bei Start des CMD-Inerpreters einen Anfangswert (aus der Registry) und dieser Wert ist eine einmalig erzeugte Kopie der Werte aus der Registry.
Ändert sich höchstens, wenn Du ihn änderst, aber auch dann hättest Du nur den Wert der Kopie geämdert.
Das würde zwar in der aktuellen CMD-Session weiter gelten, aber ein "neu" geöffnetes CMD-Fenster würde wiederum die Registrywerte als Blaupause nehmen.
Geht also per design nicht, was Du Dir erhoffst.
Zwar könntest Du durch einen Autostart-Batch bei jedem CMD-Start die von mir definierten Werte für Tag, Monat, Jahr, Stunde, Minute etc. sofort "als erstes" setzen (lassen).
Aber diese würden "statisch" sein, Bedeutet, wenn Du um 16:34h ein CMD-Fenster öffnest, würden zwar %HH% auf 16 und %MM% auf 34 gesetzt werden.
Aber: auch um 22:55h wären %hh% immer noch 16 und %mm% immer noch 34 und nich 22 bzw. 55.
Dynamische Variablen und/oder "allgemeinverbindliche" Variablen für alle geöffneten CMD-Instanzen sind nicht möglich.
Der CMD-Interpreter ist ein Werkzeug mit der Intension, dass es mehrfach parallel aufgerufen werden kann, um auch verschiedene Aufgaben/Tasks/Batches unabhängig und unbeeinflusst voneinander parallel ausführen zu können.
Mein Tipp an dieser Stelle: Versuche niemals, gegen das Design, gegen die Philosophie eines Werkzeugs zu programmieren.
Dann ermittle eben die %TT%, %MM%, %JJ%...-Variablen aktuell, jedesmal unmittelbar vor der Stelle, wo Du sie brauchst.
Alles andere wird aufwändig oder zu sehr neben der Spur, um allgemein verwendbar zu sein.
Somit also sorry, du hast keinen Schalter übersehen. Dieses Feature kann ich ich nicht bieten.
Grüsse
Biber
willkommen um Forum und danke für das Auseinandersetzen mit dem Thema.
Mal sehen, ob ich die Unklarheiten ausräumen kann.
Zu Deiner Frage "Wie kann ich erreichen, dass die gesetzten Variablen auch in nachfolgend geöffneten CMD-Sessions verfügbar sind"..
Schlechte Nachricht: Gar nicht.
Gute Nachricht: Ist auch nicht erstrebenswert.
Die Umgebungsvariablen einer CMD-Session gelten grundsätzlich immer nur in einer Session,
d.h. solange das Fenster, in der Batch (oder die Kommandozeilenbefehle) ablaufen nicht geschlossen wird.
Oder exakter gesagt, innerhalb dieser Instanz der CMD.exe.
Anders wäre es aus mehreren Gründen auch nicht handelbar.
Stell Dir vor, jede in einem Batch/jede am CMD-Prompt gesetzte Variable wäre für alle nachfolgend geöffneten CMD-Instanzen gültig.
Du würdest raschelig werden. Sobald Du dann in einem Batch den aktuellen Pfad ändern würdest mit CD,
würden alle nachfolgend CMD/Batchaufrufe sich in diesem Verzeichnis befinden.
Denn die Variable %CD% ("aktuelles Verzeichnis") würde ja für alle gelten.
Wenn Du in einem Batch die Farbenauf gelb auf blau einstellst oder die Variable %logFile% auf "x:\logs\my.log" setzt, würde es für jeden hinterher gestarteten Batch inclusive der im Taskplaner hinterlegten gelten etc etc.
Diese Art von "globalen" Variablen meinte ich nicht - diese wären für mich "sessionübergreifende Systemvariable".
Diese gibt es auch unter Windows - Variable, die für alle CMD-Sessions als Anfangsumgebung gelten werden über die Registry gesteuert (%username%, %computername%, %userprofile% oder,
da M$ ja immer im Laufe der Implementierung Angst vor der eigenen Courage bzw. der eingeschlagenen Programmierstrategie bekommt, zum Teil auch beiläufigt bei DLL-Aufrufen (%APPDATA% durch die shell.dll; %LOGONSERVER%...).
Was dann zu so lustigen Effekten führt wie "%APPDATA% nicht gesetzt" (Hatten wir neulich gerade im Forum).
Was M$ aber nicht tut oder nur SEHR verhalten ist: Variablen zu definieren, die sich zur Laufzeit selbst aktualisieren.
Es existieren einige wenige Variablen, die "dynamischen" Charakter haben, also zu unterschiedlichen Zeiten auch jeweils die Gerade-Jetzt-Werte haben.
Dazu gehören %date%, %time%, %cd% - aber alle Vaariablen, die Du über den Befehl SET angezeigt bekommst, sind statisch.
Bedeutet, die bekommen bei Start des CMD-Inerpreters einen Anfangswert (aus der Registry) und dieser Wert ist eine einmalig erzeugte Kopie der Werte aus der Registry.
Ändert sich höchstens, wenn Du ihn änderst, aber auch dann hättest Du nur den Wert der Kopie geämdert.
Das würde zwar in der aktuellen CMD-Session weiter gelten, aber ein "neu" geöffnetes CMD-Fenster würde wiederum die Registrywerte als Blaupause nehmen.
Geht also per design nicht, was Du Dir erhoffst.
Zwar könntest Du durch einen Autostart-Batch bei jedem CMD-Start die von mir definierten Werte für Tag, Monat, Jahr, Stunde, Minute etc. sofort "als erstes" setzen (lassen).
Aber diese würden "statisch" sein, Bedeutet, wenn Du um 16:34h ein CMD-Fenster öffnest, würden zwar %HH% auf 16 und %MM% auf 34 gesetzt werden.
Aber: auch um 22:55h wären %hh% immer noch 16 und %mm% immer noch 34 und nich 22 bzw. 55.
Dynamische Variablen und/oder "allgemeinverbindliche" Variablen für alle geöffneten CMD-Instanzen sind nicht möglich.
Der CMD-Interpreter ist ein Werkzeug mit der Intension, dass es mehrfach parallel aufgerufen werden kann, um auch verschiedene Aufgaben/Tasks/Batches unabhängig und unbeeinflusst voneinander parallel ausführen zu können.
Mein Tipp an dieser Stelle: Versuche niemals, gegen das Design, gegen die Philosophie eines Werkzeugs zu programmieren.
Dann ermittle eben die %TT%, %MM%, %JJ%...-Variablen aktuell, jedesmal unmittelbar vor der Stelle, wo Du sie brauchst.
Alles andere wird aufwändig oder zu sehr neben der Spur, um allgemein verwendbar zu sein.
Somit also sorry, du hast keinen Schalter übersehen. Dieses Feature kann ich ich nicht bieten.
Grüsse
Biber
bjoernanger schreibt am 18.07.2007 um 13:23:53 Uhr
Hi,
ich habe mit Begeisterung gesehen, was man alles aus Windows rauskitzeln kann. Aber eine kleines Problem hab ich da dennoch:
Gibt es eine Möglichkeit, das die Kalenderwochen am Montag anfängt?
Also 15.7.07 = KW 28 und 16.7.07 = KW 29
Oder hab ich da etwas übersehen ?
Gruß
ich habe mit Begeisterung gesehen, was man alles aus Windows rauskitzeln kann. Aber eine kleines Problem hab ich da dennoch:
Gibt es eine Möglichkeit, das die Kalenderwochen am Montag anfängt?
Also 15.7.07 = KW 28 und 16.7.07 = KW 29
Oder hab ich da etwas übersehen ?
Gruß
Biber schreibt am 18.07.2007 um 18:18:46 Uhr
Moin bjoernanger,
ich habe es oben beschrieben (oder zumindest skizzert):
Suche mal nach folgendem Abschnitt:
------------
....
.....
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:
.......
......
-------------
Zum Verständnis der VBS-DatePart()-Parameter empfehle ich M$-Technet Retrieving Specific Portions of a Date and Time Value.
Und ja, um der Frage zuvorzukommen, manchmal muss man/frau 2x200 Zeilen lesen, um 2 Batch- und 2 VBS-Zeilen zusammenschroten zu können...
Passt?
Grüße
Biber
ich habe es oben beschrieben (oder zumindest skizzert):
Suche mal nach folgendem Abschnitt:
------------
....
.....
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:
01.
'----snipp DateKrams.vbs 02.
Wscript.Echo " " & DatePart("ww",Date,vbSunday,vbFirstFourDays) & " " &_ 03.
DatePart("ww",Date) & " " & DatePart("w",Date) & " " & DatePart("y",Date) 04.
'------snapp DateKrams.vbs 01.
>for /f "tokens=2-5" %a in ('cscript //nologo DateKrams.vbs') do @echo KW=%a,KWOS=%b,DoW=%c,DoY=%d 02.
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.
Und ja, um der Frage zuvorzukommen, manchmal muss man/frau 2x200 Zeilen lesen, um 2 Batch- und 2 VBS-Zeilen zusammenschroten zu können...
Passt?
Grüße
Biber
bjoernanger schreibt am 19.07.2007 um 13:56:33 Uhr
Das ist ja echt ein wenig kompliziert ...
Wenn man erstmal weiß, das man den DatePart-Befehl tunen muß ist alles super.
Dann kommt man schnell zum Schalter vbSunday der in meinem Fall vbMonday heißen muß.
Jetzt läufts.
Wenn man erstmal weiß, das man den DatePart-Befehl tunen muß ist alles super.
Dann kommt man schnell zum Schalter vbSunday der in meinem Fall vbMonday heißen muß.
Jetzt läufts.
Biber schreibt am 19.07.2007 um 14:16:51 Uhr
Moin bjornanger,
>..der in meinem Fall vbMonday heißen muß.
Tja, mein Vorteil an dieser Stelle ist, dass ich seit Beginn des Arbeitslebens jeden Tags aufs Neue das Gefühl habe, dass mein Schalter permanent auf vbMonday steht..
Von daher habe ich mich viel damit beschäftigt...
Freut mich, dass es läuft.
Grüße
Biber
>..der in meinem Fall vbMonday heißen muß.
Tja, mein Vorteil an dieser Stelle ist, dass ich seit Beginn des Arbeitslebens jeden Tags aufs Neue das Gefühl habe, dass mein Schalter permanent auf vbMonday steht..
Von daher habe ich mich viel damit beschäftigt...
Freut mich, dass es läuft.
Grüße
Biber
yotaman schreibt am 20.09.2007 um 01:10:52 Uhr
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
Biber schreibt am 20.09.2007 um 13:15:23 Uhr
Moin yotaman,
danke für Deine Ergänzung " %time% unter NT" - baue ich oben im Skript ein heute abend.
Und schreibe vielleicht noch einen Satz zu dem Programmierstil von Bills Bande bei %time% vs. time/t.
Dein versehentliches Doppelposting weiter unten habe ich gelöscht.
Danke und Grüße
Biber
------
[Edit 20.9.2007 abends]
Änderungen eingebaut in das GetAllDateTimeInfos-Skriptchen als "Vers. 0.10"
[/Edit]
danke für Deine Ergänzung " %time% unter NT" - baue ich oben im Skript ein heute abend.
Und schreibe vielleicht noch einen Satz zu dem Programmierstil von Bills Bande bei %time% vs. time/t.
Dein versehentliches Doppelposting weiter unten habe ich gelöscht.
Danke und Grüße
Biber
------
[Edit 20.9.2007 abends]
Änderungen eingebaut in das GetAllDateTimeInfos-Skriptchen als "Vers. 0.10"
[/Edit]
yotaman schreibt am 21.09.2007 um 00:06:26 Uhr
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
Safwat schreibt am 28.02.2008 um 17:39:08 Uhr
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
Biber schreibt am 28.02.2008 um 18:15:00 Uhr
Moin safwat,
willkommen im Forum.
Deine Anforderung ist ohne großartige Datumsarithmetik lösbar, hier reicht ein einfacher Textvergleich mit dem Dateidatum.
Demo am CMD-Prompt [einzugebende Zeilen durch ">" gekennzeichnet]:
Der erste proof-of-concept-Befehl würde aus zwei Verzeichnissen alle *.txt-Dateien herausflöhen,
die ein "04.2007" im Dateidatum haben, also aus dem April 2007 sind.
Alle anderen Monat/Jahr-Kombinationen werden herausgefiltert.
...natürlich würden auch alle Dateien angezeigt, die den Text "04.2007 " im Namen tragen, ich weiß, ich weiß..
Der zweite Befehl zeigt eher, worauf es ankommt - auf eine Liste der Dateinamen mit vollständigem Pfad in Anführungszeichen.
Der dritte Befehl, der Dein nächster Schritt sein könnte und deshalb nicht von mir hingetippt wurde,
sollte dann das @echo "%i" ersetzen durch ein move "%i" X:\Aprildaten\" oder was immer Du mit diesen Dateien vorhast.
Grüße
Biber
P.S. Und der/die nächste, der hier wieder "danke im voraus" schreibt, wird ohne Kommentar gelöscht...
willkommen im Forum.
Deine Anforderung ist ohne großartige Datumsarithmetik lösbar, hier reicht ein einfacher Textvergleich mit dem Dateidatum.
Demo am CMD-Prompt [einzugebende Zeilen durch ">" gekennzeichnet]:
01.
(=18:02:19 D:\temp=) 02.
>for %i in (e:\work\*.txt d:\temp\*.txt) do @echo %~ti "%i" |find "04.2007" 03.
25.04.2007 07:13 "d:\temp\nureinzelne.txt" 04.
30.04.2007 19:46 "d:\temp\UPDate.txt" 05.
13.04.2007 15:54 "d:\temp\Userids.txt" 06.
25.04.2007 07:09 "d:\temp\vcard.txt" 07.
08.
(=18:02:44 D:\temp=) 09.
>for %i in (e:\work\*.txt d:\temp\*.txt) do @echo %~ti|find "04.2007 ">nul && @echo "%i" 10.
"d:\temp\nureinzelne.txt" 11.
"d:\temp\UPDate.txt" 12.
"d:\temp\Userids.txt" 13.
"d:\temp\vcard.txt"Der erste proof-of-concept-Befehl würde aus zwei Verzeichnissen alle *.txt-Dateien herausflöhen,
die ein "04.2007" im Dateidatum haben, also aus dem April 2007 sind.
Alle anderen Monat/Jahr-Kombinationen werden herausgefiltert.
...natürlich würden auch alle Dateien angezeigt, die den Text "04.2007 " im Namen tragen, ich weiß, ich weiß..
Der zweite Befehl zeigt eher, worauf es ankommt - auf eine Liste der Dateinamen mit vollständigem Pfad in Anführungszeichen.
Der dritte Befehl, der Dein nächster Schritt sein könnte und deshalb nicht von mir hingetippt wurde,
sollte dann das @echo "%i" ersetzen durch ein move "%i" X:\Aprildaten\" oder was immer Du mit diesen Dateien vorhast.
Grüße
Biber
P.S. Und der/die nächste, der hier wieder "danke im voraus" schreibt, wird ohne Kommentar gelöscht...
Safwat schreibt am 03.03.2008 um 14:48:25 Uhr
Danke Biber für Dein Antwort !
Es klappt das ich die Dateien rausfiltern kann !
das moven klappt auch !
Hast Du ein Idee wie diese Files dann in einem einzigen File zippen kann ?
z.B. von Dein Beispiel die gefilterte Daten dann auch als 042007.zip zu sichern ?
Es klappt das ich die Dateien rausfiltern kann !
das moven klappt auch !
Hast Du ein Idee wie diese Files dann in einem einzigen File zippen kann ?
z.B. von Dein Beispiel die gefilterte Daten dann auch als 042007.zip zu sichern ?
Biber schreibt am 03.03.2008 um 19:05:34 Uhr
Moin safwat,
dazu brauchst Du ein von der Commandline bedienbares Zip-Utility.
Sehr empfohlen wird 7-zip, siehe auch die Links unten.
Über die Forumssuche nach 7zip findest Du auch mehrere Beispielbätche, falls die mitgelieferte Hilfe nicht ausreichend sein sollte.
Hier im Rahmen dieses Tutorials wollte ich lieber noch ein bisschen Platz für eventuelle Rückfragen lassen und dieses Nebengleis nicht weiter verfolgen.
Wenn Du gar nicht weiterkommst mit der Zipperei, mach bitte in "Batch & Shell" einen neuen Thread auf.
Grüße
Biber
dazu brauchst Du ein von der Commandline bedienbares Zip-Utility.
Sehr empfohlen wird 7-zip, siehe auch die Links unten.
Über die Forumssuche nach 7zip findest Du auch mehrere Beispielbätche, falls die mitgelieferte Hilfe nicht ausreichend sein sollte.
Hier im Rahmen dieses Tutorials wollte ich lieber noch ein bisschen Platz für eventuelle Rückfragen lassen und dieses Nebengleis nicht weiter verfolgen.
Wenn Du gar nicht weiterkommst mit der Zipperei, mach bitte in "Batch & Shell" einen neuen Thread auf.
Grüße
Biber
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#
Biber schreibt am 27.05.2008 um 18:29:29 Uhr
Moin stefan#,

Tja, Spass beiseite, das kommt davon, wenn M$'s und meine geballte Schlamperei aufeinandertreffen....
Die Ursache wird vermutlich
<rausred>Deshalb habe ich auch damals schon mit den den Sourcecode geschrieben: "mit meinen Reg-Einstellungen".</rausred>
Ich hab mich damals schon köstlich darüber amüsirt, dass sich diese Werte (VIELE Datumsdefinitionswerte!) gar nicht über GUI ändern lassen... wenn Dir also irgendeine verschnarchte Freeware-Firlefanz-Anwendung diese Datums-Berechnungs-Grundlagen meint umschießen zu müssen... da kommst Du nie wieder dran. Und bei Dir ist dann Sonntag Montag.
Bitte lass uns Deinen Fall über PN oder Mail (in meinem Profil) klären und hier dann den endgültigen Backfix posten.
Grüße
Biber
Was habe ich falsch konfiguriert?
Du wahrscheinlich nicht...siehe unten.Gibt es das öfter..
Verglichen mit dreibeinigen Schimmelstuten oder verglichen mit Werbepausen auf SAT1?...oder bin ich der Einzige?
Nein, aber anderen skripten selbst einen Workaround..Tja, Spass beiseite, das kommt davon, wenn M$'s und meine geballte Schlamperei aufeinandertreffen....
Die Ursache wird vermutlich
- einerseits in den oben geposteten Registry-Einstellungen liegen, insbesondere an dem "Mit welchem Tag fängt die Woche an"-Wert
HKCU\Control Panel\International\iFirstDayOfWeek
siehe hier beim sympathischen Weltmarktführer- andererseits in meiner Schlamperei, dass (weil anderes bei meinen Tests nie aufgetreten ist) die numerischen Returnwerte für Wochentage nur 1-7 sein können... einen Wert 0 an der Stelle fange ich nicht ab.
<rausred>Deshalb habe ich auch damals schon mit den den Sourcecode geschrieben: "mit meinen Reg-Einstellungen".</rausred>
Ich hab mich damals schon köstlich darüber amüsirt, dass sich diese Werte (VIELE Datumsdefinitionswerte!) gar nicht über GUI ändern lassen... wenn Dir also irgendeine verschnarchte Freeware-Firlefanz-Anwendung diese Datums-Berechnungs-Grundlagen meint umschießen zu müssen... da kommst Du nie wieder dran. Und bei Dir ist dann Sonntag Montag.
Bitte lass uns Deinen Fall über PN oder Mail (in meinem Profil) klären und hier dann den endgültigen Backfix posten.
Grüße
Biber
testbild schreibt am 09.06.2008 um 15:19:22 Uhr
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
Biber schreibt am 09.06.2008 um 16:11:59 Uhr
Moin testbild,
danke - freut mich, wenn es nützlich war.
zum Thema "Nur die letzten x Sicherungen behalten und alle anderen Löschen"... dazu haben wir im Bereich "Batch & Shell" einige Varianten.
Die Mimik ist unter anderem hier bestimmten Ordner per Batch-Datei löschen oder hier Die ältesten Dateien löschen beschrieben... und auch noch in ein paar anderen Beiträgen.
Aber der erstgenannte ist so ziemlich die Mutter aller "Lösch-mir-die-ältesten-Sicherungsordner" hier im Forum.
Wenn es klemmt (=nach einer halben Stunde immer noch keinen Ansatz gefunden), dann mach einen neuen Beitrag auf in "Batches4Hell", da wird es auch vor dem Abendessen fertig.
Grüße
Biber
danke - freut mich, wenn es nützlich war.
zum Thema "Nur die letzten x Sicherungen behalten und alle anderen Löschen"... dazu haben wir im Bereich "Batch & Shell" einige Varianten.
Die Mimik ist unter anderem hier bestimmten Ordner per Batch-Datei löschen oder hier Die ältesten Dateien löschen beschrieben... und auch noch in ein paar anderen Beiträgen.
Aber der erstgenannte ist so ziemlich die Mutter aller "Lösch-mir-die-ältesten-Sicherungsordner" hier im Forum.
Wenn es klemmt (=nach einer halben Stunde immer noch keinen Ansatz gefunden), dann mach einen neuen Beitrag auf in "Batches4Hell", da wird es auch vor dem Abendessen fertig.
Grüße
Biber
washy schreibt am 11.06.2008 um 17:25:55 Uhr
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?
Biber schreibt am 11.06.2008 um 20:48:08 Uhr
Moin washy,
Wie meistens im täglichen K(r)ampf mit dieser Redmonder Softwareklitsche gibt es auch hier gute und schlechte Nachrichten für Dich.
Die schlechten lieber zuerst:
Mit Batch (also dem, was CMD.exe beinhaltet) und auch mit VBSkript ist da Feierabend... beide sind primär dafür da, schnell die wichtigsten und am häufigsten nachgefragten Informationen zu liefern - vorzugsweise auf den Bildschirm.
Nicht oder seltenst zur maschinellem Weiterverarbeitung.
Und das, was mal schnell mit einem DIR am CMD-Prompt oder mit einem WScript.Echo rausgerotz^H^H rausgeschrieben wird, ist halt nicht so genau.
Beim Dateidatum hört das Allgemeininteresse bei den Sekunden auf,
beim DIR-Befehl sogar bei den Minuten (Ausgabe: "11.06.2008 20:05 ....").
VBScript ist kaum genauer:
Ausgabe bei Aufruf:
... keine Millisekunden zu sehen... genauer als so gehts nicht.
Deshalb habe ich oben im Workshop-Schnipsel eine verschämte Zeile drin:
...auf deutsch: wenn Du keine Sekunden und keine Millisecs hast, setze sie auf "00".
Und beim Datei-Datum ist es immer so.
Ende der schlechten Nachrichten.
Gute Nachricht:
Beispielsweise JScript kann schon damit umgehen, dass es auch Menschen mit Millisekunden-Faible auf der Welt gibt.
In JScript lässt sich ein Datumswert aufdröseln bis auf MilliSekunden.
Wenn also JS aus einem als Parameter übergeben Dateidatum die Millisecs rausflöhen könnte...
-> Das wäre die billigste Lösung, es sei denn, Du treibst irgendwo ein (existierendes) Konsolenutility auf, das das Dateidatum mit Sekunden und Millsekunden ausgibt.
Sollte es eigentlich auch schon geben.
Mit meinen eher beschränkten Batch-Mitteln ist es nicht möglich, aus dem Datum einer bestehenden Datei Sekunden und Millisekunden zu ermitteln.
...aber das Sternzeichen könnte ich errechnen..
Grüße
Biber
... in das Format:
JJ.MM.TT_hh.mm.ss.ms.txt umbenennen.
JJ.MM.TT_hh.mm.ss.ms.txt umbenennen.
Wie meistens im täglichen K(r)ampf mit dieser Redmonder Softwareklitsche gibt es auch hier gute und schlechte Nachrichten für Dich.
Die schlechten lieber zuerst:
Mit Batch (also dem, was CMD.exe beinhaltet) und auch mit VBSkript ist da Feierabend... beide sind primär dafür da, schnell die wichtigsten und am häufigsten nachgefragten Informationen zu liefern - vorzugsweise auf den Bildschirm.
Nicht oder seltenst zur maschinellem Weiterverarbeitung.
Und das, was mal schnell mit einem DIR am CMD-Prompt oder mit einem WScript.Echo rausgerotz^H^H rausgeschrieben wird, ist halt nicht so genau.
Beim Dateidatum hört das Allgemeininteresse bei den Sekunden auf,
beim DIR-Befehl sogar bei den Minuten (Ausgabe: "11.06.2008 20:05 ....").
VBScript ist kaum genauer:
01.
Set f = CreateObject("Scripting.FileSystemObject").GetFile(Wscript.Arguments(0)) 02.
Wscript.Echo "Datei " & f.Path 03.
Wscript.Echo "Erstellt am: " & f.DateCreated 04.
Wscript.Echo "Letzter Zugriff: " & f.DateLastAccessed 05.
Wscript.Echo "Letzte Änderung: " & f.DateLastModified01.
>cscript //nologo e:\daily\GetFileAttr.vbs werte.txt 02.
Datei D:\temp\werte.txt 03.
Erstellt am: 06.07.2006 19:18:58 04.
Letzter Zugriff: 29.04.2008 22:27:04 05.
Letzte Änderung: 06.07.2006 19:19:54Deshalb habe ich oben im Workshop-Schnipsel eine verschämte Zeile drin:
01.
... 02.
For %%i in (ss ms) do if not defined %%i set "%%i=00" 03.
...Und beim Datei-Datum ist es immer so.
Ende der schlechten Nachrichten.
Gute Nachricht:
Beispielsweise JScript kann schon damit umgehen, dass es auch Menschen mit Millisekunden-Faible auf der Welt gibt.
In JScript lässt sich ein Datumswert aufdröseln bis auf MilliSekunden.
01.
... 02.
var myDate = new Date(pDate); 03.
var ms= myDate.getMilliseconds(); // <-- Nur in JS. 04.
// Nicht unter CMD.exe oder VBScript 05.
...-> Das wäre die billigste Lösung, es sei denn, Du treibst irgendwo ein (existierendes) Konsolenutility auf, das das Dateidatum mit Sekunden und Millsekunden ausgibt.
Sollte es eigentlich auch schon geben.
Mit meinen eher beschränkten Batch-Mitteln ist es nicht möglich, aus dem Datum einer bestehenden Datei Sekunden und Millisekunden zu ermitteln.
...aber das Sternzeichen könnte ich errechnen..
Grüße
Biber
washy schreibt am 11.06.2008 um 23:56:08 Uhr
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!
>...aber das Sternzeichen könnte ich errechnen..
*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*
Biber schreibt am 12.06.2008 um 07:48:18 Uhr
Moin washy,
na ja, wenn es nur um die Sekunden des Dateidatums geht, das bekommen wir mit diesen beiden Schrubbeltools CMD.exe und VBSkript grad noch hin.
Nur Millisekunden sind auf dem Weg unerreichbar.
Wenn Du das Dateidatum genauer brauchst als es der DIR-Befehl anzeigt, dann holen wir das mit den gestern angedeuteten GetFile()-Methoden.
Demoschnipsel:
Demo am CMD-Prompt, erst Datumsgenauigkeit mit DIR, danach mit VBSkript:
Diese Rückgabe (Variable %fdlastMod%) kann wiederum von meiner GetAlldateTimeInfos verarbeitet werden.
Oder aber (was sinnvoller wäre) direkt für diese Umbenamserei nutzen.
Wenn Du Schwierigkeiten haben solltest, das in einen Massenverarbeitungs-Batch (viele Dateien/ganze Unterverzeichnisse) einzubauen, lass uns das bitte in einem neuem Beitrag klären.
Grüße
Biber
na ja, wenn es nur um die Sekunden des Dateidatums geht, das bekommen wir mit diesen beiden Schrubbeltools CMD.exe und VBSkript grad noch hin.
Nur Millisekunden sind auf dem Weg unerreichbar.
Wenn Du das Dateidatum genauer brauchst als es der DIR-Befehl anzeigt, dann holen wir das mit den gestern angedeuteten GetFile()-Methoden.
Demoschnipsel:
01.
::---- snippFdLastModified.cmd 02.
@echo off & setlocal 03.
Set "GFLM=%temp%\GetFiledateLastModified.vbs" 04.
>"%GFLM%" Echo Set f = CreateObject("Scripting.FileSystemObject").GetFile(Wscript.Arguments(0)) 05.
>>"%GFLM%" Echo Wscript.Echo f.DateLastmodified 06.
For /f "delims=" %%i in ('cscript //nologo "%GFLM%" "%~1"') do set "fdlastMod=%%i" 07.
Echo Dateidatum "%~1": 08.
Echo %fdlastMod%01.
>for %i in (werte.txt) do @echo %~ti 02.
06.07.2006 19:19 03.
>FdlastModified.cmd werte.txt 04.
Dateidatum "werte.txt": 05.
06.07.2006 19:19:54Oder aber (was sinnvoller wäre) direkt für diese Umbenamserei nutzen.
Wenn Du Schwierigkeiten haben solltest, das in einen Massenverarbeitungs-Batch (viele Dateien/ganze Unterverzeichnisse) einzubauen, lass uns das bitte in einem neuem Beitrag klären.
Grüße
Biber
Biber schreibt am 23.10.2008 um 23:20:35 Uhr
Moin srmerlin,
Danke für den Hinweis.
Da hatte ich wohl ein bisschen geschlampt...
Habe oben im Tut die Zeile 30 geändert von...
...auf...
Damit wäre dieser Schönheitsfehler behoben.
Grüße
Biber
Danke für den Hinweis.
Da hatte ich wohl ein bisschen geschlampt...
Habe oben im Tut die Zeile 30 geändert von...
For %%i in (%1 %2 %3) Do If /i %%i==/u goto :CleanupFor %%i in (%1 %2 %3) Do If /i %%i==/u Set "AllDateTimeVars=" & goto :CleanupDamit wäre dieser Schönheitsfehler behoben.
Grüße
Biber
Aspedal99 schreibt am 07.11.2008 um 17:23:55 Uhr
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?
Biber schreibt am 07.11.2008 um 18:06:07 Uhr
Moin Aspedal99,
nein, das ist mir noch nicht bekannt.
Aber bei diesen ja in der Tat verheerenden Fehlfunktionen unter XP SP3 will ich natürlich schnellstmöglich die Ursache finden und in meinem Schnipsel berücksichtigen.
Bitte lass uns beide per PN oder Mail (in meinem Profil angegeben) weitermachen, das Ergebnis kommt dann natürlich hier ins Forum.
Grüße
Biber
[Edit 16.11.2008]
Habe bis heute noch keine Antwort - auch auf eine PN - erhalten und von daher keinen Ansatzpunkt.
Sollte auch jemand anderes diese Problem kennen, bitte gerne PN oder Mail an mich.
[/Edit}
nein, das ist mir noch nicht bekannt.
Aber bei diesen ja in der Tat verheerenden Fehlfunktionen unter XP SP3 will ich natürlich schnellstmöglich die Ursache finden und in meinem Schnipsel berücksichtigen.
Bitte lass uns beide per PN oder Mail (in meinem Profil angegeben) weitermachen, das Ergebnis kommt dann natürlich hier ins Forum.
Grüße
Biber
[Edit 16.11.2008]
Habe bis heute noch keine Antwort - auch auf eine PN - erhalten und von daher keinen Ansatzpunkt.
Sollte auch jemand anderes diese Problem kennen, bitte gerne PN oder Mail an mich.
[/Edit}
dolsch schreibt am 19.02.2009 um 10:09:33 Uhr
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?
Biber schreibt am 19.02.2009 um 12:13:54 Uhr
Moin dotsch und willkommen im Forum.
habe ich eben gerade auch durch "in den Speicher kopieren" des GetAllDateTimeInfo-Schnipsels reproduzieren können.
Keine Ahnung, wie das zustandekam - vermutlich habe ich die zuletzt ins Tutorial Version im "falschen" Editor bearbeitet oder so...
Ich stelle noch mal eine um die trailing blanks bereinigte Sourcecode-Kopie ins Tutorial oben.
Am nächsten Regentag.
Global im Zusammenhang mit Batch-Programmen bedeutet ja "für die Lebensdauer der CMD/Batch-Session".
Nicht für neue (z.B. über den Explorer oder den Taskplaner gestartete) Batches, die zufällig zeitgleich, aber "in einem eigenen Fenster" laufen.
Aber für das von Dir angedeutete Szenario:
Ja, da hast Du Recht und ich habe seit Jahrzehnten ganz gedankenlos auch die 2stelligen Sekundenbruchteile als "ms" bzw Millisekunden bezeichnet.
Sicherlich teilweise verleitet von der oft z.B. bei Datenbank-Uhrzeitformaten verwendeten Nomenklatur.
Formal wäre richtig, bei Millisekunden (= Tausendstel Sekunden) auch drei NK-Stellen anzuzeigen und nicht wie die Redmonder nur zwei NK-Stellen:
Hier hingegen:
Eventuell mach ich doch aus dem Tutorial eine Doktorarbeit "Umgang mit Datum und Zeit in der Datenverarbeitung" ?
Grüße
Biber
herzlichen Dank für das Tutorial. Du glänzt nicht nur mit
Wissen, sondern kannst es auch sehr gut vermitteln.
Danke für die Blumen.Wissen, sondern kannst es auch sehr gut vermitteln.
Ich habe ein paar Fragen bzw. Anregungen:
bedenkenlos entfernen, oder gibt es irgend eine Zeile, in der er beabsichtigt ist? ...
Nein, diese in fast jeder (aber eben nicht jeder) Zeile vorhandenenen Leerzeichen am Ende-der-Zeile sind absolut unbeabsichtigt.- Am Ende vieler Zeilen befinden sich ein oder mehrere Leerzeichen.
bedenkenlos entfernen, oder gibt es irgend eine Zeile, in der er beabsichtigt ist? ...
habe ich eben gerade auch durch "in den Speicher kopieren" des GetAllDateTimeInfo-Schnipsels reproduzieren können.
Keine Ahnung, wie das zustandekam - vermutlich habe ich die zuletzt ins Tutorial Version im "falschen" Editor bearbeitet oder so...
Ich stelle noch mal eine um die trailing blanks bereinigte Sourcecode-Kopie ins Tutorial oben.
Am nächsten Regentag.
* 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?
Sauberer ist es. Die mit "GetAllDateTimeInfos /s" sollen ja -by concept- global gesetzt werden.Wenn ich GetAllDateTimeInfos /s aus einem anderen Batch heraus
aufgerufen habe, muss ich die Variablen wieder mit GetAllDateTimeInfos /u löschen?
Global im Zusammenhang mit Batch-Programmen bedeutet ja "für die Lebensdauer der CMD/Batch-Session".
Nicht für neue (z.B. über den Explorer oder den Taskplaner gestartete) Batches, die zufällig zeitgleich, aber "in einem eigenen Fenster" laufen.
Aber für das von Dir angedeutete Szenario:
- CMD-Session-Fenster ist offen
- BatchEins.bat wird gestartet
- in BatchEins.bat wird "GetAllDateTimeInfos /s" aufgerufen
- BatchEins.bat ist fertig und CMD-Session-Fenster bleibt geöffnet --------> Alle "GetAllDateTimeInfos /s"-Variablen sind und bleiben gesetzt,
- Cmd-Session-Fenster wird geschlossen ----> Alle "GetAllDateTimeInfos /s"-Variablen sind Geschichte.
* 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?
Das müßten demzufolge hundertstel Sekunden und nicht tausendstel Sekunden sein,
also Zentisekunden (cs, zs oder hs) und nicht Millisekunden (ms). Stimmt doch, oder?
Ja, da hast Du Recht und ich habe seit Jahrzehnten ganz gedankenlos auch die 2stelligen Sekundenbruchteile als "ms" bzw Millisekunden bezeichnet.
Sicherlich teilweise verleitet von der oft z.B. bei Datenbank-Uhrzeitformaten verwendeten Nomenklatur.
Formal wäre richtig, bei Millisekunden (= Tausendstel Sekunden) auch drei NK-Stellen anzuzeigen und nicht wie die Redmonder nur zwei NK-Stellen:
01.
>time 02.
Aktuelle Zeit: 12:01:39,16 also Zentisekunden (cs, zs oder hs) und nicht Millisekunden (ms). Stimmt doch, oder?
Zenti-Sekunden ...... hmmja.... ... als Analogie zu - Meter->[Dezimeter]->Zentimeter->Millimeter würde es passen.
- Sekunde->[[Dezisekunde???]]->[Zentisekunde?]->[Millisekunde]
Eventuell mach ich doch aus dem Tutorial eine Doktorarbeit "Umgang mit Datum und Zeit in der Datenverarbeitung" ?
Grüße
Biber
dolsch schreibt am 21.02.2009 um 10:43:00 Uhr
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_(Ein ...
http://en.wikipedia.org/wiki/Internationa ...
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_ ...
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 ...
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_(Ein ...
http://en.wikipedia.org/wiki/Internationa ...
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_ ...
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 ...
YYYY-MM-DDThh;mm;ss+1;00 bzw. YYYY-MM-DDThh;mm;ss+2;00 (Sommerzeit)
Biber schreibt am 21.02.2009 um 17:53:08 Uhr
Moin dotsch,
vielen Dank für Deine Recherche und Ergänzung.
Insbesondere die Datumsdarstellung mit 2-stelligen Jahresangaben ist in der IT-Welt gottseidank kaum noch anzutreffen und eigentlich absolut unverantwortlich.
Erst Recht, seit es nun wirklich jedes Jahr wie den "08.08.08", den "09.09.09" oder den "11.11.11" gibt. Erst in vier Hahren wird es wieder kontextbedingt einfacher.
Deine Variante mit den Semikola als stilisierte Doppelpunkte... hm, okay, solange es für jede/n Leser/in interpretierbar und erkennbar ist...
Wenn ich in meiner Erinnerung krame.... meistens lass ich die Trennzeichen bei hhmmss-Angaben in Logfilenamen ganz weg.
Weill eben da die Reihenfolge ohnehin für jeden klar und nicht diskussionswürdig zu sein scheint - egal ob diesseits oder jenseits des Pazifiks.
Grüße
Biber
vielen Dank für Deine Recherche und Ergänzung.
Und soweit ich verstanden habe, entspräche folgendes schon nicht mehr dem internationalen Standard:
03-04-01 oder 2003/04/01
Da würde ich uneingeschränkt zustimmen.03-04-01 oder 2003/04/01
Insbesondere die Datumsdarstellung mit 2-stelligen Jahresangaben ist in der IT-Welt gottseidank kaum noch anzutreffen und eigentlich absolut unverantwortlich.
Erst Recht, seit es nun wirklich jedes Jahr wie den "08.08.08", den "09.09.09" oder den "11.11.11" gibt. Erst in vier Hahren wird es wieder kontextbedingt einfacher.
Deine Variante mit den Semikola als stilisierte Doppelpunkte... hm, okay, solange es für jede/n Leser/in interpretierbar und erkennbar ist...
Wenn ich in meiner Erinnerung krame.... meistens lass ich die Trennzeichen bei hhmmss-Angaben in Logfilenamen ganz weg.
Weill eben da die Reihenfolge ohnehin für jeden klar und nicht diskussionswürdig zu sein scheint - egal ob diesseits oder jenseits des Pazifiks.
Grüße
Biber
dolsch schreibt am 23.02.2009 um 10:15:18 Uhr
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):
01.
>reg add "HKCU\Control Panel\International" /v idate /t REG_SZ /d 1 /f 02.
>date 03.
Aktuelles Datum: Sa 01-10-2005 04.
Geben Sie das neue Datum ein: (TT-MM-JJ) 05.
06.
>date /t 07.
Sa 01-10-2005 08.
>reg add "HKCU\Control Panel\International" /v idate /t REG_SZ /d 0 /f 09.
>date /t 10.
Sa 10-01-2005 11.
12.
>date 13.
Aktuelles Datum: Sa 10-01-2005 14.
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
01.
For %%i in (%AllDateTimeVars%) do @if defined %%i set %%i 01.
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:
01.
:: 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
Biber schreibt am 25.02.2009 um 08:48:36 Uhr
Moin dotsch,
sorry für die späte Antwort.
Hier meine Rest-Hinweise auf die (noch nicht selbst beantworteten) Fragen und Unsauberkeiten.
Und da habe ich natürlich meistens dieses "Inline-Echo-Off"-Zeichen "@" drin. Und manchmal verbleibt es dann auch redundanterweise im Batch.
Prüfe die Existenz der Umgebungsvariablen %OS%. Wenn es die gibt UND da drin "Windows_NT" steht , ist es mit hoher Wahrscheinlichkeit ein Windows NT oder was immer danach kommt.
Wenn es die Variable NICHT gibt, ist es so Gates will ein Win95/98....
Wegen dieses halbseidenen Konstruktes wird eben auch unter WinXP oder Vi$ta am CMD-Prompt angezeigt
.... und die Internetforen sind voll von Hilfe suchenden AnwenderInnen mit gesundem Menschenverstand, die schreiben
Vielen Dank für Deine Nachfragen... ich freue mich, wenn mein Tutorial ernsthaft und natürlich auch kritisch gelesen wird.
Grüße
Biber
sorry für die späte Antwort.
Hier meine Rest-Hinweise auf die (noch nicht selbst beantworteten) Fragen und Unsauberkeiten.
In diesem Zusammenhang wüßte ich gerne, wozu das at-Zeichen vor dem if gut ist
Das ist einfach nur überflüssig bzw. Schlampigkeit von mir. Meistens "teste" ich ja nur Teil-Zeilen der hier skizzierten Batche am CMD-Prompt.Und da habe ich natürlich meistens dieses "Inline-Echo-Off"-Zeichen "@" drin. Und manchmal verbleibt es dann auch redundanterweise im Batch.
... dem undokumentierten Parameter belassen. Absicht oder vergessen?
Vergessen. Bzw. war mir hier bei diesem Thema vollkommen egal. Nicht im Fokus. Unwichtiges Nebengeplänkel.....müsste .... %AllSystemDateTimeVars% .... heißen
Ist oben korrigiert. (aber nur punktuell, ich habe NICHT die ganzen Pre-Versionen der am Ende des Tuts hergeleiteten Batch bereinigt/geprüft).Lässt sich Code eigentlich als Zitat formatieren?
Nicht automatisch. Das wäre ein "feature request", den Du im Bereich "Off Topic"->"administrator.de-Feedback" stellen könntest.Find vs. FindStr...
Jein..... Als ich das Tut geschrieben habe, war (mir) FindStr.exe noch relativ neu. Und ich habe keine Ahnung mehr, ob FindStr.exe schon bei WinNT dabei war oder erst ab Win2000. Das (Redmonder) Find.exe dagegen ist auf jedem Windows-Rechner dabei.... und wer das durch ein migriertes Unix-Find.exe mit anderen Parametern ersetzt... nicht mein Problem.Übrigens heißen doch auch XP und Vista intern NT. Das Echo "Läuft nur unter WinNT oder höher.Sorry.".... ist ... missverständlich
Auch ein "Jein". Die von M$ höchstselbst damals empfohlene Prüfung auf "isses noch Win9x?" oder "isses was richtiges, also Windows_NT-Architektur?" war:Prüfe die Existenz der Umgebungsvariablen %OS%. Wenn es die gibt UND da drin "Windows_NT" steht , ist es mit hoher Wahrscheinlichkeit ein Windows NT oder was immer danach kommt.
Wenn es die Variable NICHT gibt, ist es so Gates will ein Win95/98....
Wegen dieses halbseidenen Konstruktes wird eben auch unter WinXP oder Vi$ta am CMD-Prompt angezeigt
01.
>set os 02.
OS=Windows_NT "Ich hab da einen Fehler. ich habe einen WinXP-Rechner, bei dem im Environment steht "OS=Windows_NT". Wie kann ich das in der Registry ändern??"
Vielen Dank für Deine Nachfragen... ich freue mich, wenn mein Tutorial ernsthaft und natürlich auch kritisch gelesen wird.
Grüße
Biber
dolsch schreibt am 26.02.2009 um 11:02:22 Uhr
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/ ...
http://www.msfn.org/board/index.php?showt ...
http://www.msfn.org/board/CMD-vs-Bat-file ...
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.cf ...
»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:
01.
@echo off 02.
03.
:: With the help of the tutorial 04.
:: http://www.administrator.de/Workshop_Batch_for_Runaways_Part_III_Datums-_und_Zeitvariablen_im_Batch.html 05.
set "myDate=%date%" 06.
for /f "tokens=2" %%i in ("%myDate%") do set "myDate=%%i" 07.
08.
if not exist DateOrder?.txt ( 09.
start /wait regedit /e SystemDateTimeInfo.reg "HKEY_CURRENT_USER\Control Panel\International" 10.
for /f "tokens=1* delims==" %%i in ('type SystemDateTimeInfo.reg ^| findstr /i "iDate"') do set "iDate=%%j" 11.
del SystemDateTimeInfo.reg 12.
) 13.
14.
if defined iDate echo File represents order in date output. Delete it, if you change the regional settings on this computer. > DateOrder%iDate%.txt 15.
16.
for /f "tokens=1-3 delims=-/." %%a in ("%myDate%") do ( 17.
if exist "DateOrder0.txt" for %%i in ("JJ=%%c" "MM=%%a" "TT=%%b") do set %%i 18.
if exist "DateOrder1.txt" for %%i in ("JJ=%%c" "MM=%%b" "TT=%%a") do set %%i 19.
if exist "DateOrder2.txt" for %%i in ("JJ=%%a" "MM=%%b" "TT=%%c") do set %%i 20.
) 21.
22.
for /f "tokens=1-3 delims=:,." %%a in ("%time%") do for %%i in ("hh=%%a" "min=%%b" "ss=%%c") do set %%i 23.
set "hh=%hh: =0%" 24.
25.
echo Log %JJ%-%MM%-%TT% @ %hh%;%min%;%ss% 26.
pauseIch 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:
01.
@echo off 02.
set "alpha=beliebig" 03.
if not defined alpha echo alpha ist nicht definiert. 04.
set /a "beta=1%alpha%" 2>NUL 05.
if errorlevel 1 ( 06.
echo %alpha% ist weder Dezimal- noch Oktalzahl, aber m”glicherweise eine Hexadezimalzahl. 07.
) else ( 08.
echo %alpha% ist eine Dezimal- oder Oktalzahl, keinesfalls aber eine Hexadezimalzahl. 09.
) 10.
pauseDas 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/ ...
http://www.msfn.org/board/index.php?showt ...
http://www.msfn.org/board/CMD-vs-Bat-file ...
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.cf ...
»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!
01.
Habe ich der Übersicht wegen gelöscht, da im Wesentlichen so wie in EDITIERT 4Dass 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.
01.
@echo off 02.
03.
:: With the help of the tutorial 04.
:: http://www.administrator.de/Workshop_Batch_for_Runaways_Part_III_Datums-_und_Zeitvariablen_im_Batch.html 05.
set "myDate=%date%" 06.
for /f "tokens=2" %%i in ("%myDate%") do set "myDate=%%i" 07.
08.
if not exist DateOrder?.txt ( 09.
start /wait regedit /e SystemDateTimeInfo.reg "HKEY_CURRENT_USER\Control Panel\International" 10.
for /f "tokens=1* delims==" %%i in ('type SystemDateTimeInfo.reg ^| findstr /i "iDate"') do set "iDate=%%j" 11.
del SystemDateTimeInfo.reg 12.
) 13.
14.
if defined iDate echo File represents order in date output. Delete it, if you change the regional settings on this computer. > DateOrder%iDate%.txt 15.
16.
for /f "tokens=1-3 delims=-/." %%a in ("%myDate%") do ( 17.
if exist "DateOrder0.txt" for %%i in ("YY=%%c" "MM=%%a" "DD=%%b") do set %%i 18.
if exist "DateOrder1.txt" for %%i in ("YY=%%c" "MM=%%b" "DD=%%a") do set %%i 19.
if exist "DateOrder2.txt" for %%i in ("YY=%%a" "MM=%%b" "DD=%%c") do set %%i 20.
) 21.
22.
for %%i in (YY MM DD) do if not defined %%i goto :ViaVBS 23.
24.
set /a "test=1%YY%" 2>NUL 25.
if errorlevel 1 goto :ViaVBS 26.
set /a "test=1%MM%" 2>NUL 27.
if errorlevel 1 goto :ViaVBS 28.
set /a "test=1%DD%" 2>NUL 29.
if errorlevel 1 goto :ViaVBS 30.
31.
if 1000 GTR %YY% goto :ViaVBS 32.
if 12 LSS %MM% goto :ViaVBS 33.
if 31 LSS %DD% goto :ViaVBS 34.
35.
goto :output 36.
37.
:ViaVBS 38.
echo Wscript.Echo Year(Now)^&"-"^&Month(Now)^&"-"^&Day(Now) > ComputeDateVia.vbs 39.
for /f "tokens=1-3 delims=-" %%a in ('cscript //nologo ComputeDateVia.vbs') do ( 40.
for %%i in ("YY=%%a" "MM=%%b" "DD=%%c") do set %%i 41.
) 42.
if %MM% LSS 10 set "MM=0%MM%" 43.
if %DD% LSS 10 set "DD=0%DD%" 44.
del ComputeDateVia.vbs 45.
46.
:output 47.
for /f "tokens=1-3 delims=:,." %%a in ("%time%") do for %%i in ("hh=%%a" "min=%%b" "ss=%%c") do set %%i 48.
set "hh=%hh: =0%" 49.
50.
echo Log %YY%-%MM%-%DD% @ %hh%;%min%;%ss% 51.
pauseSchöne Grüße
dolsch
Noc06 schreibt am 19.06.2009 um 15:40:03 Uhr
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
Biber schreibt am 19.06.2009 um 16:46:59 Uhr
Moin Noc06,
danke für Deine Nachfrage.
Nein, case-sensitive Variablen unter Windows-Systemen.... die Einführung dieses Features hätte sicherlich höhere Wellen geschlagen.
Wenn es so wäre, dann dürften von x über Media- oder sonstige Sonderposten-Märkte verhökerten M$-Systemen circa x-3 nicht mehr über das Anmeldeskript hinauskommen.
Denn mehr als 3 AnwenderInnen haben sicherlich nicht die konsistente Klein- und Grossschreibung der Umgebungsvariablen verifiziert.
Wird an irgendetwas Banalerem hängen - ...vielleicht ist die Rückgabe oder Auswertung des VBS-Schnipsels (oben im Tut als %vbssnippet% temporär angelegt) marode.
Lass uns da mal ansetzen.
Der temporäre Gib-mal-ein-paar-Datumsdetails-VBS-Code sähe ja als VbsSnippet.vbs so aus:
....und würde beim Aufruf vom CMD-Prompt z.b. liefern (Eingabezeile durch ">" kenntlich gemacht):
Mit dieser grottig kryptischen Ausgabezeile kann natürlich niemand etwas anfangen, ...
ausgenommen die FOR/F-Anweisung. die ich im Tut-beispiel dieses Geraffel umspeichern lasse.
Wenn wir das am CMD-Prompt nachkaspern, sieht das so aus:
....wichtig und von Dir bitte zu Testen ist in dieser Ausgabe natürlich speziell der DoW-Wert "5" für den zu erwartenden Donnerstag.
Denn aus diesem Wert "5" wird ja so etwas wie "Do" oder "Thu" abgeleitet.
Bitte überprüfe das mal eben - wenn dort kein Fehler zu identifizieren ist, lass uns per PN weiterforschen.
Sollte aber ein lösbares Problem sein.
Grüße
Biber
danke für Deine Nachfrage.
Kann es sein, daß ...[..] der Code also casesensitv ist)?
Nein, case-sensitive Variablen unter Windows-Systemen.... die Einführung dieses Features hätte sicherlich höhere Wellen geschlagen.
Wenn es so wäre, dann dürften von x über Media- oder sonstige Sonderposten-Märkte verhökerten M$-Systemen circa x-3 nicht mehr über das Anmeldeskript hinauskommen.
Denn mehr als 3 AnwenderInnen haben sicherlich nicht die konsistente Klein- und Grossschreibung der Umgebungsvariablen verifiziert.
Wird an irgendetwas Banalerem hängen - ...vielleicht ist die Rückgabe oder Auswertung des VBS-Schnipsels (oben im Tut als %vbssnippet% temporär angelegt) marode.
Lass uns da mal ansetzen.
Der temporäre Gib-mal-ein-paar-Datumsdetails-VBS-Code sähe ja als VbsSnippet.vbs so aus:
01.
' ---- vbsSnippet.vbs 02.
If WScript.arguments.count = 1 Then 03.
dDate=WScript.arguments.item(0) 04.
Else 05.
dDate=Date 06.
End If 07.
Wscript.Echo "x," & DatePart("ww",dDate,vbSunday,vbFirstFourDays) & "," & _ 08.
DatePart("ww",dDate) & "," & DatePart("w",dDate) & "," & DatePart("y",dDate)01.
>cscript Vbssnippet.vbs 10.12.2009 02.
x,49,50,5,344ausgenommen die FOR/F-Anweisung. die ich im Tut-beispiel dieses Geraffel umspeichern lasse.
Wenn wir das am CMD-Prompt nachkaspern, sieht das so aus:
01.
>for /f "delims=, tokens=2-5" %i in ('cscript Vbssnippet.vbs 10.12.2009') do @echo KW:%i OSKW:%j DoW:%k DoY:%l 02.
KW:49 OSKW:50 DoW:5 DoY:344Denn aus diesem Wert "5" wird ja so etwas wie "Do" oder "Thu" abgeleitet.
Bitte überprüfe das mal eben - wenn dort kein Fehler zu identifizieren ist, lass uns per PN weiterforschen.
Sollte aber ein lösbares Problem sein.
Grüße
Biber
Noc06 schreibt am 19.06.2009 um 18:22:23 Uhr
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?
Biber schreibt am 19.06.2009 um 20:36:33 Uhr
Moin Noc06,
na, das ist ja heftig.... ich werde die Redmonder nie verstehen, fürchte ich. *kopfschüttel*
Okay, ich werde (zeitnah) mal die Groß/Kleinschreibung in meinem Beispielschnipsel oben anpassen.
Zu Deiner Zusatzfrage mit dem Monatsletzten... klar geht das.
Is' sich ja irgendetwas logisch Herleitbares und von daher einfach runterzuskripten.
Bzw. wenn Du es schaffst, die logische Berechnung zu formulieren, dann kann es jede/r 11jährige runtertippseln in der Skriptsprache, die gerade am Angesagtesten ist.
Logisch/abstrakt formuliert wäre doch eine der möglichen Berechnungen:
In dem VBSnipsel von vorhin kannst Du ja mal die letzten 2 Zeile ersetzen durch diese:
und Testen.
.....works as designed..
Grüße und danke fürs Mitforschen
Biber
na, das ist ja heftig.... ich werde die Redmonder nie verstehen, fürchte ich. *kopfschüttel*
Okay, ich werde (zeitnah) mal die Groß/Kleinschreibung in meinem Beispielschnipsel oben anpassen.
Zu Deiner Zusatzfrage mit dem Monatsletzten... klar geht das.
Is' sich ja irgendetwas logisch Herleitbares und von daher einfach runterzuskripten.
Bzw. wenn Du es schaffst, die logische Berechnung zu formulieren, dann kann es jede/r 11jährige runtertippseln in der Skriptsprache, die gerade am Angesagtesten ist.
Logisch/abstrakt formuliert wäre doch eine der möglichen Berechnungen:
- nimm das Datum (meinetwegen "10.12.2009" wie im Beispiel)
- gehe auf den ersten Tag dieses Datums (ist trivial->ist "01." + Monat +Jahr
- Addiere einen Monat ("01.12.2009" + 1 Monat = "01.01.2010"
- Ziehe einen Tag ab --> "31.12.2009"
In dem VBSnipsel von vorhin kannst Du ja mal die letzten 2 Zeile ersetzen durch diese:
01.
... 02.
' Monatsletzter: 03.
Wscript.echo dateAdd ("d", -1, dateAdd("m", 1, "01." & Month(dDate) & "." &year(ddate)))01.
>cscript Vbssnippet.vbs 10.12.2009 02.
31.12.09.....works as designed..
Grüße und danke fürs Mitforschen
Biber
Biber schreibt am 20.06.2009 um 01:40:58 Uhr
Moin Noc06,
kleiner und peinlicher Nachtrag der Ordnung halber.
Der RPC (Redmonder PraktikantInnen-Clan) ist in diesem Fall gänzlich unschuldig
Und ich zieh auch meine implizite Behauptung zurück, dass sich die Anzahl der Programmierfehler in M$-Betriebssystemen proportional zur Bit-Breite verhält.
War in diesem Fall ein klarer Schusselfehler von mir... vermutlich bei einer der letzten Aktualisierungen des Sourcecodes reingepfuscht.
Der Blöd-Bug war einfach in der jetzigen Code-Zeile 127, die endet auf:
Und "find /i" macht nun mal einen Vergleich ohne Berücksichtigung der Klein/Grossschreibung.
Defaultverhalten allerdings -also ohne /i - ist der exakte Vergleich.
Und der geht natürlich bei "Ist denn 'cDow' gleich 'cDoW' ?" in die Grütze.
Oder, um einen forenbekannten Bätcher zu zitieren:
"...works as designed..."
Grüße
Biber
kleiner und peinlicher Nachtrag der Ordnung halber.
Der RPC (Redmonder PraktikantInnen-Clan) ist in diesem Fall gänzlich unschuldig
Und ich zieh auch meine implizite Behauptung zurück, dass sich die Anzahl der Programmierfehler in M$-Betriebssystemen proportional zur Bit-Breite verhält.
War in diesem Fall ein klarer Schusselfehler von mir... vermutlich bei einer der letzten Aktualisierungen des Sourcecodes reingepfuscht.
Der Blöd-Bug war einfach in der jetzigen Code-Zeile 127, die endet auf:
if defined %%i set %%i|find /i "%%i="
....dass dort bis vorhin ein ....find "%%i="... stand. Ohne den Schalter "/i"Und "find /i" macht nun mal einen Vergleich ohne Berücksichtigung der Klein/Grossschreibung.
Defaultverhalten allerdings -also ohne /i - ist der exakte Vergleich.
Und der geht natürlich bei "Ist denn 'cDow' gleich 'cDoW' ?" in die Grütze.
Oder, um einen forenbekannten Bätcher zu zitieren:
"...works as designed..."
Grüße
Biber
Noc06 schreibt am 20.06.2009 um 10:54:04 Uhr
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.
Gruß und schönes WE
Noc06
NeonZero schreibt am 26.06.2010 um 10:01:39 Uhr
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 %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):
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):
01.
:: Algorithmus frei nach [http://www.commandline.co.uk/lib/treeview/index.php] 02.
:: '-->Klick: Batch Function Library/Date and Time Functions/DateToDOW 03.
... 04.
set yy=42 & set mm=05 & set dd=23 & set TwoDigitYearMax=70 05.
if 1%yy% LSS 200 if 1%yy% LSS 1%TwoDigitYearMax% (set yy=20%yy%) else (set yy=19%yy%) 06.
... 07.
set /a dd=100%dd%%%100,mm=100%mm%%%100 08.
set /a z=14-mm,z/=12,y=yy+4800-z,m=mm+12*z-3,dow=153*m+2 09.
set /a dow=dow/5+dd+y*365+y/4-y/100+y/400-2472630,dow%%=7,dow+=1 10.
...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
NeonZero schreibt am 27.06.2010 um 08:51:06 Uhr
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 ..., 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:
01.
@echo off & setlocal EnableExtensions 02.
03.
::Das Datum "tag.monat.jahr" in seine Bestandteile zerlegen: 04.
if "%~1" == "" ( ::kein Parameter angegeben; das aktuelle Datum %DATE% soll verwendet werden... 05.
for /f "tokens=1-3 delims=." %%a in ("%DATE:* =%") do set _dd=%%a & set _mm=%%b & set _yy=%%c 06.
) else ( ::das übergebene Datum verwenden... 07.
for /f "tokens=1-3 delims=." %%a in ("%~1") do set _dd=%%a & set _mm=%%b & set _yy=%%c 08.
) 09.
10.
::Rufen wir den Code von Ritchie Lawrence auf, um den Wochentag des Datums zu berechnen: 11.
call :DateToDOW %_yy% %_mm% %_dd% _WoTgNr 12.
13.
::Die Wochentagsnummer (1 bis 7) in den Namen des Wochentags umwandeln: 14.
for /f "tokens=%_WoTgNr%" %%a in ("Montag Dienstag Mittwoch Donnerstag Freitag Samstag Sonntag") do set _Wochentag=%%a 15.
16.
::Wochentag ausgeben 17.
echo Der gesuchte Wochentag ist ein: %_Wochentag% 18.
19.
goto :EOF ::Springe an das Ende der Datei, also verlasse die Batch (weil fertig) 20.
21.
:DateToDOW %yy% %mm% %dd% dow 22.
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: 23.
:: By: Ritchie Lawrence, 2003-04-29. Version 1.1 24.
:: Func: Creates a day of week number from a calendar date, where 1 = Mon 25.
:: and 7 = Sun. For NT4/2000/XP/2003. 26.
:: Args: %1 year component to be converted, 2 or 4 digits (by val) 27.
:: %2 month component to be converted, leading zero ok (by val) 28.
:: %3 day of month to be converted, leading zero ok (by val) 29.
:: %4 var to receive day of week number, 1 to 7 (by ref) 30.
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: 31.
set yy=%1&set mm=%2&set dd=%3 32.
if 1%yy% LSS 200 if 1%yy% LSS 170 (set yy=20%yy%) else (set yy=19%yy%) 33.
set /a dd=100%dd%%%100,mm=100%mm%%%100 34.
set /a z=14-mm,z/=12,y=yy+4800-z,m=mm+12*z-3,dow=153*m+2 35.
set /a dow=dow/5+dd+y*365+y/4-y/100+y/400-2472630,dow%%=7,dow+=1 36.
set %4=%dow% 37.
exit /b 0 38.
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: 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+2
Das 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+=1
Klarer 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+2
set /a dow=dow/5+dd+y*365+y/4-y/100+y/400-2472630,dow%%=7,dow+=1
y=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+=1
Damit 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:
01.
@echo off & setlocal EnableExtensions 02.
03.
call :FncPartDate -f DD/MM/YY -0 _Year _Month _Day %1 &::Das übergebene Datum in seine Bestandteile zerlegen 04.
05.
echo ------------------------------------------------------------------------------ 06.
echo # Wochentagsberechnung stur nach dem Gregorianischen Kalendersystem: # 07.
echo ------------------------------------------------------------------------------ 08.
set /a _WDNr=0 09.
call :DateToDOW %_Year% %_Month% %_Day% _WDNr 10.
call :FncWeekdayNrToName %_WDNr% _WDName 11.
echo Der gesuchte Wochentag ist ein: %_WDName% ^(laut DateToDOW^) 12.
13.
set /a _WDNr=0 14.
call :FncDateToWeekdayNr_Hack_00 %_Year% %_Month% %_Day% _WDNr 15.
call :FncWeekdayNrToName %_WDNr% _WDName 16.
echo Der gesuchte Wochentag ist ein: %_WDName% ^(laut FncDateToWeekdayNr_Hack_00^) 17.
18.
set /a _WDNr=0 19.
call :FncDateToWeekdayNr_Hack_01 %_Year% %_Month% %_Day% _WDNr 20.
call :FncWeekdayNrToName %_WDNr% _WDName 21.
echo Der gesuchte Wochentag ist ein: %_WDName% ^(laut FncDateToWeekdayNr_Hack_01^) 22.
23.
set /a _WDNr=0 24.
call :FncDateToWeekdayNr_Hack_10 %_Year% %_Month% %_Day% _WDNr 25.
call :FncWeekdayNrToName %_WDNr% _WDName 26.
echo Der gesuchte Wochentag ist ein: %_WDName% ^(laut FncDateToWeekdayNr_Hack_10^) 27.
28.
set /a _WDNr=0 29.
call :FncDateToWeekdayNr_Hack_11 %_Year% %_Month% %_Day% _WDNr 30.
call :FncWeekdayNrToName %_WDNr% _WDName 31.
echo Der gesuchte Wochentag ist ein: %_WDName% ^(laut FncDateToWeekdayNr_Hack_11^) 32.
33.
echo. 34.
echo ------------------------------------------------------------------------------ 35.
echo # Berechnung des Julianischen Tages stur nach dem Gregorian. Kalendersystem: # 36.
echo ------------------------------------------------------------------------------ 37.
set /a _JDay=0 38.
call :FncDateToJulianDay_Hack_00 %_Year% %_Month% %_Day% _JDay 39.
echo Umrechnung Datum nach JulianDay: %_JDay% ^(laut FncDateToJulianDay_Hack_00^) 40.
set /a _JDay=0 41.
call :FncDateToJulianDay_Hack_01 %_Year% %_Month% %_Day% _JDay 42.
echo Umrechnung Datum nach JulianDay: %_JDay% ^(laut FncDateToJulianDay_Hack_01^) 43.
set /a _JDay=0 44.
call :FncDateToJulianDay_Hack_10 %_Year% %_Month% %_Day% _JDay 45.
echo Umrechnung Datum nach JulianDay: %_JDay% ^(laut FncDateToJulianDay_Hack_10^) 46.
echo. 47.
set /a _WDNr=0 48.
call :FncJulianDayToWeekdayNr %_JDay% _WDNr 49.
call :FncWeekdayNrToName %_WDNr% _WDName 50.
echo Berechneter Wochentag aus JulianDay %_JDay%: %_WDName% 51.
echo. 52.
echo ------------------------------------------------------------------------------ 53.
echo # Julian Day bis 04.10.1582 nach dem Julianischen, dann Gregorian. Kalender: # 54.
echo ------------------------------------------------------------------------------ 55.
set /a _JDay=0 56.
call :FncDateToJulianDay_Hack_11 %_Year% %_Month% %_Day% _JDay 57.
echo. 58.
echo Umrechnung Datum nach JulianDay: %_JDay% ^(laut FncDateToJulianDay_Hack_11^) 59.
echo. 60.
set /a _WDNr=0 61.
call :FncJulianDayToWeekdayNr %_JDay% _WDNr 62.
call :FncWeekdayNrToName %_WDNr% _WDName 63.
echo Berechneter Wochentag aus JulianDay %_JDay%: %_WDName% 64.
65.
goto :EOF ::Springe an das Ende der Datei, also verlasse die Batch (weil fertig) 66.
67.
:FncPartDate ::Function returns the year, month and day of date (parts date into its components) 68.
::Options: -f DD/MM/YY or YY/MM/DD or MM/DD/YY /*Input-Date-Format by YY=Year, MM=Month, DD=Day*/ 69.
:: -yy <SplitYear> /*if e.g. SplitYaer==70 then double-digit-year form 00 to 69 make to 20xx, else 19xx*/ 70.
:: -0 /* remove leading zeros by returns; on this option the 0xxxx-year can have no more than 5 digits */ 71.
::Parameters: <VarReturnsYear> <VarReturnsMonth> <VarReturnsDay> [date or nothing for current date] 72.
::Example: call :FncPartDate -f DD/MM/YY -yy 70 -0 _Year _Month _Day "05.05.55" /*returns _Year=2055, _Day=5 */ 73.
:: call :FncPartDate -f DD/MM/YY _Year _Month _Day "05.05.55" /*returns _Year=55, _Day=05*/ 74.
:: call :FncPartDate -f YY/MM/DD -yy 70 _Year _Month _Day "84.05.05" /*returns _Year=1984, _Day=05*/ 75.
:: call :FncPartDate -f YY/MM/DD -0 _Year _Month _Day "84.05.05" /*returns _Year=84, _Day=5 */ 76.
::################################################################################################################### 77.
setlocal EnableDelayedExpansion 78.
if "%~1" == "-f" ( set _#2=%~2 &set "_F1=_!_#2:~0,2!" &set "_F2=_!_#2:~3,2!" &set "_F3=_!_#2:~6,2!" &shift &shift 79.
) else ( set "_F1=_DD" &set "_F2=_MM" &set "_F3=_YY" ) 80.
if "%~1" == "-yy" ( set "_SpYY=%~2" &shift &shift ) else ( set "_SpYY=" ) 81.
if "%~1" == "-0" ( set "_RLZ=on" &shift ) else ( set "_RLZ=" ) 82.
83.
if "%~4" == "" ( set "_MyDate=%DATE:* =%" ) else ( set "_MyDate=%~4" ) 84.
for /f "tokens=1-3 delims=./ " %%a in ("%_MyDate%") do set "%_F1%=%%a" & set "%_F2%=%%b" & set "%_F3%=%%c" 85.
86.
if "%_YY:~0,1%" == "-" (set "_YY=%_YY:~1,100%" &set "_NS=-") else (set "_NS=") &::Vorzeichen entfernen 87.
if defined _RLZ ( ::führende Nullen entfernen 88.
if "%_YY:~0,1%" == "0" set /a _YY"=(100000%_YY%)%%100000" 89.
if "%_MM:~0,1%" == "0" set /a _MM"=(100000%_MM%)%%100000" 90.
if "%_DD:~0,1%" == "0" set /a _DD"=(100000%_DD%)%%100000" 91.
) 92.
set "_YY=%_NS%%_YY%" &::Vorzeichen wieder einfügen 93.
94.
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%) 95.
endlocal & set "%~1=%_YY%" & set "%~2=%_MM%" & set "%~3=%_DD%" 96.
exit /b 0 97.
98.
:FncWeekdayNrToName ::Function returns the name of the weekday from weekday number 99.
::Options: -s "Monday Tuesday Wednesday Thursday Friday Saturday Sunday unknown" /*use my own weekdayname-string*/ 100.
::Parameters: <weekday-number form 1(=Monday) to 7(=Sunday)> <VarReturnsWeekdayName> 101.
::Example: call :FncWeekdayNrToName -s "Mo Tu We Th Fr Sa Su unknown" 5 _Name /*returns _Name="Fr" */ 102.
:: call :FncWeekdayNrToName 5 _Name /*returns _Name="Freitag"*/ 103.
::################################################################################################################### 104.
setlocal EnableDelayedExpansion 105.
if "%~1" == "-s" ( set "_WNS=%~2" &shift &shift 106.
) else ( set "_WNS=Montag Dienstag Mittwoch Donnerstag Freitag Samstag Sonntag unbekannt" ) 107.
set /a _WeekdayNumber"=%~1" 108.
if %_WeekdayNumber% LSS 1 set /a _WeekdayNumber"=8" 109.
if %_WeekdayNumber% GTR 7 set /a _WeekdayNumber"=8" 110.
for /f "tokens=%_WeekdayNumber%" %%a in ("%_WNS%") do set _WeekdayName=%%a 111.
endlocal & set "%~2=%_WeekdayName%" 112.
exit /b 0 113.
114.
:FncDateToWeekdayNr_Hack_00 ::Eigene Lawrence-Variante ohne y+=4800'er Umweg 115.
::Parameters: <Year> <Month> <Day> <VarNameToReturnWeekdayNr> 116.
::Note: The date less than 01/01/1970 is invalid 117.
::Example: call :FncDateToWeekdayNr 5555 05 05 _DayOfWeekNr 118.
::#################### Berechnung des Wochentages vom dd.mm des Jahres 1970 bis 5881579 ####################### 119.
::Nicht fuer den produktiven Einsatz gedacht und geeignet; nur zum Testen. 120.
::Algorithmus frei nach http://www.commandline.co.uk/lib/treeview/index.php, Autor: Ritchie Lawrence 121.
set _MyYear=%1&set _MyMonth=%2&set _MyDay=%3 122.
if %_MyYear% LSS 1970 exit /b 1 &::Berechnung nur bis 29.12.1969 möglich 123.
::Mit den vorhandenen Daten frei nach dem Algorithmus von Ritchie Lawrence den Wochentag berechnen: 124.
if %_MyMonth% LEQ 2 ( set _bJanOrFeb=1 ) else ( set _bJanOrFeb=0 ) &::Jan or Feb = 1, sonst 0 125.
set /a _MonthsFactor"=(12*_bJanOrFeb)+(_MyMonth-3)" &::im Mär=0, Apr=1 ... Feb=11 126.
set /a _ElapsedDaysUntilMyMonths"=(153*_MonthsFactor+2)/5" &::im Mär=0, Apr=31 ... Feb=337 127.
set /a _ElapsedDaysOfMyYear"=_ElapsedDaysUntilMyMonths+_MyDay" &::+ verstrichene Tage des akt. Monats 128.
set /a _MyYear"-=_bJanOrFeb" &::Jan und Feb liegen hier im verg. Jahr 129.
set /a _ElapsedDaysUntilMyYear"=_MyYear*365 + (_MyYear/4 - _MyYear/100 + _MyYear/400)" 130.
set /a _Weekday"=(_ElapsedDaysUntilMyYear+_ElapsedDaysOfMyYear - 719466)%%7 + 1" 131.
set %4=%_Weekday% 132.
exit /b 0 133.
134.
:FncDateToWeekdayNr_Hack_01 ::Lawrence-Variante ohne y+=4800'er Umweg & ohne 29.12.1969-Datumsgrenze 135.
::Parameters: <Year> <Month> <Day> <VarNameToReturnWeekdayNr> 136.
::Example: call :FncDateToWeekdayNr 5555 05 05 _DayOfWeekNr 137.
::################ Berechnung des Wochentages vom dd.mm des Jahres -2147483648 bis 5879609 #################### 138.
::Nicht fuer den produktiven Einsatz gedacht und geeignet; nur zum Testen. 139.
set _MyYear=%1&set _MyMonth=%2&set _MyDay=%3 140.
141.
if %_MyYear% EQU 0 ( ::Jahr 0000 wurde angegeben; ungültige Jahreszahl... 142.
echo FncDateToWeekdayNr_Hack01: Error^^! 143.
echo On 31.12.0001 before Christ ^(BC^) immediately follows the 01.01.0001 AD ^(CE^). 144.
echo The year 0000 does not exist. Use -0001 do you mean the year 1 before Christ. 145.
exit /b 1 146.
) 1>&2 147.
if %_MyYear% LSS 0 set /a _MyYear"+=1" &::Das Jahr -1 liegt rechnerisch im Jahr 0, -2 im Jahr -1, etc. 148.
:FncDateToWeekdayNr_Hack01_YearLoop &::negative Jahreszahl in eine gültige positive Zahl umwandeln... 149.
if %_MyYear% LSS 1 set /a _MyYear"+=4000000" &::...alle 400 J. wiederh. sich die WoTage (*10000 ist schneller) 150.
if %_MyYear% LSS 1 goto :FncDateToWeekdayNr_Hack01_YearLoop &::LSS 1 (statt 0) weil Jahr im JanOrFeb sonst -1 151.
152.
::Im Folgenden gilt es die bereits verstrichenen Tage des Jahres im März-bis-Februar-Jahresmodell zu berechnen. 153.
if %_MyMonth% LEQ 2 ( set _bJanOrFeb=1 ) else ( set _bJanOrFeb=0 ) &::Jan or Feb = 1, sonst 0 154.
::Algorithmus frei nach http://www.commandline.co.uk/lib/treeview/index.php, Autor: Ritchie Lawrence 155.
set /a _MonthsFactor"=(12*_bJanOrFeb)+(_MyMonth-3)" &::im Mär=0, Apr=1 ... Feb=11 156.
set /a _ElapsedDaysUntilMyMonths"=(153*_MonthsFactor+2)/5" &::im Mär=0, Apr=31 ... Feb=337 157.
set /a _ElapsedDaysOfMyYear"=_ElapsedDaysUntilMyMonths+_MyDay" &::+ verstrichene Tage des akt. Monats 158.
::Nun gilt es die Tage der vergangenen Jahre bis zum rechnerischen Jahr 0000 zurückzuberechenen. 159.
set /a _MyYear"-=_bJanOrFeb" &::Jan und Feb liegen hier im verg. Jahr 160.
set /a _ElapsedDaysUntilMyYear"=_MyYear*365 + (_MyYear/4 - _MyYear/100 + _MyYear/400)" 161.
::Wochentag=(verstrichene Tage + 1 Tag /*damit der Ursprungstag der Berechnung ein Montag ist*/) mod 7 + 1 162.
set /a _Weekday"=(_ElapsedDaysUntilMyYear+_ElapsedDaysOfMyYear + 1)%%7 + 1" 163.
set %4=%_Weekday% 164.
exit /b 0 165.
166.
:FncDateToWeekdayNr_Hack_10 ::Ein gänzlich anderer Weg... 167.
::Parameters: <Year> <Month> <Day> <VarNameToReturnWeekdayNr> 168.
::Example: call :FncDateToWeekdayNr 5555 05 05 _DayOfWeekNr 169.
::############## Berechnung des Wochentages vom dd.mm des Jahres -2147483648 bis 2147483641 ################### 170.
::Nicht fuer den produktiven Einsatz gedacht und geeignet; nur zum Testen. 171.
::Algorithmus frei nach http://de.wikipedia.org/w/index.php?title=Wochentagsberechnung&oldid=75828222 172.
set _MyYear=%1&set _MyMonth=%2&set _MyDay=%3 173.
174.
if %_MyYear% EQU 0 ( ::Jahr 0000 wurde angegeben; ungültige Jahreszahl... 175.
echo FncDateToWeekdayNr_Hack10: Error^^! 176.
echo On 31.12.0001 before Christ ^(BC^) immediately follows the 01.01.0001 AD ^(CE^). 177.
echo The year 0000 does not exist. Use -0001 do you mean the year 1 before Christ. 178.
exit /b 1 179.
) 1>&2 180.
if %_MyYear% LSS 0 set /a _MyYear"+=1" &::Das Jahr -1 liegt rechnerisch im Jahr 0, -2 im Jahr -1, etc. 181.
:FncDateToWeekdayNr_Hack10_YearLoop &::negative Jahreszahl in eine gültige positive Zahl umwandeln... 182.
if %_MyYear% LSS 1 set /a _MyYear"+=4000000" &::...alle 400 J. wiederh. sich die WoTage (*10000 ist schneller) 183.
if %_MyYear% LSS 1 goto :FncDateToWeekdayNr_Hack10_YearLoop &::LSS 1 (statt 0) weil Jahr im JanOrFeb sonst -1 184.
185.
set /a _MyDayID"=_MyDay%%7" &::Tageskennziffer ermitteln 186.
for /f "tokens=%_MyMonth%" %%a in ("0 3 3 6 1 4 6 2 5 0 3 5") do set _MyMonthID=%%a 187.
188.
if %_MyMonth% LEQ 2 ( set _bJanOrFeb=1 ) else ( set _bJanOrFeb=0 ) 189.
set /a _MyYear"-=_bJanOrFeb" &::Im Jan or Feb Schaltjahr nur bis zum verganenen Jahr berechnen 190.
set /a _MyLeapYearID"=(_MyYear/4 - _MyYear/100 + _MyYear/400)%%7" &::Schaltjahreskennziffer ermitteln 191.
192.
set /a _Weekday"=(_MyDayID + _MyMonthID + _MyYear+_bJanOrFeb + _MyLeapYearID -2)%%7 + 1" &::Wochentag berechnen 193.
set %4=%_Weekday% 194.
exit /b 0 195.
196.
:FncDateToWeekdayNr_Hack_11 ::Ein eigener Weg; die Idee ist aus den anderen Ansätzen heraus entstanden 197.
::Parameters: <Year> <Month> <Day> <VarNameToReturnWeekdayNr> 198.
::Example: call :FncDateToWeekdayNr 5555 05 05 _DayOfWeekNr 199.
::############## Berechnung des Wochentages vom dd.mm des Jahres -2147483648 bis 1728356768 ################### 200.
::Nicht fuer den produktiven Einsatz gedacht und geeignet; nur zum Testen. 201.
set _MyYear=%1&set _MyMonth=%2&set _MyDay=%3 202.
203.
if %_MyYear% EQU 0 ( ::Jahr 0000 wurde angegeben; ungültige Jahreszahl... 204.
echo FncDateToWeekdayNr_Hack10: Error^^! 205.
echo On 31.12.0001 before Christ ^(BC^) immediately follows the 01.01.0001 AD ^(CE^). 206.
echo The year 0000 does not exist. Use -0001 do you mean the year 1 before Christ. 207.
exit /b 1 208.
) 1>&2 209.
if %_MyYear% LSS 0 set /a _MyYear"+=1" &::Das Jahr -1 liegt rechnerisch im Jahr 0, -2 im Jahr -1, etc. 210.
:FncDateToWeekdayNr_Hack11_YearLoop &::negative Jahreszahl in eine gültige positive Zahl umwandeln... 211.
if %_MyYear% LSS 1 set /a _MyYear"+=4000000" &::...alle 400 J. wiederh. sich die WoTage (*10000 ist schneller) 212.
if %_MyYear% LSS 1 goto :FncDateToWeekdayNr_Hack11_YearLoop &::LSS 1 (statt 0) weil Jahr im JanOrFeb sonst -1 213.
214.
::Verstrichene Monatstage des Jahres mit einem Algorithmus eines März-bis-Februar-Jahresmodells berechnen... 215.
if %_MyMonth% LEQ 2 ( set _bJanOrFeb=1 ) else ( set _bJanOrFeb=0 ) &::Jan or Feb = 1, sonst 0 216.
::Algorithmus frei nach http://www.commandline.co.uk/lib/treeview/index.php, Autor: Ritchie Lawrence 217.
set /a _MonthsFactor"=(12*_bJanOrFeb)+(_MyMonth-3)" &::im Mär=0, Apr=1 ... Jan=10, Feb=11 218.
set /a _ElapsedDaysUntilMyMonths"=(153*_MonthsFactor+2)/5" &::im Mär=0, Apr=31 ... Jan=306, Feb=337 219.
220.
set /a _ElapsedDaysUntilMyMonths"+=59 - 365*_bJanOrFeb" &::zurückrechnen in das gängige Jahresmodell 221.
:: ab März+=59, die Tage Jan+Feb<--' '-->nur im Jan or Feb: - (59 + 306_MärzBisJanTage_des_März-bis-Feb-Modells) 222.
223.
set /a _MyYear"-=_bJanOrFeb" &::im Jan/Feb Schaltjahr nur bis Jahr-1 berechnen 224.
set /a _MyLeapYears"=(_MyYear/4 - _MyYear/100 + _MyYear/400)" &::Schaltjahre ermitteln 225.
226.
::Das rechnerische Jahr 0 beginnt an einem Samstag. Jedes darauf folgende Jahr erhöht den Tag des Jahresbeginns 227.
::um 1 Tag. Jedes Schaltjahr erhöht ihn um 1 weiteren Tag. Daher: (Tage+Monatstage + Jahre + Schaltjahre) mod 7 228.
::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. 229.
set /a _Weekday"=(_MyDay+_ElapsedDaysUntilMyMonths + _MyYear+_bJanOrFeb + _MyLeapYears -2)%%7 + 1" 230.
set %4=%_Weekday% 231.
exit /b 0 232.
233.
:FncJulianDayToWeekdayNr 234.
::Parameters: <JulianDayNr> <VarNameToReturnWeekdayNr> 235.
::############################################################################################################# 236.
setlocal EnableDelayedExpansion 237.
set _JD=%~1 238.
set /a _WDNr"=_JD%%7+1" 239.
if %_WDNr% LSS 1 set /a _WDNr"+=7" &::für Tage vor dem ersten JulianDay 240.
endlocal & set "%~2=%_WDNr%" 241.
exit /b 0 242.
243.
:FncDateToJulianDay_Hack_00 ::Umrechnung eines Datums (Gregorianischem Kalender) auf den juliansichen Tag 244.
::Parameters: <Year> <Month> <Day> <VarNameToReturnJulianDayNr> 245.
::Example: call :FncDateToJulianDay 5555 05 05 _JulianDay 246.
::############################################################################################################# 247.
::Nicht fuer den produktiven Einsatz gedacht und geeignet; nur zum Testen. 248.
::Algorithmus frei nach http://docs.kde.org/stable/de/kdeedu/kstars/ai-julianday.html; hier umgesetzt auf batch 249.
set _MyYear=%1&set _MyMonth=%2&set _MyDay=%3 250.
251.
if %_MyYear% EQU 0 ( ::Jahr 0000 wurde angegeben; ungültige Jahreszahl... 252.
echo FncDateToJulianDay_Hack00: Error^^! 253.
echo On 31.12.0001 before Christ ^(BC^) immediately follows the 01.01.0001 AD ^(CE^). 254.
echo The year 0000 does not exist. Use -0001 do you mean the year 1 before Christ. 255.
exit /b 1 256.
) 1>&2 257.
if %_MyYear% LSS 0 set /a _MyYear"+=1" &::Das Jahr -1 liegt rechnerisch im Jahr 0, -2 im Jahr -1, etc. 258.
259.
::das Datum auf den Julianischen Tag umrechnen: 260.
set /a _JD"=_MyDay-32075 + 1461*(_MyYear+4800 + (_MyMonth-14)/12)/4" 261.
set /a _JD"+=367*(_MyMonth-2 - (_MyMonth-14)/12*12)/12" 262.
set /a _JD"-=3*((_MyYear + 4900 + (_MyMonth - 14)/12)/100)/4" 263.
set /a %~4"=%_JD%" &::Hinweis: JulianDay 0 == 1. Jan. 4713 v.u.Z. julianisch == 24. Nov. 4714 v.u.Z. greogorianisch 264.
exit /b 0 265.
266.
:FncDateToJulianDay_Hack_01 ::Umrechnung eines Datums (Gregorianischem Kalender) auf den juliansichen Tag 267.
::Parameters: <Year> <Month> <Day> <VarNameToReturnJulianDayNr> 268.
::Example: call :FncDateToJulianDay 5555 05 05 _JulianDay 269.
::############################################################################################################# 270.
::Nicht fuer den produktiven Einsatz gedacht und geeignet; nur zum Testen. 271.
::Algorithmus frei nach http://www.commandline.co.uk/lib/treeview/index.php, Autor: Ritchie Lawrence 272.
set _MyYear=%1&set _MyMonth=%2&set _MyDay=%3 273.
274.
if %_MyYear% EQU 0 ( ::Jahr 0000 wurde angegeben; ungültige Jahreszahl... 275.
echo FncDateToJulianDay_Hack01: Error^^! 276.
echo On 31.12.0001 before Christ ^(BC^) immediately follows the 01.01.0001 AD ^(CE^). 277.
echo The year 0000 does not exist. Use -0001 do you mean the year 1 before Christ. 278.
exit /b 1 279.
) 1>&2 280.
if %_MyYear% LSS 0 set /a _MyYear"+=1" &::Das Jahr -1 liegt rechnerisch im Jahr 0, -2 im Jahr -1, etc. 281.
282.
::Im Folgenden gilt es die bereits verstrichenen Tage des Jahres im März-bis-Februar-Jahresmodell zu berechnen. 283.
if %_MyMonth% LEQ 2 ( set _bJanOrFeb=1 ) else ( set _bJanOrFeb=0 ) &::Jan or Feb = 1, sonst 0 284.
set /a _MonthsFactor"=(12*_bJanOrFeb)+(_MyMonth-3)" &::im Mär=0, Apr=1 ... Feb=11 285.
set /a _ElapsedDaysUntilMyMonths"=(153*_MonthsFactor+2)/5" &::im Mär=0, Apr=31 ... Feb=337 286.
set /a _ElapsedDaysOfMyYear"=_ElapsedDaysUntilMyMonths+_MyDay" &::+ verstrichene Tage des akt. Monats 287.
::Nun gilt es die Tage der vergangenen Jahre bis zum Jahr 0000 zurückzuberechenen. 288.
set /a _MyYear"-=_bJanOrFeb" &::Jan und Feb liegen hier im verg. Jahr 289.
if %_MyYear% LSS 0 set /a _ElapsedDaysOfMyYear"-=1" 290.
set /a _ElapsedDaysUntilMyYear"=_MyYear*365 + (_MyYear/4 - _MyYear/100 + _MyYear/400)" 291.
set /a _JD"=(_ElapsedDaysUntilMyYear+_ElapsedDaysOfMyYear+1721119)" &::+Tage vom 01. März 0000 bis JulianDay 0 292.
set /a %~4"=%_JD%" &::Hinweis: JulianDay 0 == 1. Jan. 4713 v.u.Z. julianisch == 24. Nov. 4714 v.u.Z. greogorianisch 293.
exit /b 0 294.
295.
:FncDateToJulianDay_Hack_10 ::Ein anderer Weg... Umrechnung Datum auf den juliansichen Tag 296.
::Parameters: <Year> <Month> <Day> <VarNameToReturnJulianDayNr> 297.
::Example: call :FncDateToJulianDay 5555 05 05 _JulianDay 298.
::############################################################################################################# 299.
::Nicht fuer den produktiven Einsatz gedacht und geeignet; nur zum Testen. 300.
::Algorithmus frei nach http://de.wikipedia.org/w/index.php?title=Julianisches_Datum&oldid=76256118#Berechnung_aus_dem_Kalenderdatum 301.
setlocal EnableDelayedExpansion 302.
set _MyYear=%1&set _MyMonth=%2&set _MyDay=%3 303.
304.
if %_MyYear% EQU 0 ( ::Jahr 0000 wurde angegeben; ungültige Jahreszahl... 305.
echo FncDateToJulianDay_Hack01: Error^^! 306.
echo On 31.12.0001 before Christ ^(BC^) immediately follows the 01.01.0001 AD ^(CE^). 307.
echo The year 0000 does not exist. Use -0001 do you mean the year 1 before Christ. 308.
exit /b 1 309.
) 1>&2 310.
if %_MyYear% LSS 0 set /a _MyYear"+=1" &::Das Jahr -1 liegt rechnerisch im Jahr 0, -2 im Jahr -1, etc. 311.
312.
if %_MyMonth% LEQ 2 ( set _bJanOrFeb=1 ) else ( set _bJanOrFeb=0 ) 313.
set /a _Y"=_MyYear-_bJanOrFeb" 314.
set /a _M"=_MyMonth + (12*_bJanOrFeb) + 1" 315.
set /a _JD"=365*(_Y+4716) + (_Y+4716)/4 + 30*_M + 6001*_M/10000 - 1524 + _MyDay + 2 - _Y/100 + _Y/400" 316.
endlocal &set "%~4=%_JD%" &::Hinweis: JulianDay 0 == 1. Jan. 4713 v.u.Z. julianisch == 24. Nov. 4714 v.u.Z. greogorianisch 317.
exit /b 0 318.
319.
:FncDateToJulianDay_Hack_11 ::Datum zum juliansichen Tag _mit historisch korrekter Berechnung_ 320.
::Parameters: <Year> <Month> <Day> <VarNameToReturnJulianDayNr> 321.
::Example: call :FncDateToJulianDay 5555 05 05 _JulianDay 322.
::############################################################################################################# 323.
::Nicht fuer den produktiven Einsatz gedacht und geeignet; nur zum Testen. 324.
::Algorithmus frei nach http://de.wikipedia.org/w/index.php?title=Julianisches_Datum&oldid=76256118#Berechnung_aus_dem_Kalenderdatum 325.
setlocal EnableDelayedExpansion 326.
set _MyYear=%1&set _MyMonth=%2&set _MyDay=%3 327.
328.
if %_MyYear% EQU 0 ( ::Jahr 0000 wurde angegeben; ungültige Jahreszahl... 329.
echo FncDateToJulianDay_Hack01: Error^^! 330.
echo On 31.12.0001 before Christ ^(BC^) immediately follows the 01.01.0001 AD ^(CE^). 331.
echo The year 0000 does not exist. Use -0001 do you mean the year 1 before Christ. 332.
exit /b 1 333.
) 1>&2 334.
if %_MyYear% LSS 0 set /a _MyYear"+=1" &::Das Jahr -1 liegt rechnerisch im Jahr 0, -2 im Jahr -1, etc. 335.
336.
if %_MyMonth% LEQ 2 ( set _bJanOrFeb=1 ) else ( set _bJanOrFeb=0 ) 337.
set /a _Y"=_MyYear-_bJanOrFeb" 338.
set /a _M"=_MyMonth + (12*_bJanOrFeb) + 1" 339.
340.
set /a _MyCalendar"=_MyYear*100 + _MyMonth*10 + _MyDay" 341.
set /a _GregorianCalendar"= 1582*100 + 10*10 + 15" 342.
set /a _JulianCalendar"= 1582*100 + 10*10 + 4" 343.
if %_MyCalendar% GEQ %_GregorianCalendar% ( ::ab 15.10.1582 Schaltjahresberechnung nach dem Gregorian. Kal. 344.
echo Berechnung nach dem Gregorianischen Kalender... 345.
set /a _JD"=365*(_Y+4716) + (_Y+4716)/4 + 30*_M + 6001*_M/10000 - 1524 + _MyDay + 2 - _Y/100 + _Y/400" 346.
) 347.
if %_MyCalendar% LSS %_GregorianCalendar% if %_MyCalendar% GTR %_JulianCalendar% ( 348.
echo FncDateToJulianDay_Hack_11: Error^^! 349.
echo Historically the days between 05-14 in October 1582 does not exist. 350.
exit /b 1 351.
) 1>&2 352.
if %_MyCalendar% LEQ %_JulianCalendar% ( ::bis 04.10.1582 Schaltjahresberechnung nach dem Julian. Kalender 353.
echo Berechnung nach dem Julianischen Kalender... 354.
set /a _JD"=365*(_Y+4716) + (_Y+4716)/4 + 30*_M + 6001*_M/10000 + _MyDay - 1524" 355.
) 356.
endlocal &set "%~4=%_JD%" 357.
exit /b 0 358.
359.
:DateToDOW %yy% %mm% %dd% dow 360.
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: 361.
:: By: Ritchie Lawrence, 2003-04-29. Version 1.1 362.
:: Func: Creates a day of week number from a calendar date, where 1 = Mon 363.
:: and 7 = Sun. For NT4/2000/XP/2003. 364.
:: Args: %1 year component to be converted, 2 or 4 digits (by val) 365.
:: %2 month component to be converted, leading zero ok (by val) 366.
:: %3 day of month to be converted, leading zero ok (by val) 367.
:: %4 var to receive day of week number, 1 to 7 (by ref) 368.
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: 369.
set yy=%1&set mm=%2&set dd=%3 370.
::if 1%yy% LSS 200 if 1%yy% LSS 170 (set yy=20%yy%) else (set yy=19%yy%) 371.
set /a dd=100%dd%%%100,mm=100%mm%%%100 372.
set /a z=14-mm,z/=12,y=yy+4800-z,m=mm+12*z-3,dow=153*m+2 373.
set /a dow=dow/5+dd+y*365+y/4-y/100+y/400-2472630,dow%%=7,dow+=1 374.
set %4=%dow% 375.
exit /b 0 376.
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: 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: DonnerstagDamit 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:
01.
Original-Code: 02.
set /a z=14-mm,z/=12,y=yy+4800-z,m=mm+12*z-3,dow=153*m+2 03.
set /a dow=dow/5+dd+y*365+y/4-y/100+y/400-2472630,dow%%=7,dow+=1 04.
Dieser Code nur anders formatiert: 05.
set /a z=14-mm, z/=12, m"=(12*z) + (mm-3)", dow"=(153*m + 2)/5" 06.
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)
Biber schreibt am 27.06.2010 um 14:31:29 Uhr
Moin NeonZero,
seinerzeit Anno 2005 als ich dieses Tut geschrieben habe, war ich auch manchmal in dieser Phase "dieser Algorithmus lässt mich nicht los", ähnlich wie du es beschreibst.
Und das lag vor allem damals an der Erkenntnis (die ich tagelang einfach nicht glauben wollte)
"Hey, 5 Jahre nach diesem Y2K-Desaster, wo ALLE gelobt hatten 'Ab sofort gehen wir vernünftiger mit der Speicherung von Datumswerten um - wir haben verstanden!' - 5 Jahre danach ist kein Excel, kein Oracle und kein Linux dieser Welt dazu in der Lage auszurechnen, ob die Santa Maria an einen Dienstag oder einem Donnerstag vor Amerika gelandet ist.
Weil die alle nur in einem putziputzikleinen Zeitfensterchen "richtig" rechnen können.
Und wer die Frage beantworten will, an welchem Wochentag der Stapellauf von Noahs Arche war, der kommt mit dem Talmud zum Ziel, nicht aber mit irgendwelchen 32- oder 64-Bit-Klamotten."
Das, was (vermutlich) in der Kernelfunktionen der OSe implementiert ist, wird mit kleinen Unschärfen der folgende Algorithmus sein.
der oben von dir gerade seziert wird und der beispielsweise hier in einer PHP-Variante diskutiert wird.
Quelle: Datums- und Zeitberechnung mit PHP, Schaltjahre, Zeitzonen
In den Kernelfunktionen gibt es keine Notwendigkeit wie im Batch, sich auf Integerwerte und/oder Ganzzahlen zu beschränken - dort dürfte natürlich auch mit "365,25 Tagen pro Jahr" etc gerechnet werden.
Aber bei jeder Vereinfachung auf "Rechnen nur mit Ganzzahlen" ergibt sich zwangsläufig dieser merkwürdige Wert "4800 Jahre" aus der Zeile
--> Kurzer Sinn der ganzen Rede:
Aber im Sinne eines Tutorials zu dem Thema finde ich deine Hinweise und Hinterfragungen durchaus richtig.
Grüße und schon jetzt danke
Biber
seinerzeit Anno 2005 als ich dieses Tut geschrieben habe, war ich auch manchmal in dieser Phase "dieser Algorithmus lässt mich nicht los", ähnlich wie du es beschreibst.
Und das lag vor allem damals an der Erkenntnis (die ich tagelang einfach nicht glauben wollte)
"Hey, 5 Jahre nach diesem Y2K-Desaster, wo ALLE gelobt hatten 'Ab sofort gehen wir vernünftiger mit der Speicherung von Datumswerten um - wir haben verstanden!' - 5 Jahre danach ist kein Excel, kein Oracle und kein Linux dieser Welt dazu in der Lage auszurechnen, ob die Santa Maria an einen Dienstag oder einem Donnerstag vor Amerika gelandet ist.
Weil die alle nur in einem putziputzikleinen Zeitfensterchen "richtig" rechnen können.
Und wer die Frage beantworten will, an welchem Wochentag der Stapellauf von Noahs Arche war, der kommt mit dem Talmud zum Ziel, nicht aber mit irgendwelchen 32- oder 64-Bit-Klamotten."
Das, was (vermutlich) in der Kernelfunktionen der OSe implementiert ist, wird mit kleinen Unschärfen der folgende Algorithmus sein.
der oben von dir gerade seziert wird und der beispielsweise hier in einer PHP-Variante diskutiert wird.
Zitat eines Kommentars von Christian Seiler, 02. 10. 2007, 09:40
01.
function wochentag ($jahr, $monat, $tag, $g = true) { 02.
if ($monat <= 2) { 03.
$jahr--; 04.
$monat += 12; 05.
} 06.
if ($g) { 07.
$jahrhundert = (int) (($jahr + 4800) / 100) - 48; 08.
$korrektur = 2 - $jahrhundert + (int) (($jahrhundert + 48) / 4) - 12; 09.
} else { 10.
$korrektur = 0; 11.
} 12.
$jul_tag_zahl = (int) (365.25 * ($jahr + 4716))+ (int) (30.6001 * ($monat + 1)) + $tag + $korrektur - 1524; 13.
return $jul_tag_zahl % 7; 14.
}Dies dürfte auch die effizienteste korrekte Implementierung in PHP sein,
ist etwa 1,3x so schnell wie Deine Lösung,
unterstützt sowohl den gregorianischen als auch den julianischen Kalender
und ist korrekt für alle Daten ab dem 1. Januar 4713 v.U.Z. (das war vor etwa 6720 Jahren).
ist etwa 1,3x so schnell wie Deine Lösung,
unterstützt sowohl den gregorianischen als auch den julianischen Kalender
und ist korrekt für alle Daten ab dem 1. Januar 4713 v.U.Z. (das war vor etwa 6720 Jahren).
Quelle: Datums- und Zeitberechnung mit PHP, Schaltjahre, Zeitzonen
In den Kernelfunktionen gibt es keine Notwendigkeit wie im Batch, sich auf Integerwerte und/oder Ganzzahlen zu beschränken - dort dürfte natürlich auch mit "365,25 Tagen pro Jahr" etc gerechnet werden.
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 ....
die du ganz unten zitierst.--> Kurzer Sinn der ganzen Rede:
- dein Hinweis auf eine Vereinfachung des Abschneidens eines Textteils mit "Set bla=%bla:* =%" ist gut und hilfreich.
- der Algorithmus von Ritchie Lawrence ist eine Spur zu effekthascherisch und kommentararm. Nicht verständlich und transparent. Gebe ich dir Recht.
- der Algorithmus von Ritchie Lawrence ist allerdings dennoch richtig.
- die Codezeile "set /a dd=100%dd%%%100,mm=100%mm%%%100" ist NICHT ersetzbar durch deine Alternative, da R.L. auch beiläufig eben auch auch den Monats/Tagwerten "08" und "09", die als Hex-Werte fehlinterpretiert werden würden, die Dez-Zahlen 8 und 9 macht.
Aber im Sinne eines Tutorials zu dem Thema finde ich deine Hinweise und Hinterfragungen durchaus richtig.
Grüße und schon jetzt danke
Biber
NeonZero schreibt am 27.06.2010 um 15:22:41 Uhr
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
Biber schreibt am 30.06.2010 um 20:47:37 Uhr
Moin NeonZero,
ganz, ganz dickes Lob und Anerkennung für die Auseinandersetzung mit den Datums/Kalender/Wochentagsalgorithmen.
Und deiner Art, das zu tun.
Ich denke, es dürfte auch in etwas weiterem Umkreis kein vollständigerer und auf die Herleitung der Algorithmen bedachter Artikel zu diesem Thema zu finden sein.
Faszinierend finde ich auch, dass - wenn es um konkrete Algorithmen und Lösungsstrategien geht -
selbst ein für viele vorsintflutliches und kantiges Steinzeitwerkzeug wie ein CMD-Batchscript
plötzlich ungeahnte Passgenauigkeit und spielerische Leichtigkeit gewinnt
Wenn jemand damit umgehen kann jedenfalls.
Deine Ausführungen wären auf jeden Fall ein eigenes Tutorial wert. Gefällt mir sehr gut
Danke
Biber
ganz, ganz dickes Lob und Anerkennung für die Auseinandersetzung mit den Datums/Kalender/Wochentagsalgorithmen.
Und deiner Art, das zu tun.
Ich denke, es dürfte auch in etwas weiterem Umkreis kein vollständigerer und auf die Herleitung der Algorithmen bedachter Artikel zu diesem Thema zu finden sein.
Faszinierend finde ich auch, dass - wenn es um konkrete Algorithmen und Lösungsstrategien geht -
selbst ein für viele vorsintflutliches und kantiges Steinzeitwerkzeug wie ein CMD-Batchscript
plötzlich ungeahnte Passgenauigkeit und spielerische Leichtigkeit gewinnt
Wenn jemand damit umgehen kann jedenfalls.
Deine Ausführungen wären auf jeden Fall ein eigenes Tutorial wert. Gefällt mir sehr gut
Danke
Biber
NeonZero schreibt am 01.07.2010 um 10:27:52 Uhr
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
pieh-ejdsch schreibt am 19.02.2012 um 17:24:36 Uhr
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.2011Da 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:
01.
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:
01.
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:
01.
For %%i in (INDate INTime %Other% %AllDateTimeVars%) do @if defined %%i set %%i|find /i "%%i="01.
For %%i in (vbssnippet INTime INDate %Other% Other) Do Set "%%i="Gruß Phil
Biber schreibt am 20.02.2012 um 07:44:04 Uhr
Moin Phil,
vielen Dank für deine Hinweise und Ergänzungen.
Ich habe alles oben in eine angepasste Version v0.11 eingebaut mit Verweis auf deinen Kommentar.
Die Zeilennummern haben sich (durch eine neue Kommentarzeile) um +1 verschoben, wenn ich jetzt gleich die Änderung in Zeile 51 anspreche, steht es jetzt in Zeile 52 usw.
Eine kleine Änderung habe ich gemacht.
Das überflüssige bzw eigentlich auch falsche Leerzeichen zwischen "echo" und "|" in der Zeile 51
--> hab ich so geändert
--> auch damit ist gewährleistet, dass der auf eine Eingabe wartende Befehl "date" mit einem (Leer-)Input bedient wird.
Und ein Befehl "date<nul" ist für die Nicht-so-regelmäßig-Bätscher vielleicht noch einen Hauch nachvollziehbarer als deine Variante "echo(|date".
Mag ja vom Effekt gleichbedeutend sein, aber deine ist ziemlich schwer über Suchmaschinen zu finden
Mit übernommen wider innere Überzeugung habe ich in ebendieser Zeile den zusätzlichen Delimeter "." [Punkt] für den Fall,
in irgendeinem Land/irgendeiner Sprachregion würden in der Eingabeaufforderung
Das kann ich mir nicht vorstellen. Auch weil Spontaneität und Kreativität zwei der letzten Eigenschaften sind, die ich den Redmonder PraktikantInnen unterstellen würde.
Aber egal, dieser Punkt ist ja nicht der springende. Also ist er jetzt drin.
Auch die Umbenamsung von .bat in .cmd habe ich oben übernommen.
Vielen Dank & Grüße
Biber
vielen Dank für deine Hinweise und Ergänzungen.
Ich habe alles oben in eine angepasste Version v0.11 eingebaut mit Verweis auf deinen Kommentar.
Die Zeilennummern haben sich (durch eine neue Kommentarzeile) um +1 verschoben, wenn ich jetzt gleich die Änderung in Zeile 51 anspreche, steht es jetzt in Zeile 52 usw.
Eine kleine Änderung habe ich gemacht.
Das überflüssige bzw eigentlich auch falsche Leerzeichen zwischen "echo" und "|" in der Zeile 51
01.
FOR /F "tokens=2-4 delims=./-,() skip=1" %%a in ('echo(^|date') do (--> hab ich so geändert
01.
FOR /F "tokens=2-4 delims=./-,() skip=1" %%a in ('date^<nul') do (Und ein Befehl "date<nul" ist für die Nicht-so-regelmäßig-Bätscher vielleicht noch einen Hauch nachvollziehbarer als deine Variante "echo(|date".
Mag ja vom Effekt gleichbedeutend sein, aber deine ist ziemlich schwer über Suchmaschinen zu finden
Mit übernommen wider innere Überzeugung habe ich in ebendieser Zeile den zusätzlichen Delimeter "." [Punkt] für den Fall,
in irgendeinem Land/irgendeiner Sprachregion würden in der Eingabeaufforderung
Aktuelles Datum: 20.02.2012
Geben Sie das neue Datum ein: (TT-MM-JJ)
.. in der zweiten Zeile die TTs und MMs und JJs mit Punkten getrennt angezeigt.Geben Sie das neue Datum ein: (TT-MM-JJ)
Das kann ich mir nicht vorstellen. Auch weil Spontaneität und Kreativität zwei der letzten Eigenschaften sind, die ich den Redmonder PraktikantInnen unterstellen würde.
Aber egal, dieser Punkt ist ja nicht der springende. Also ist er jetzt drin.
Auch die Umbenamsung von .bat in .cmd habe ich oben übernommen.
Vielen Dank & Grüße
Biber
pieh-ejdsch schreibt am 20.02.2012 um 12:55:10 Uhr
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^<nulGruß Phil












65645schreibt am 27.05.2008 um 17:40:31 Uhr