Як зберегти поточну дату у форматі YYYY-MM-DD у певну змінну у файлі Windows .bat?
Аналог оболонки Unix:
today=`date +%F`
echo $today
Як зберегти поточну дату у форматі YYYY-MM-DD у певну змінну у файлі Windows .bat?
Аналог оболонки Unix:
today=`date +%F`
echo $today
Відповіді:
Ви можете отримати поточну дату локально-агностично, використовуючи
for /f "skip=1" %%x in ('wmic os get localdatetime') do if not defined MyDate set MyDate=%%x
Потім ви можете витягти окремі частини за допомогою підрядків:
set today=%MyDate:~0,4%-%MyDate:~4,2%-%MyDate:~6,2%
Іншим способом, де ви отримуєте змінні, які містять окремі частини, буде:
for /f %%x in ('wmic path win32_localtime get /format:list ^| findstr "="') do set %%x
set today=%Year%-%Month%-%Day%
Набагато приємніше, ніж поспіль з підрядками, за рахунок забруднення вашого змінного простору імен.
Якщо вам потрібен UTC замість місцевого часу, команда більш-менш однакова:
for /f %%x in ('wmic path win32_utctime get /format:list ^| findstr "="') do set %%x
set today=%Year%-%Month%-%Day%
for /fповертає два рядки, останній з яких є порожнім. Ви можете вирішити це, використовуючи set MyDate=між ними. Я думаю, що саме про це натрапив користувач2023861.
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% невірна відповідь: вона повертає один раз місяць і день. Як отримати двозначну ліву підкладку з нульовим місячним і денним рядком дати?
Якщо ви хочете досягти цього, використовуючи стандартні команди MS-DOS у пакетному файлі, ви можете використовувати:
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
Я впевнений, що це можна вдосконалити далі, але це дає дату в 3 змінних для Дня (ДД), Місяця (мм) та Року (рр. Р-р). Потім ви можете використовувати їх пізніше в пакетному сценарії, як потрібно.
SET todaysdate=%yyyy%%mm%%dd%
echo %dd%
echo %mm%
echo %yyyy%
echo %todaysdate%
Хоча я розумію, що на це питання було прийнято відповідь, цей альтернативний метод може бути оцінений багатьма, хто хоче досягти цього, не використовуючи консоль WMI, тому сподіваюся, що це додасть певного значення цьому питанню.
Використовуйте date /Tдля пошуку формату в командному рядку.
Якщо формат дати Thu 17/03/2016використовується таким чином:
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%
Ще два способи, які не залежать від налаштувань часу (обидва взяті з способу отримання даних / часу незалежними від локалізації ). І обидва також отримують день тижня, і жоден з них не вимагає дозволу адміністратора!
MAKECAB - буде працювати в КОЖНІЙ системі Windows (швидко, але створює невеликий тимчасовий файл) (сценарій 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 - це не рідна команда для Windows XP та Windows Server 2003 , але її можна завантажити з сайту Microsoft . Але він вбудований у все від Windows Vista і вище:
@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
І ще три способи, що використовують інші мови скриптів Windows. Вони дадуть вам більше гнучкості, наприклад, ви можете отримати тиждень року, час у мілісекундах тощо.
JScript / BATCH гібрид (потрібно зберегти як .bat). JScript доступний у будь-якій системі від Windows NT і вище, як частина Windows Script Host ( хоча його можна відключити через реєстр, це рідкісний випадок ):
@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());
Гібрид VBScript / BATCH ( Чи можна вставляти та виконувати VBScript у пакетному файлі без використання тимчасового файлу? ) Той самий випадок, що й jscript, але гібридизація не така ідеальна:
: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 - може встановлюватися на кожній машині, у якій є .NET - завантаження з Microsoft ( v1 , v2 та v3 (лише для Windows 7 і вище)). Установлено за замовчуванням у всіх формах Windows 7 / Win2008 і вище:
C:\> powershell get-date -format "{dd-MMM-yyyy HH:mm}"
Самостійно складений jscript.net/batch (я ніколи не бачив машину Windows без .NET, тому думаю, що це досить портативний):
@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 Це не може отримати рік і день тижня. Він порівняно повільний, також створює тимчасовий файл і базується на часових марках, які логман ставить на свої файли журналів. Це, мабуть, ніколи не буде використовуватися кимось, включаючи мене, - але це ще один спосіб ...
@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
Детальніше про функцію Get-Date .
Мені дуже сподобався метод Джої, але я думав, що трохи розширюся на ньому.
При такому підході ви можете запускати код кілька разів і не турбуватися про те, що старе значення "приклеюється", оскільки воно вже визначене.
Кожен раз, коли ви запускаєте цей пакетний файл, він виводить суміщене подання дати та часу, сумісне за 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%
У цій версії вам потрібно бути обережним, щоб не копіювати / вставляти один і той же код у кілька місць у файлі, оскільки це може спричинити повторювані мітки. Ви можете мати окрему мітку для кожної копії, або просто помістити цей код у свій власний пакетний файл і викликати його зі свого вихідного файлу, де це необхідно.
Відповідно до відповіді від @ProVi, просто змініть, щоб відповідати потрібному форматуванню
echo %DATE:~10,4%-%DATE:~7,2%-%DATE:~4,2% %TIME:~0,2%:%TIME:~3,2%:%TIME:~6,2%
повернеться
yyyy-MM-dd hh:mm:ss
2015-09-15 18:36:11
EDIT Відповідно до коментаря @Jeb, хто правильний, вказаний вище формат часу працюватиме лише у випадку, якщо ваша команда DATE / T повернеться
ddd dd/mm/yyyy
Thu 17/09/2015
Однак це легко редагувати відповідно до вашої мови, використовуючи індексацію кожного символу в рядку, що повертається відповідною змінною середовища DATE%, ви можете витягти потрібні частини рядка.
напр. Використання% DATE ~ 10,4% дозволить розширити змінну середовища DATE, а потім використовувати лише 4 символи, які починаються з 11-го (зсув 10) символу розширеного результату
Наприклад, якщо використовуються дати в стилі США, застосовується наступне
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
Перевірте це ..
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
Якщо у вас встановлений Python, ви можете це зробити
python -c "import datetime;print(datetime.date.today().strftime('%Y-%m-%d'))"
Ви можете легко адаптувати рядок формату під свої потреби.
python -c "import datetime;print(datetime.date.today())", оскільки __str__метод dateкласу просто викликає isoformat().
Можна використовувати PowerShell і перенаправити його вихід на змінну середовища, використовуючи цикл.
З командного рядка ( 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
У пакетному файлі ви можете втекти %aяк %%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 то використовуйте верхню частину ММ на місяць та зворотну косу рису, щоб уникнути буквальних символів.
Зважаючи на формат дати та часу - це інформація, що залежить від місця розташування, для їх отримання з змінних% date% та% time% знадобиться додаткове зусилля для розбору рядка з перетворенням формату на увагу. Доброю ідеєю є використання деяких API для отримання структури даних та розбору за вашим бажанням. WMIC - хороший вибір. Нижче наведено приклад використання Win32_LocalTime . Ви також можете використовувати Win32_CurrentTime або 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
Результат:
2018-04-25_10: 03: 11
Це розширення відповіді Джої, щоб включити час і прокладати частини 0.
Наприклад, результат буде 2019-06-01_17-25-36. Також зауважте, що це час 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%
Я використовую наступне:
set iso_date=%date:~6,4%-%date:~3,2%-%date:~0,2%
Або в поєднанні з назвою лог-файлу "MyLogFileName":
set log_file=%date:~6,4%-%date:~3,2%-%date:~0,2%-MyLogFileName
Якщо ви не заперечуєте проти одноразової інвестиції від 10 до 30 хвилин, щоб отримати надійне рішення (це не залежить від параметрів регіону Windows), будь ласка, читайте далі.
Давайте звільнимо свій розум. Ви хочете спростити сценарії, щоб вони виглядали так? (Припустимо, ви хочете встановити змінну 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
Ти можеш. Просто побудуйте FormatNow.exe за допомогою C # .NET і додайте його у свій PATH.
Примітки:
Переваги:
Вихідний код FormatNow.exe, який я створив за допомогою Visual Studio 2010 (я вважаю за краще створити його сам, щоб уникнути ризику завантаження невідомої, можливо, шкідливої програми). Просто скопіюйте та вставте коди нижче, складіть програму один раз, і тоді у вас є надійний формат формат дати для всіх майбутніх цілей.
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());
}
}
}
}
Взагалі, працюючи зі складною логікою, ми можемо спростити її, побудувавши дуже невелику програму і викликавши програму для отримання виводу назад до змінної пакетного сценарію. Ми не студенти, і ми не беремо іспитів, щоб вимагати, щоб ми дотримувались правила єдиного сценарію для вирішення проблем. У реальному робочому середовищі дозволений будь-який (законний) метод. Чому ми все-таки повинні дотримуватися слабких можливостей пакетного сценарію Windows, який потребує вирішення багатьох простих завдань? Чому ми повинні використовувати неправильний інструмент для роботи?