Jak zapisać bieżącą datę w formacie RRRR-MM-DD w jakiejś zmiennej w pliku .bat systemu Windows?
Analog powłoki Unix:
today=`date +%F`
echo $today
Jak zapisać bieżącą datę w formacie RRRR-MM-DD w jakiejś zmiennej w pliku .bat systemu Windows?
Analog powłoki Unix:
today=`date +%F`
echo $today
Odpowiedzi:
Możesz uzyskać bieżącą datę w sposób niezależny od ustawień regionalnych za pomocą
for /f "skip=1" %%x in ('wmic os get localdatetime') do if not defined MyDate set MyDate=%%x
Następnie możesz wyodrębnić poszczególne części za pomocą podciągów:
set today=%MyDate:~0,4%-%MyDate:~4,2%-%MyDate:~6,2%
Innym sposobem, w którym otrzymujesz zmienne zawierające poszczególne części, byłoby:
for /f %%x in ('wmic path win32_localtime get /format:list ^| findstr "="') do set %%x
set today=%Year%-%Month%-%Day%
O wiele przyjemniejsze niż majstrowanie przy podciągach kosztem zanieczyszczania przestrzeni nazw zmiennych.
Jeśli potrzebujesz czasu UTC zamiast czasu lokalnego, polecenie jest mniej więcej takie samo:
for /f %%x in ('wmic path win32_utctime get /format:list ^| findstr "="') do set %%x
set today=%Year%-%Month%-%Day%
for /f
zwraca dwie linie, z których druga jest pusta. Możesz rozwiązać ten problem, używając set MyDate=
pomiędzy. Myślę, że właśnie o to natknął się user2023861.
Year
, Month
, Day
, Hour
, Minute
, Second
, Quarter
, WeekInMonth
,DayOfWeek
for /f %%x in ('wmic path win32_localtime get /format:list ^| findstr "="') do set %%x set today=%Year%-%Month%-%Day%
jest nieprawidłową odpowiedzią: zwraca jedną cyfrę miesiąca i dnia. Jak uzyskać 2-cyfrowe lewe wypełnione zerowym ciągiem miesiąca i dnia do daty?
Jeśli chcesz to osiągnąć za pomocą standardowych poleceń MS-DOS w pliku wsadowym, możesz użyć:
FOR /F "TOKENS=1 eol=/ DELIMS=/ " %%A IN ('DATE/T') DO SET dd=%%A
FOR /F "TOKENS=1,2 eol=/ DELIMS=/ " %%A IN ('DATE/T') DO SET mm=%%B
FOR /F "TOKENS=1,2,3 eol=/ DELIMS=/ " %%A IN ('DATE/T') DO SET yyyy=%%C
Jestem pewien, że można to poprawić, ale daje to datę na 3 zmienne dla dnia (dd), miesiąca (mm) i roku (rrrr). W razie potrzeby można ich później użyć w skrypcie wsadowym.
SET todaysdate=%yyyy%%mm%%dd%
echo %dd%
echo %mm%
echo %yyyy%
echo %todaysdate%
Chociaż rozumiem, że odpowiedź na to pytanie została zaakceptowana, ta alternatywna metoda może być doceniona przez wielu, którzy chcą to osiągnąć bez korzystania z konsoli WMI, więc mam nadzieję, że doda ona trochę wartości do tego pytania.
Użyj, date /T
aby znaleźć format w wierszu polecenia.
Jeśli format daty jest Thu 17/03/2016
używany w następujący sposób:
set datestr=%date:~10,4%-%date:~7,2%-%date:~4,2%
echo %datestr%
SELECT CONVERT(VARCHAR(16), GETDATE(), 112)
”.
%date:~10,4%%date:~7,2%%date:~4,2%T%time:~0,2%%time:~3,2%%time:~6,2%
Jeszcze dwa sposoby, które nie zależą od ustawień czasu (oba pochodzą z artykułu Jak uzyskać dane / czas niezależnie od lokalizacji ). Oba również otrzymują dzień tygodnia i żaden z nich nie wymaga uprawnień administratora !:
MAKECAB - będzie działać na KAŻDYM systemie Windows (szybko, ale tworzy mały plik tymczasowy) (skrypt foxidrive):
@echo off
pushd "%temp%"
makecab /D RptFileName=~.rpt /D InfFileName=~.inf /f nul >nul
for /f "tokens=3-7" %%a in ('find /i "makecab"^<~.rpt') do (
set "current-date=%%e-%%b-%%c"
set "current-time=%%d"
set "weekday=%%a"
)
del ~.*
popd
echo %weekday% %current-date% %current-time%
pause
ROBOCOPY - nie jest to natywne polecenie dla Windows XP i Windows Server 2003 , ale można je pobrać ze strony Microsoft . Ale jest wbudowany we wszystko od Windows Vista i nowszych:
@echo off
setlocal
for /f "skip=8 tokens=2,3,4,5,6,7,8 delims=: " %%D in ('robocopy /l * \ \ /ns /nc /ndl /nfl /np /njh /XF * /XD *') do (
set "dow=%%D"
set "month=%%E"
set "day=%%F"
set "HH=%%G"
set "MM=%%H"
set "SS=%%I"
set "year=%%J"
)
echo Day of the week: %dow%
echo Day of the month : %day%
echo Month : %month%
echo hour : %HH%
echo minutes : %MM%
echo seconds : %SS%
echo year : %year%
endlocal
I jeszcze trzy sposoby korzystania z innych języków skryptów systemu Windows. Dadzą ci większą elastyczność, np. Możesz uzyskać tydzień w roku, czas w milisekundach i tak dalej.
Hybryda JScript / BATCH (należy zapisać jako .bat
). JScript jest dostępny na każdym systemie od Windows NT i nowszych jako część Hosta skryptów systemu Windows ( chociaż można go wyłączyć przez rejestr, jest to rzadki przypadek ):
@if (@X)==(@Y) @end /* ---Harmless hybrid line that begins a JScript comment
@echo off
cscript //E:JScript //nologo "%~f0"
exit /b 0
*------------------------------------------------------------------------------*/
function GetCurrentDate() {
// Today date time which will used to set as default date.
var todayDate = new Date();
todayDate = todayDate.getFullYear() + "-" +
("0" + (todayDate.getMonth() + 1)).slice(-2) + "-" +
("0" + todayDate.getDate()).slice(-2) + " " + ("0" + todayDate.getHours()).slice(-2) + ":" +
("0" + todayDate.getMinutes()).slice(-2);
return todayDate;
}
WScript.Echo(GetCurrentDate());
Hybryda VBScript / BATCH ( czy możliwe jest osadzenie i wykonanie VBScript w pliku wsadowym bez użycia pliku tymczasowego? ) Ten sam przypadek co jscript, ale hybrydyzacja nie jest tak doskonała:
:sub echo(str) :end sub
echo off
'>nul 2>&1|| copy /Y %windir%\System32\doskey.exe %windir%\System32\'.exe >nul
'& echo current date:
'& cscript /nologo /E:vbscript "%~f0"
'& exit /b
'0 = vbGeneralDate - Default. Returns date: mm/dd/yy and time if specified: hh:mm:ss PM/AM.
'1 = vbLongDate - Returns date: weekday, monthname, year
'2 = vbShortDate - Returns date: mm/dd/yy
'3 = vbLongTime - Returns time: hh:mm:ss PM/AM
'4 = vbShortTime - Return time: hh:mm
WScript.echo Replace(FormatDateTime(Date, 1), ", ", "-")
PowerShell - można go zainstalować na każdym komputerze z platformą .NET - pobrać z firmy Microsoft ( v1 , v2 i v3 (tylko dla Windows 7 i nowszych)). Instalowany domyślnie na wszystkim z Windows 7 / Win2008 i nowszych:
C:\> powershell get-date -format "{dd-MMM-yyyy HH:mm}"
Samodzielnie skompilowany jscript.net/batch (nigdy nie widziałem komputera z systemem Windows bez .NET, więc myślę, że jest to całkiem przenośny):
@if (@X)==(@Y) @end /****** silent line that start jscript comment ******
@echo off
::::::::::::::::::::::::::::::::::::
::: Compile the script ::::
::::::::::::::::::::::::::::::::::::
setlocal
if exist "%~n0.exe" goto :skip_compilation
set "frm=%SystemRoot%\Microsoft.NET\Framework\"
:: searching the latest installed .net framework
for /f "tokens=* delims=" %%v in ('dir /b /s /a:d /o:-n "%SystemRoot%\Microsoft.NET\Framework\v*"') do (
if exist "%%v\jsc.exe" (
rem :: the javascript.net compiler
set "jsc=%%~dpsnfxv\jsc.exe"
goto :break_loop
)
)
echo jsc.exe not found && exit /b 0
:break_loop
call %jsc% /nologo /out:"%~n0.exe" "%~dpsfnx0"
::::::::::::::::::::::::::::::::::::
::: End of compilation ::::
::::::::::::::::::::::::::::::::::::
:skip_compilation
"%~n0.exe"
exit /b 0
****** End of JScript comment ******/
import System;
import System.IO;
var dt=DateTime.Now;
Console.WriteLine(dt.ToString("yyyy-MM-dd hh:mm:ss"));
Logman Nie można uzyskać roku i dnia tygodnia. Jest stosunkowo wolny, tworzy również plik tymczasowy i jest oparty na sygnaturach czasowych, które logman umieszcza w swoich plikach dziennika. Będzie działać wszystko od Windows XP i nowszych. Prawdopodobnie nigdy nie będzie używany przez nikogo - łącznie ze mną - ale to jeszcze jeden sposób ...
@echo off
setlocal
del /q /f %temp%\timestampfile_*
Logman.exe stop ts-CPU 1>nul 2>&1
Logman.exe delete ts-CPU 1>nul 2>&1
Logman.exe create counter ts-CPU -sc 2 -v mmddhhmm -max 250 -c "\Processor(_Total)\%% Processor Time" -o %temp%\timestampfile_ >nul
Logman.exe start ts-CPU 1>nul 2>&1
Logman.exe stop ts-CPU >nul 2>&1
Logman.exe delete ts-CPU >nul 2>&1
for /f "tokens=2 delims=_." %%t in ('dir /b %temp%\timestampfile_*^&del /q/f %temp%\timestampfile_*') do set timestamp=%%t
echo %timestamp%
echo MM: %timestamp:~0,2%
echo dd: %timestamp:~2,2%
echo hh: %timestamp:~4,2%
echo mm: %timestamp:~6,2%
endlocal
exit /b 0
Więcej informacji o funkcji Get-Date .
Naprawdę podobała mi się metoda Joeya, ale pomyślałem, że trochę ją rozwinę.
W tym podejściu można uruchamiać kod wiele razy i nie martwić się, że stara wartość daty „utknie”, ponieważ jest już zdefiniowana.
Za każdym razem, gdy uruchomisz ten plik wsadowy, wygeneruje on połączoną reprezentację daty i godziny zgodną z ISO 8601.
FOR /F "skip=1" %%D IN ('WMIC OS GET LocalDateTime') DO (SET LIDATE=%%D & GOTO :GOT_LIDATE)
:GOT_LIDATE
SET DATETIME=%LIDATE:~0,4%-%LIDATE:~4,2%-%LIDATE:~6,2%T%LIDATE:~8,2%:%LIDATE:~10,2%:%LIDATE:~12,2%
ECHO %DATETIME%
W tej wersji musisz uważać, aby nie skopiować / wkleić tego samego kodu w wielu miejscach w pliku, ponieważ spowodowałoby to zduplikowanie etykiet. Możesz mieć osobną etykietę dla każdej kopii lub po prostu umieścić ten kod we własnym pliku wsadowym i wywołać go z pliku źródłowego, gdy jest to konieczne.
Zgodnie z odpowiedzią @ProVi po prostu zmień, aby dopasować wymagane formatowanie
echo %DATE:~10,4%-%DATE:~7,2%-%DATE:~4,2% %TIME:~0,2%:%TIME:~3,2%:%TIME:~6,2%
wróci
yyyy-MM-dd hh:mm:ss
2015-09-15 18:36:11
EDYCJA Zgodnie z komentarzem @Jeb, kto jest poprawny, powyższy format czasu będzie działał tylko wtedy, gdy polecenie DATE / T powróci
ddd dd/mm/yyyy
Thu 17/09/2015
Edytowanie w celu dostosowania do ustawień regionalnych jest łatwe, jednak za pomocą indeksowania każdego znaku w ciągu zwracanym przez odpowiednią zmienną środowiskową% DATE% można wyodrębnić potrzebne części ciągu.
na przykład. Użycie% DATE ~ 10,4% spowodowałoby rozwinięcie zmiennej środowiskowej DATE, a następnie użycie tylko 4 znaków, które zaczynają się od 11. (przesunięcie 10) znaku rozszerzonego wyniku
Na przykład, jeśli używasz dat w stylu amerykańskim, obowiązują następujące zasady
ddd mm/dd/yyyy
Thu 09/17/2015
echo %DATE:~10,4%-%DATE:~4,2%-%DATE:~7,2% %TIME:~0,2%:%TIME:~3,2%:%TIME:~6,2%
2015-09-17 18:36:11
Sprawdź ten..
for /f "tokens=2 delims==" %%a in ('wmic OS Get localdatetime /value') do set "dt=%%a"
set "YY=%dt:~2,2%" & set "YYYY=%dt:~0,4%" & set "MM=%dt:~4,2%" & set "DD=%dt:~6,2%"
set "HH=%dt:~8,2%" & set "Min=%dt:~10,2%" & set "Sec=%dt:~12,2%" & set "MS=%dt:~15,3%"
set "datestamp=%YYYY%%MM%%DD%" & set "timestamp=%HH%%Min%%Sec%" & set "fullstamp=%YYYY%-%MM%-%DD%_%HH%-%Min%-%Sec%-%MS%"
echo datestamp: "%datestamp%"
echo timestamp: "%timestamp%"
echo fullstamp: "%fullstamp%"
pause
Jeśli masz zainstalowany Python, możesz to zrobić
python -c "import datetime;print(datetime.date.today().strftime('%Y-%m-%d'))"
Możesz łatwo dostosować ciąg formatu do swoich potrzeb.
python -c "import datetime;print(datetime.date.today())"
, ponieważ __str__
metoda date
klasy po prostu wywołuje isoformat()
.
Możliwe jest użycie programu PowerShell i przekierowanie jego danych wyjściowych do zmiennej środowiskowej przy użyciu pętli.
Z wiersza poleceń ( cmd
):
for /f "tokens=*" %a in ('powershell get-date -format "{yyyy-MM-dd+HH:mm}"') do set td=%a
echo %td%
2016-25-02+17:25
W pliku wsadowym możesz uciec %a
jako %%a
:
for /f "tokens=*" %%a in ('powershell get-date -format "{yyyy-MM-dd+HH:mm}"') do set td=%%a
FOR /F "tokens=*" %%a IN ('powershell get-date -format "{yyyy\-MM\-dd\THH\:mm\:ss}"') DO SET date=%%a
tak, więc użyj górnego MM dla miesiąca i ukośnika odwrotnego, aby uniknąć literałów.
Ze względu na to, że format daty i czasu jest informacją specyficzną dla lokalizacji, pobranie ich ze zmiennych% date% i% time% będzie wymagało dodatkowego wysiłku, aby przeanalizować ciąg z uwzględnieniem zmiany formatu. Dobrym pomysłem jest użycie jakiegoś interfejsu API do pobrania struktury danych i przeanalizowania, jak chcesz. WMIC to dobry wybór. Poniższy przykład użyj Win32_LocalTime . Możesz także użyć Win32_CurrentTime lub Win32_UTCTime .
@echo off
SETLOCAL ENABLEDELAYEDEXPANSION
for /f %%x in ('wmic path Win32_LocalTime get /format:list ^| findstr "="') do set %%x
set yyyy=0000%Year%
set mmmm=0000%Month%
set dd=00%Day%
set hh=00%Hour%
set mm=00%Minute%
set ss=00%Second%
set ts=!yyyy:~-4!-!mmmm:~-2!-!dd:~-2!_!hh:~-2!:!mm:~-2!:!ss:~-2!
echo %ts%
ENDLOCAL
Wynik:
2018-04-25_10: 03: 11
Jest to rozszerzenie odpowiedzi Joeya, które obejmuje czas i wypełnia części zerami.
Na przykład wynikiem będzie 2019-06-01_17-25-36. Należy również pamiętać, że jest to czas UTC.
for /f %%x in ('wmic path win32_utctime get /format:list ^| findstr "="') do set %%x
set Month=0%Month%
set Month=%Month:~-2%
set Day=0%Day%
set Day=%Day:~-2%
set Hour=0%Hour%
set Hour=%Hour:~-2%
set Minute=0%Minute%
set Minute=%Minute:~-2%
set Second=0%Second%
set Second=%Second:~-2%
set TimeStamp=%Year%-%Month%-%Day%_%Hour%-%Minute%-%Second%
Używam następujących:
set iso_date=%date:~6,4%-%date:~3,2%-%date:~0,2%
Lub w połączeniu z nazwą pliku dziennika „MyLogFileName”:
set log_file=%date:~6,4%-%date:~3,2%-%date:~0,2%-MyLogFileName
Jeśli nie przeszkadza Ci jednorazowa inwestycja od 10 do 30 minut w celu uzyskania niezawodnego rozwiązania (które nie zależy od ustawień regionalnych systemu Windows), czytaj dalej.
Uwolnijmy nasze umysły. Czy chcesz uprościć skrypty, aby wyglądały tak? (Załóżmy, że chcesz ustawić zmienną LOG_DATETIME)
FOR /F "tokens=* USEBACKQ" %%F IN (`FormatNow "yyyy-MM-dd"`) DO (
Set LOG_DATETIME=%%F
)
echo I am going to write log to Testing_%LOG_DATETIME%.log
Możesz. Po prostu zbuduj FormatNow.exe w C # .NET i dodaj go do swojej PATH.
Uwagi:
Korzyści:
Kod źródłowy programu FormatNow.exe, który zbudowałem w Visual Studio 2010 (wolę zbudować go samodzielnie, aby uniknąć ryzyka pobrania nieznanego, prawdopodobnie złośliwego programu). Po prostu skopiuj i wklej poniższe kody, skompiluj program raz, a otrzymasz niezawodny program formatujący datę do wszystkich przyszłych zastosowań.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;
namespace FormatNow
{
class Program
{
static void Main(string[] args)
{
try
{
if (args.Length < 1)
{
throw new ArgumentException("Missing format");
}
string format = args[0];
Console.Write(DateTime.Now.ToString(format, CultureInfo.InvariantCulture.DateTimeFormat));
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
}
}
Ogólnie rzecz biorąc, gdy mamy do czynienia ze skomplikowaną logiką, możemy to uprościć, tworząc bardzo mały program i wywołując program, aby zamiast tego przechwycić dane wyjściowe z powrotem do zmiennej skryptu wsadowego. Nie jesteśmy studentami i nie podchodzimy do egzaminów wymagających od nas przestrzegania zasady wsadowego scenariusza w celu rozwiązania problemów. W rzeczywistym środowisku pracy dozwolona jest każda (legalna) metoda. Dlaczego nadal mielibyśmy trzymać się słabych możliwości skryptu wsadowego systemu Windows, który wymaga obejścia wielu prostych zadań? Dlaczego powinniśmy używać niewłaściwego narzędzia do pracy?