Sformatuj datę i godzinę w skrypcie wsadowym systemu Windows

192

W skrypcie wsadowym systemu Windows (Windows XP) muszę sformatować bieżącą datę i godzinę, aby później użyć ich w nazwach plików itp.

Jest to podobne do pytania Przepełnienie stosu Jak dołączyć datę w plikach wsadowych , ale z czasem też.

Mam to do tej pory:

echo %DATE%
echo %TIME%
set datetimef=%date:~-4%_%date:~3,2%_%date:~0,2%__%time:~0,2%_%time:~3,2%_%time:~6,2%
echo %datetimef%

co daje:

28/07/2009
 8:35:31.01
2009_07_28__ 8_36_01

Czy jest sposób, w jaki mogę zezwolić na jednocyfrową godzinę w% TIME%, aby uzyskać następujące?

2009_07_28__08_36_01
Laurie
źródło
Możesz zamienić puste spacje w datetimefzmiennej i zamiast tego wstawić 0. Na przykład:SET datetimef=%datetimef: =0%
SebaGra

Odpowiedzi:

148

Skończyło się na tym skrypcie:

set hour=%time:~0,2%
if "%hour:~0,1%" == " " set hour=0%hour:~1,1%
echo hour=%hour%
set min=%time:~3,2%
if "%min:~0,1%" == " " set min=0%min:~1,1%
echo min=%min%
set secs=%time:~6,2%
if "%secs:~0,1%" == " " set secs=0%secs:~1,1%
echo secs=%secs%

set year=%date:~-4%
echo year=%year%

:: W WIN2008R2 np. Musiałem ustawić „ustawiony miesiąc =% data: ~ 3,2%” jak poniżej :: w przeciwnym razie dla MIESIĄCA pojawi się 00

set month=%date:~4,2%
if "%month:~0,1%" == " " set month=0%month:~1,1%
echo month=%month%
set day=%date:~0,2%
if "%day:~0,1%" == " " set day=0%day:~1,1%
echo day=%day%

set datetimef=%year%%month%%day%_%hour%%min%%secs%

echo datetimef=%datetimef%
Laurie
źródło
11
Do Twojej wiadomości, w Windows Server 2003 i Windows 7, ten skrypt dał mi „201200Mo_085806” (poprawny rok i czas).
sfuqua,
50
Uwaga dla kogoś, kto przyjdzie tutaj z Google (jak ja): To zależy od ustawień regionalnych, więc może wymagać poprawek do pracy w systemie Windows innym niż angielski!
PiotrK
Zrobiłem to w ten sposób: Time / T> Time.dat set / P ftime = <Time.dat set fDate =% date: ~ 6 %% date: ~ 3,2 %% date: ~ 0,2 %% ftime: ~ 0,2 %% ftime: ~ 3,2% echo% fData% -> 201310170928
Ice
Co robi% time: ~ 0,2%, gdzie jest trochę dokumentacji dotyczącej struktury: ~,%?
user1605665,
6
Wszystko to można zrobić w zaledwie 2 liniach przy użyciu zwykłej zamiany ciągów: stackoverflow.com/a/23558738/1879699
Andreas
71
@ECHO OFF
: Sets the proper date and time stamp with 24Hr Time for log file naming
: convention

SET HOUR=%time:~0,2%
SET dtStamp9=%date:~-4%%date:~4,2%%date:~7,2%_0%time:~1,1%%time:~3,2%%time:~6,2% 
SET dtStamp24=%date:~-4%%date:~4,2%%date:~7,2%_%time:~0,2%%time:~3,2%%time:~6,2%

if "%HOUR:~0,1%" == " " (SET dtStamp=%dtStamp9%) else (SET dtStamp=%dtStamp24%)

ECHO %dtStamp%

PAUSE
coś
źródło
2
W systemie Windows Server 2003 i Windows 7 dało mi to prawidłowy ciąg. O wiele bardziej elegancki niż ten, który budowałem w przeszłości, więc dziękuję!
sfuqua,
3
Oto, co daje mi Windows 7 z rosyjskimi ustawieniami narodowymi. Aktualny czas to 2013-05-03T02: 22: 51, ale skrypt wypisuje: „2013-5.-01_02_22_51”
nightcoder
7
% Date% da inny ciąg znaków w różnych lokalizacjach.
AechoLiu,
2
zwraca 20146.0._173502 (czeskie ustawienia narodowe)
Muflix
2
win7 64bit najwyższy, niepoprawny czas: 20140.01_131612, musi być (2014.10.26_131612)
waza123
66

Oto jak generuję nazwę pliku dziennika (na podstawie http://ss64.com/nt/syntax-getdate.html ):

@ECHO OFF
:: Check WMIC is available
WMIC.EXE Alias /? >NUL 2>&1 || GOTO s_error

:: Use WMIC to retrieve date and time
FOR /F "skip=1 tokens=1-6" %%G IN ('WMIC Path Win32_LocalTime Get Day^,Hour^,Minute^,Month^,Second^,Year /Format:table') DO (
   IF "%%~L"=="" goto s_done
      Set _yyyy=%%L
      Set _mm=00%%J
      Set _dd=00%%G
      Set _hour=00%%H
      SET _minute=00%%I
      SET _second=00%%K
)
:s_done

:: Pad digits with leading zeros
      Set _mm=%_mm:~-2%
      Set _dd=%_dd:~-2%
      Set _hour=%_hour:~-2%
      Set _minute=%_minute:~-2%
      Set _second=%_second:~-2%

Set logtimestamp=%_yyyy%-%_mm%-%_dd%_%_hour%_%_minute%_%_second%
goto make_dump

:s_error
echo WMIC is not available, using default log filename
Set logtimestamp=_

:make_dump
set FILENAME=database_dump_%logtimestamp%.sql
...
nightcoder
źródło
5
najlepsza odpowiedź na SO w przypadku pytań o generowanie znaczników czasowych niezależnych od ustawień regionalnych.
Mike Campbell
2
Niesamowite! Powinien istnieć sposób na oznaczenie tego jako rozwiązania
Rado,
48

Zwykle robię to w ten sposób, ilekroć potrzebuję ciągu daty / godziny:

set dt=%DATE:~6,4%_%DATE:~3,2%_%DATE:~0,2%__%TIME:~0,2%_%TIME:~3,2%_%TIME:~6,2%
set dt=%dt: =0%

Dotyczy to niemieckiego formatu daty / godziny (dd.mm.rrrr gg: mm: ss). Zasadniczo konkatenuję podciągi i na koniec zastępuję wszystkie spacje zerami.

Krótkie wyjaśnienie działania podciągów:

%VARIABLE:~num_chars_to_skip,num_chars_to_keep%

Aby uzyskać tylko rok od daty takiej jak „29.03.2018”, użyj:

%DATE:~6,4%
       ^-----skip 6 characters
         ^---keep 4 characters 
Andreas
źródło
7
zdecydowanie najbardziej eleganckie rozwiązanie, gdy potrzebujesz czystego znacznika czasu (bez spacji i innych znaków)
jvdneste
1
Nie mogłem się bardziej zgodzić z podziękowaniami @jvdneste za udostępnienie mrt
this.user3272243
1
absolutnie świetne - i działa [wymagana składnia jest bardzo myląca, ale to nie jest problem z plakatem]
JosephDoggie
38

Jeśli zainstalowano PowerShell, możesz łatwo i niezawodnie uzyskać datę / godzinę w dowolnym formacie, na przykład:

for /f %%a in ('powershell -Command "Get-Date -format yyyy_MM_dd__HH_mm_ss"') do set datetime=%%a
move "%oldfile%" "backup-%datetime%"

Oczywiście w dzisiejszych czasach PowerShell jest zawsze zainstalowany, ale w Windows XP prawdopodobnie będziesz chciał użyć tej techniki tylko wtedy, gdy skrypt wsadowy jest używany w znanym środowisku, w którym wiesz, że PS jest dostępny (lub sprawdź w pliku wsadowym, czy PowerShell jest dostępny ...)

Możesz rozsądnie zapytać: dlaczego w ogóle używać pliku wsadowego, jeśli możesz użyć programu PowerShell, aby uzyskać datę / godzinę, ale myślę, że niektóre oczywiste powody są następujące: (a) nie znasz się na programie PowerShell i nadal wolisz robić większość rzeczy w staromodny sposób z plikami wsadowymi lub (b) aktualizujesz stary skrypt i nie chcesz przenosić całej zawartości na PS.

G. Lombard
źródło
(a) w moim przypadku i to działa idealnie (nietoperz jest tylko dla mojego środowiska, ale mam różne lokalizacje na różnych komputerach). Dziękuję Ci!
ccalboni
30

Dzisiaj spotkałem ten problem i rozwiązałem go za pomocą:

SET LOGTIME=%TIME: =0%

Zastępuje spacje zerami i zasadniczo zeruje pady na godzinę.

Po szybkim wyszukiwaniu nie dowiedziałem się, czy wymagało to rozszerzenia poleceń (nadal działało z SETLOCAL DISABLEEXTENSIONS).

opello
źródło
OK, podstawienie w zmiennych. Teraz - jak podstawić dwukropek ( :)?
Tomasz Gandor,
@TomaszGandor To działa dla mnie: echo %TIME: =:%ale jeśli nie jest, może spróbuj uciec :z ^podobnym echo %TIME: =^:%(co również działa dla mnie).
opello
1
+1 za prostotę. Dwukropki nie są poprawne w nazwach plików. set theTime =% Time :: =% usuwa je. Czy możesz podstawić 0 spacją, usunąć dwukropki i skrócić do 6 znaków (usuwając w ten sposób część dziesiętną) w pojedynczej instrukcji? To nic wielkiego, jeśli zajmuje dwie lub trzy linie. Jestem po prostu ciekawy.
riderBill
Nie to co wiem. Prosimy o dalsze działania, jeśli je znajdziesz!
opello
21

Jak już wspomniano, parsowanie daty i godziny jest przydatne tylko wtedy, gdy znasz format używany przez bieżącego użytkownika (na przykład MM / dd / rr lub dd-MM-rrrr, żeby wymienić tylko dwa). Można to ustalić, ale zanim wykonasz wszystkie stresujące i parsowania, nadal będziesz mieć do czynienia z sytuacją, w której użyjesz nieoczekiwanego formatu i konieczne będą dalsze poprawki.

Możesz także użyć programu zewnętrznego, który zwróci informację o błędzie daty w preferowanym formacie, ale ma to wady związane z koniecznością dystrybucji programu narzędziowego wraz ze skryptem / partią.

Istnieją również sztuczki wsadowe wykorzystujące zegar CMOS w dość surowy sposób, ale dla większości ludzi jest to zbyt blisko drutów, a także nie zawsze preferowane miejsce do pobierania daty / godziny.

Poniżej znajduje się rozwiązanie, które pozwala uniknąć powyższych problemów. Tak, wprowadza kilka innych problemów, ale dla moich celów uznałem, że jest to najłatwiejsze, najczystsze i najbardziej przenośne rozwiązanie do tworzenia znaczników danych w plikach .bat dla nowoczesnych systemów Windows. To tylko przykład, ale myślę, że zobaczysz, jak zmodyfikować dla innych formatów daty i / lub godziny itp.

reg copy "HKCU\Control Panel\International" "HKCU\Control Panel\International-Temp" /f
reg add "HKCU\Control Panel\International" /v sShortDate /d "yyMMdd" /f
@REM reg query "HKCU\Control Panel\International" /v sShortDate
set LogDate=%date%
reg copy "HKCU\Control Panel\International-Temp" "HKCU\Control Panel\International" /f
jph
źródło
3
Właśnie tego szukałem. Coś, co działa w każdym ustawieniu regionalnym. Dzięki!
Lost_DM,
+1 za „nowoczesne systemy Windows”, z którymi mamy do czynienia :) Żartując na bok, jest to bardzo pomysłowy i, jak powiedziałeś, przenośny sposób radzenia sobie z tym problemem.
Zach Young,
9
To okropne rozwiązanie. Jeśli to się nie powiedzie, ustawienie globalne zostanie trwale zmienione. Wprowadza również warunki wyścigu z innymi aplikacjami.
MikeKulls,
Możesz użyć tej reg query "HKCU\Control Panel\International" /v sShortDateczęści bez zmiany ustawienia rejestru (ćwiczenie pozostaw czytelnikowi!).
tricasse
9

Poniższe informacje mogą nie być bezpośrednią odpowiedzią, ale bliższą?

set hour=%time:~0,2%
if "%hour:~0,1%" == " " set datetimef=%date:~-4%_%date:~3,2%_%date:~0,2%__0%time:~1,2%_%time:~3,2%_%time:~6,2%
else set datetimef=%date:~-4%_%date:~3,2%_%date:~0,2%__%time:~0,2%_%time:~3,2%_%time:~6,2%

Przynajmniej może być inspirujące.

ufukgun
źródło
9

Jeśli nie potrzebujesz tego formatu:

2009_07_28__08_36_01

Następnie możesz użyć następujących 3 wierszy kodu, które używają% date% i% time%:

set mydate=%date:/=%
set mytime=%time::=%
set mytimestamp=%mydate: =_%_%mytime:.=_%

Uwaga: Znaki /i :są usuwane, a znak .i spacja są zastępowane znakiem podkreślenia.

Przykładowe dane wyjściowe (wykonane w środę 8/5/15 o 12:49 z 50 sekundami i 93 milisekundami):

echo %mytimestamp%
Wed_08052015_124950_93
Jesse
źródło
gdy godzina jest mniejsza niż 12, ustaw mydate =% date: / =% set mytime =% time :: =% set mytime =% mytime: = 0% set mytimestamp =% mydate: = _% _% mytime:. = _ %
ragche
8
REM Assumes UK style date format for date environment variable (DD/MM/YYYY).
REM Assumes times before 10:00:00 (10am) displayed padded with a space instead of a zero.
REM If first character of time is a space (less than 1) then set DATETIME to:
REM YYYY-MM-DD-0h-mm-ss
REM Otherwise, set DATETIME to:
REM YYYY-MM-DD-HH-mm-ss
REM Year, month, day format provides better filename sorting (otherwise, days grouped
REM together when sorted alphabetically).

IF "%time:~0,1%" LSS "1" (
   SET DATETIME=%date:~6,4%-%date:~3,2%-%date:~0,2%-0%time:~1,1%-%time:~3,2%-%time:~6,2%
) ELSE (
   SET DATETIME=%date:~6,4%-%date:~3,2%-%date:~0,2%-%time:~0,2%-%time:~3,2%-%time:~6,2%
)

ECHO %DATETIME%
Mike Raynham
źródło
6

offset:lengthFormatowanie obsługiwane z SETpolecenia w systemie Windows nie pozwoli na wkładce 0jak wydaje się być zainteresowany.

Możesz jednak napisać skrypt BATCH, aby sprawdzić, czy godzina jest mniejsza niż, 10i
odpowiednio wpisać inny echociąg znaków.

Znajdziesz tu trochę informacji na temat SETkomendy na ten link .


Aby to zrobić, możesz także przejść na inne metody programowania.

W uniksowym bashu (dostępnym w Cygwin w systemie Windows) jest dość proste stwierdzenie:

date +%Y_%m_%d__%H_%M_%S

I zawsze prawidłowo się pada.

nik
źródło
6

Zrobiłem to w ten sposób:

REM Generate FileName from date and time in format YYYYMMTTHHMM

Time /T > Time.dat
set /P ftime= < Time.dat

set FileName=LogFile%date:~6%%date:~3,2%%date:~0,2%%ftime:~0,2%%ftime:~3,2%.log

echo %FileName%

LogFile201310170928.log

lód
źródło
Działa na angielskim serwerze (nazwa systemu operacyjnego: Microsoft (R) Windows 2003 Server 2003 Standard x64 Edition, wersja systemu operacyjnego: 5.2.3790 Service Pack 2 Build 3790)
Ice
1
a także przetestowane na niemieckim serwerze (Betriebssystemname: Microsoft® Windows Server® 2008 Enterprise, Betriebssystemversion: 6.0.6002 Service Pack 2 Build 6002)
Ice
1
Nawet ten jest w porządku: (Betriebssystemname: Microsoft Windows Server 2012 Standard, Betriebssystemversion: 6.2.9200 Nicht zutreffend Build 9200)
Ice
4
::========================================================================  
::== CREATE UNIQUE DATETIME STRING IN FORMAT YYYYMMDD-HHMMSS   
::======= ================================================================  
FOR /f %%a IN ('WMIC OS GET LocalDateTime ^| FIND "."') DO SET DTS=%%a  
SET DATETIME=%DTS:~0,8%-%DTS:~8,6%  

Pierwszy wiersz zawsze wyświetla dane wyjściowe w tym formacie:
strefa czasowa: 20150515150941.077000 + 120
To pozostawia tylko formatowanie wyjścia zgodnie z własnymi życzeniami.

Kees
źródło
4

Ten plik nietoperza (zapisany jako datetimestr.bat) tworzy ciąg datetime 3 razy: (1) długi ciąg datetime z dniem tygodnia i sekund, (2) krótki ciąg datetime bez nich i (3) krótką wersję kodu.

@echo off
REM "%date: =0%" replaces spaces with zeros
set d=%date: =0%
REM "set yyyy=%d:~-4%" pulls the last 4 characters
set yyyy=%d:~-4%
set mm=%d:~4,2%
set dd=%d:~7,2%
set dow=%d:~0,3%
set d=%yyyy%-%mm%-%dd%_%dow%

set t=%TIME: =0%
REM "%t::=%" removes semi-colons
REM Instead of above, you could use "%t::=-%" to 
REM replace semi-colons with hyphens (or any 
REM non-special character)
set t=%t::=%
set t=%t:.=%

set datetimestr=%d%_%t%
@echo  Long date time str = %datetimestr%

set d=%d:~0,10%
set t=%t:~0,4%
set datetimestr=%d%_%t%
@echo Short date time str = %datetimestr%


@REM Short version of the code above
set d=%date: =0%
set t=%TIME: =0%
set datetimestr=%d:~-4%-%d:~4,2%-%d:~7,2%_%d:~0,3%_%t:~0,2%%t:~3,2%%t:~6,2%%t:~9,2%
@echo Datetimestr = %datetimestr%

pause

Aby odpowiednio podziękować, połączyłem koncepcje Petera Mortensena (18 czerwca o godz. 21:02) i opello (25 sierpnia o godz. 14:27).

Możesz napisać to znacznie krócej, ale ta długa wersja ułatwia czytanie i rozumienie kodu.

Cadvena
źródło
4

Naprawdę jestem nowy w tworzeniu plików wsadowych i to jest mój kod !! (Nie jestem pewien dlaczego, ale nie mogłem połączyć date / t i time / t razem i nie mogłem użyć % date% i % time% bezpośrednio bez zmiennej ...)

@ECHO OFF
set ldt=%date% %time%
echo %ldt%>> logs.txt
EXIT

Jest to rodzaj ponownego wykorzystania od innych (pytanie brzmiało, aby uzyskać sformatowany czas do użycia jako nazwę pliku).

Kelly
źródło
4

Istnieje inny prosty sposób:

set HH=%time:~0,2%
if %HH% LEQ 9 (
set HH=%time:~1,1%
)
Vijay
źródło
3

Do generowania YYYY-MM-DD hh:mm:ssznacznika czasu (24-godzinnego) używam:

SET CURRENTTIME=%TIME%
IF "%CURRENTTIME:~0,1%"==" " (SET CURRENTTIME=0%CURRENTTIME:~1%)
FOR /F "tokens=2-4 delims=/ " %%A IN ('DATE /T') DO (SET TIMESTAMP=%%C-%%A-%%B %CURRENTTIME%)
M. Dudley
źródło
Czy zakłada określone ustawienie regionalne?
Peter Mortensen
1
Według ss64.com/nt/syntax-variables.html%TIME% i %DATE%zmienne używają tego samego formatu, jak TIMEi DATEpoleceń, odpowiednio. W moim systemie zmienne nie pasują do moich ustawień regionalnych.
M. Dudley,
3

Ten skrypt wsadowy zrobi dokładnie to, czego chce OP (testowany na Windows XP SP3).

Użyłem również tej sprytnej sztuczki rejestru opisanej wcześniej przez „jph”, którą IMHO jest najprostszym sposobem uzyskania 100% spójnego formatowania daty "yyyy_MM_dd"w dowolnym nowym lub starym systemie Windows. Zmiana na jedną wartość rejestru w tym celu jest chwilowa i trywialna; trwa tylko kilka milisekund, zanim zostanie natychmiast cofnięte.

Kliknij dwukrotnie ten plik wsadowy, aby uzyskać natychmiastową wersję demonstracyjną, pojawi się okno wiersza polecenia i wyświetli znacznik czasu. . . . .

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: generates a custom formatted timestamp string using date and time.
:: run this batch file for an instant demo.
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

@ECHO OFF
SETLOCAL & MODE CON:COLS=80 LINES=15 & COLOR 0A

:: --- CHANGE THE COMPUTER DATE FORMAT TEMPORARILY TO MY PREFERENCE "yyyy_MM_dd",
REG COPY "HKCU\Control Panel\International" "HKCU\Control Panel\International-Temp" /f 2>nul >nul
REG ADD "HKCU\Control Panel\International" /v sShortDate /d "yyyy_MM_dd" /f 2>nul >nul

SET MYDATE=%date%

:: --- REVERT COMPUTER DATE BACK TO SYSTEM PREFERENCE
REG COPY "HKCU\Control Panel\International-Temp" "HKCU\Control Panel\International" /f 2>nul >nul
REG DELETE "HKCU\Control Panel\International-Temp" /f 2>nul >nul

:: --- SPLIT THE TIME [HH:MM:SS.SS] TO THREE SEPARATE VARIABLES [HH] [MM] [SS.SS]
FOR /F "tokens=1-3 delims=:" %%A IN ('echo %time%') DO (
SET HOUR=%%A
SET MINUTES=%%B
SET SECONDS=%%C
)

:: --- CHOOSE ONE OF THESE TWO OPTIONS :
:: --- FOR 4 DIGIT SECONDS        //REMOVES THE DOT FROM THE SECONDS VARIABLE [SS.SS]
:: SET SECONDS=%SECONDS:.=%
:: --- FOR 2 DIGIT SECONDS        //GETS THE FIRST TWO DIGITS FROM THE SECONDS VARIABLE [SS.SS]
SET SECONDS=%SECONDS:~0,2% 

:: --- FROM 12 AM TO 9 AM, THE HOUR VARIABLE WE EXTRACTED FROM %TIME% RETURNS A SINGLE DIGIT, 
:: --- WE PREFIX A ZERO CHARACTER TO THOSE CASES, SO THAT OUR WANTED TIMESTAMP
:: --- ALWAYS GENERATES DOUBLE-DIGIT HOURS (24-HOUR CLOCK TIME SYSTEM).
IF %HOUR%==0 (SET HOUR=00)
IF %HOUR%==1 (SET HOUR=01)
IF %HOUR%==2 (SET HOUR=02)
IF %HOUR%==3 (SET HOUR=03)
IF %HOUR%==4 (SET HOUR=04)
IF %HOUR%==5 (SET HOUR=05)
IF %HOUR%==6 (SET HOUR=06)
IF %HOUR%==7 (SET HOUR=07)
IF %HOUR%==8 (SET HOUR=08)
IF %HOUR%==9 (SET HOUR=09)

:: --- GENERATE OUR WANTED TIMESTAMP
SET TIMESTAMP=%MYDATE%__%HOUR%_%MINUTES%_%SECONDS%

:: --- VIEW THE RESULT IN THE CONSOLE SCREEN
ECHO.
ECHO    Generate a custom formatted timestamp string using date and time.
ECHO.
ECHO    Your timestamp is:    %TIMESTAMP%
ECHO.
ECHO.
ECHO    Job is done. Press any key to exit . . .
PAUSE > NUL

EXIT
derty2
źródło
Działa również w systemie Windows 2019. Będę trzymać twoje rozwiązanie, podoba mi się :)
user225479
Pytanie, właśnie odkryłem, że po północy końcowe wyjście „0” spada w wyniku. Masz pomysł, dlaczego? Mój wynik z twoim skryptem daje: Twój znacznik czasu to: 2019_09_16__0_58_07 Zamiast ..00_58_07. Ale po 1 godzinie działa zgodnie z oczekiwaniami (i da wynik: ..01_01_56).
user225479
Dodałem IF% HOUR% == 0 (SET HOUR = 00) do instrukcji ELSE. Mam nadzieję, że to powinno naprawić :)
user225479
Dziękujemy za opinię @ user225479. Naprawiłem kod. Wszystkie możliwe permutacje zmiennej HOUR przekonwertowanej na format 24 HOUR będą teraz działać poprawnie. Zmodyfikowałem również układ, aby był łatwiejszy do odczytania.
derty2
2
set hourstr = %time:~0,2%
if "%time:~0,1%"==" " (set hourstr=0%time:~1,1%)
set datetimestr=%date:~0,4%%date:~5,2%%date:~8,2%-%hourstr%%time:~3,2%%time:~6,2%
Will Wu
źródło
2

Utwórz plik o nazwie „search_files.bat” i umieść poniżej zawartość w pliku. Następnie kliknij dwukrotnie. Tymczasowa zmienna% THH% została wprowadzona, aby odpowiednio obsługiwać AM. Jeśli w pierwszych 2 cyfrach czasu występuje 0, system Windows ignoruje resztę nazwy pliku LOG.

CD .
SET THH=%time:~0,2%
SET THH=%THH: =0%
dir /s /b *.* > %date:~10,4%-%date:~4,2%-%date:~7,2%@%THH%.%time:~3,2%.%time:~6,2%.LOG
MacGyver
źródło
2

Podoba mi się krótka wersja na górze @ lorax, ale dla innych ustawień językowych może być nieco inna.

Na przykład w ustawieniach języka niemieckiego (z naturalnym formatem daty: dd.mm.rrrr) zapytanie miesiąca należy zmienić z 4,2 na 3,2:

@ECHO OFF
: Sets the proper date and time stamp with 24h time for log file naming convention i.e.

SET HOUR=%time:~0,2%
SET dtStamp9=%date:~-4%%date:~3,2%%date:~7,2%_0%time:~1,1%%time:~3,2%%time:~6,2% 
SET dtStamp24=%date:~-4%%date:~3,2%%date:~7,2%_%time:~0,2%%time:~3,2%%time:~6,2%

if "%HOUR:~0,1%" == " " (SET dtStamp=%dtStamp9%) else (SET dtStamp=%dtStamp24%)

ECHO %dtStamp%
: Outputs= 20160727_081040
: (format: YYYYMMDD_HHmmss; e.g.: the date-output of this post timestamp)

PAUSE
webMac
źródło
1

To moje 2 centy za datetime string. W MM DD YYYYsystemach przełącz pierwsze i drugie %DATE:~wpisy.

    REM ====================================================================================
    REM CREATE UNIQUE DATETIME STRING FOR ADDING TO FILENAME
    REM ====================================================================================
    REM Can handle dd DDxMMxYYYY and DDxMMxYYYY > CREATES YYYYMMDDHHMMSS (x= any character)
    REM ====================================================================================
    REM CHECK for SHORTDATE dd DDxMMxYYYY 
    IF "%DATE:~0,1%" GTR "3" (
        SET DATETIME=%DATE:~9,4%%DATE:~6,2%%DATE:~3,2%%TIME:~0,2%%TIME:~3,2%%TIME:~6,2%
    ) ELSE (
    REM ASSUMES SHORTDATE DDxMMxYYYY
        SET DATETIME=%DATE:~6,4%%DATE:~3,2%%DATE:~0,2%%TIME:~0,2%%TIME:~3,2%%TIME:~6,2%
        )
    REM CORRECT FOR HOURS BELOW 10
    IF %DATETIME:~8,2% LSS 10 SET DATETIME=%DATETIME:~0,8%0%DATETIME:~9,5%
    ECHO %DATETIME%
Walizka
źródło
1

Próbowałem zaakceptować odpowiedź i działa całkiem dobrze. Niestety format czasu w USA wygląda na H: MM: SS.CS, a brakujące 0 z przodu powodowało problemy z analizą przed 10 rano. Aby pokonać tę przeszkodę i umożliwić analizowanie większości formatów czasu na świecie, wymyśliłem tę prostą procedurę, która wydaje się działać całkiem dobrze.

:ParseTime
rem The format of %%TIME%% is H:MM:SS.CS or (HH:MM:SS,CS) for example 0:01:23.45 or 23:59:59,99
FOR /F "tokens=1,2,3,4 delims=:.," %%a IN ("%1") DO SET /A "%2=(%%a * 360000) + (%%b * 6000) + (%%c * 100) + %%d"
GOTO :EOF

Zaletą tej procedury jest to, że przekazujesz ciąg czasu jako pierwszy parametr, a nazwę zmiennej środowiskowej, która ma zawierać czas (w centisekundach) jako drugi parametr. Na przykład:

CALL :ParseTime %START_TIME% START_CS
CALL :ParseTime %TIME% END_CS
SET /A DURATION=%END_CS% - %START_CS%

(* Chris *)

TheChrisPratt
źródło
1

Może coś takiego:

@call:DateTime

@for %%? in (
    "Year   :Y"
    "Month  :M"
    "Day    :D"
    "Hour   :H"
    "Minutes:I"
    "Seconds:S"
) do @for /f "tokens=1-2 delims=:" %%# in (%%?) do @for /f "delims=" %%_ in ('echo %%_DT_%%$_%%') do @echo %%# : _DT_%%$_ : %%_

:: OUTPUT
:: Year    : _DT_Y_ : 2014
:: Month   : _DT_M_ : 12
:: Day     : _DT_D_ : 17
:: Hour    : _DT_H_ : 09
:: Minutes : _DT_I_ : 04
:: Seconds : _DT_S_ : 35

@pause>nul

@goto:eof

:DateTime
    @verify errorlevel 2>nul & @wmics Alias /? >nul 2>&1
    @if not errorlevel 1 (
        @for /f "skip=1 tokens=1-6" %%a in ('wmic path win32_localtime get day^,hour^,minute^,month^,second^,year /format:table') do @if not "%%f"=="" ( set "_DT_D_=%%a" & set "_DT_H_=%%b" & set "_DT_I_=%%c" & set "_DT_M_=%%d" & set "_DT_S_=%%e" & set "_DT_Y_=%%f" )
    ) else (
        @set "_DT_T_=1234567890 "
    )
    @if errorlevel 1 (
        @for %%? in ("iDate" "sDate" "iTime" "sTime" "F" "Y" "M" "D" "H" "I" "S") do @set "_DT_%%~?_=%%~?"
        @for %%? in ("Date" "Time") do @for /f "skip=2 tokens=1,3" %%a in ('reg query "HKCU\Control Panel\International" /v ?%%~? 2^>nul') do @for /f %%x in ('echo:%%_DT_%%a_%%') do @if "%%x"=="%%a" set "_DT_%%a_=%%b"
        @for /f "tokens=1-3 delims=%_DT_T_%" %%a in ("%time%") do @set "_DT_T_=%%a%%b%%c"
    )
    @if errorlevel 1 (
        @if "%_DT_iDate_%"=="0" (set "_DT_F_=_DT_D_ _DT_Y_ _DT_M_") else if "%_DT_iDate_%"=="1" (set "_DT_F_=_DT_D_ _DT_M_ _DT_Y_") else if "%_DT_iDate_%"=="2" (set "_DT_F_=_DT_Y_ _DT_M_ _DT_D_")
        @for /f "tokens=1-4* delims=%_DT_sDate_%" %%a in ('date/t') do @for /f "tokens=1-3" %%x in ('echo:%%_DT_F_%%') do @set "%%x=%%a" & set "%%y=%%b" & set "%%z=%%c"
        @for /f "tokens=1-3 delims=%_DT_T_%" %%a in ("%time%") do @set "_DT_H_=%%a" & set "_DT_I_=%%b" & set "_DT_S_=%%c"
        @for %%? in ("iDate" "sDate" "iTime" "sTime" "F" "T") do @set "_DT_%%~?_="
    )
    @for %%i in ("Y"                ) do @for /f %%j in ('echo:"%%_DT_%%~i_%%"') do @set /a _DT_%%~i_+=  0 & @for /f %%k in ('echo:"%%_DT_%%~i_:~-4%%"') do @set "_DT_%%~i_=%%~k"
    @for %%i in ("M" "D" "H" "I" "S") do @for /f %%j in ('echo:"%%_DT_%%~i_%%"') do @set /a _DT_%%~i_+=100 & @for /f %%k in ('echo:"%%_DT_%%~i_:~-2%%"') do @set "_DT_%%~i_=%%~k"
@exit/b
SerGeeK Kasimov
źródło
1

W takich sytuacjach skorzystaj z prostego, standardowego podejścia programistycznego: Zamiast wkładać ogromny wysiłek w analizowanie nieznanego elementu, po prostu zapisz bieżącą konfigurację, zresetuj ją do znanego stanu, wyodrębnij informacje, a następnie przywróć pierwotny stan. Używaj tylko standardowych zasobów Windows.

W szczególności formaty daty i godziny są przechowywane pod kluczem rejestru HKCU \ Control Panel \ International \ w [definicji MS] „wartości”: „sTimeFormat” i „sShortDate”. Reg to edytor rejestru konsoli dołączany do wszystkich wersji systemu Windows. Podwyższone uprawnienia nie są wymagane do modyfikowania klucza HKCU

Prompt $N:$D $T$G

::Save current config to a temporary (unique name) subkey, Exit if copy fails
Set DateTime=
Set ran=%Random%
Reg copy "HKCU\Control Panel\International" "HKCU\Control Panel\International-Temp%ran%" /f
If ErrorLevel 1 GoTO :EOF

::Reset the date format to your desired output format (take effect immediately)
::Resetting the time format is useless as it only affect subsequent console windows
::Reg add "HKCU\Control Panel\International" /v sTimeFormat /d "HH_mm_ss"   /f
Reg add "HKCU\Control Panel\International" /v sShortDate  /d "yyyy_MM_dd" /f

::Concatenate the time and (reformatted) date strings, replace any embedded blanks with zeros
Set DateTime=%date%__%time:~0,2%_%time:~3,2%_%time:~6,2%
Set DateTime=%DateTime: =0%

::Restore the original config and delete the temp subkey, Exit if restore fails
Reg copy   "HKCU\Control Panel\International-Temp%ran%" "HKCU\Control Panel\International" /f
If ErrorLevel 1 GoTO :EOF
Reg delete "HKCU\Control Panel\International-Temp%ran%" /f

Prosty, bezpośredni i powinien działać dla wszystkich regionów.

Z powodów, których nie rozumiem, resetowanie wartości „sShortDate” zaczyna obowiązywać natychmiast w oknie konsoli, ale resetowanie bardzo podobnej wartości „sTimeFormat” NIE działa, dopóki nie otworzy się nowe okno konsoli. Jednak jedyne, co można zmienić, to ogranicznik - pozycje cyfr są ustalone. Podobnie, token czasowy „HH” ma poprzedzać zera na początku, ale tak nie jest. Na szczęście obejścia są łatwe.

ArtK
źródło
-1 „Zamiast dodawać wiodące zero, dlaczego nie zakłócasz konfiguracji maszyny, nie zmieniasz jej na przypadkową potrzebę, a potem robisz swoje?” To podejście jest nie z tego świata, wymaga znacznego wysiłku i może prowadzić do nieskończonej liczby niepożądanych konsekwencji. Nie chcę nawet rozpoczynać dyskusji na temat czytelności i standardowego oczekiwanego zachowania kodu. sława.
vaitrafra
Resetowanie sTimeFormatformatu czasu jest bezużyteczne . Nie. Ponieważ ma to wpływ na kolejne monity konsoli, zastosuj je za pomocąfor /f "delims=" %%G in ('cmd /C echo SET "DateTime=%%date%%__%%time%%"') do %%G
JosefZ
1

Ten skrypt używa interfejsu WMI, do którego dostęp uzyskuje się głównie za pomocą narzędzia WMIC, które jest integralną częścią systemu Windows od Windows XP Professional (edycja Home jest również obsługiwana, ale narzędzie nie jest instalowane domyślnie). Skrypt implementuje również obejście brakującego narzędzia WMIC, tworząc i wywołując skrypt WSH vbscript w celu uzyskania dostępu do interfejsu WMI i zapisywania na konsoli danych wyjściowych w tym samym formacie, jaki zapewnia narzędzie WMIC.

@ECHO OFF
REM Returns: RETURN
REM Modify:  RETURN, StdOut
REM Required - mandatory: none
REM Required - optionaly: format strings delimited by a space to format an output delimited by predefined delimiter
REM    YYYY = 4-digit year
REM      MM = 2-digit month
REM      DD = 2-digit day
REM      hh = 2-digit hour
REM      mm = 2-digit minute
REM      ss = 2-digit second
REM      ms = 3-digit millisecond

CALL :getTime %*
ECHO %RETURN%
GOTO :EOF


REM SUBROUTINE
REM Returns: RETURN
REM Modify:  RETURN
REM Required - mandatory: none
REM Required - optionaly: format strings delimited by a space to format an output delimited by predefined delimiter
REM    YYYY = 4-digit year
REM      MM = 2-digit month
REM      DD = 2-digit day
REM      hh = 2-digit hour
REM      mm = 2-digit minute
REM      ss = 2-digit second
REM      ms = 3-digit millisecond
:getTime
  SETLOCAL EnableDelayedExpansion
    SET DELIM=-
    WHERE /Q wmic.exe
    IF NOT ERRORLEVEL 1 FOR /F "usebackq skip=1 tokens=*" %%x IN (`wmic.exe os get LocalDateTime`) DO (SET DT=%%x & GOTO getTime_Parse)
    SET _TMP=%TEMP:"=%
    ECHO Wscript.StdOut.WriteLine (GetObject("winmgmts:root\cimv2:Win32_OperatingSystem=@").LocalDateTime)>"%_TMP%\get_time_local-helper.vbs"
    FOR /F "usebackq tokens=*" %%x IN (`cscript //B //NoLogo "%_TMP%\get_time_local-helper.vbs"`) DO (SET DT=%%x & GOTO getTime_Parse)
    :getTime_Parse
      SET _RET=
      IF "%1" EQU "" (
        SET _RET=%DT:~0,4%%DELIM%%DT:~4,2%%DELIM%%DT:~6,2%%DELIM%%DT:~8,2%%DELIM%%DT:~10,2%%DELIM%%DT:~12,2%%DELIM%%DT:~15,3%
      ) ELSE (
        REM Not recognized format strings are ignored during parsing - no error is reported.
       :getTime_ParseLoop
         SET _VAL=
         IF "%1" EQU "YYYY" SET _VAL=%DT:~0,4%
         IF "%1" EQU "MM"   SET _VAL=%DT:~4,2%
         IF "%1" EQU "DD"   SET _VAL=%DT:~6,2%
         IF "%1" EQU "hh"   SET _VAL=%DT:~8,2%
         IF "%1" EQU "mm"   SET _VAL=%DT:~10,2%
         IF "%1" EQU "ss"   SET _VAL=%DT:~12,2%
         IF "%1" EQU "ms"   SET _VAL=%DT:~15,3%
         IF DEFINED _VAL (
           IF DEFINED _RET (
             SET _RET=!_RET!%DELIM%!_VAL!
           ) ELSE (
             SET _RET=!_VAL!
           )
         )
         SHIFT
         IF "%1" NEQ "" GOTO getTime_ParseLoop
      )
  ENDLOCAL & SET RETURN=%_RET%
GOTO :EOF
Petr Matlas
źródło
1

Przyjemnym trikiem jednoliniowym, aby uniknąć wczesnego rozszerzenia zmiennej, jest użycie cmd /c echo ^%time^%

cmd /c echo ^%time^% & dir /s somelongcommand & cmd /c echo ^%time^%
tresf
źródło
0
:: =============================================================
:: Batch file to display Date and Time seprated by undescore.
:: =============================================================
:: Read the system date.
:: =============================================================
@SET MyDate=%DATE%
@SET MyDate=%MyDate:/=:%
@SET MyDate=%MyDate:-=:%
@SET MyDate=%MyDate: =:%
@SET MyDate=%MyDate:\=:%
@SET MyDate=%MyDate::=_%
:: =============================================================
:: Read the system time.
:: =============================================================
@SET MyTime=%TIME%
@SET MyTime=%MyTime: =0%
@SET MyTime=%MyTime:.=:%
@SET MyTime=%MyTime::=_%
:: =============================================================
:: Build the DateTime string.
:: =============================================================
@SET DateTime=%MyDate%_%MyTime%
:: =============================================================
:: Display the Date and Time as it is now.
:: =============================================================
@ECHO MyDate="%MyDate%" MyTime="%MyTime%" DateTime="%DateTime%"
:: =============================================================
:: Wait before close.
:: =============================================================
@PAUSE
:: =============================================================
Christo
źródło
0

Aby uzyskać bardzo proste rozwiązanie dla daty numerycznej do użycia w nazwach plików, użyj następującego kodu:

set month=%date:~4,2%
set day=%date:~7,2%
set curTimestamp=%month%%day%%year%

rem then the you can add a prefix and a file extension easily like this
echo updates%curTimestamp%.txt
Thomas Boomer
źródło
0

Podziel wyniki polecenia daty ukośnikiem, a następnie możesz przenieść każdy z tokenów do odpowiednich zmiennych.

FOR /F "tokens=1-3 delims=/" %%a IN ("%date:~4%") DO (
SET _Month=%%a
SET _Day=%%b
SET _Year=%%c
)
ECHO Month %_Month%
ECHO Day %_Day%
ECHO Year %_Year%
Casey
źródło