Как сохранить текущую дату в формате ГГГГ-ММ-ДД в какую-либо переменную в файле Windows .bat?
Аналог оболочки Unix:
today=`date +%F`
echo $today
Как сохранить текущую дату в формате ГГГГ-ММ-ДД в какую-либо переменную в файле 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=
промежуточные. Думаю, вот на что споткнулся 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%
неверный ответ: возвращает однозначный месяц и день. Как получить 2-значное левое дополнение с нулевой строкой месяца и дня до даты?
Если вы хотите добиться этого с помощью стандартных команд 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 Не может получить год и день недели. Он сравнительно медленный, также создает временный файл и основан на отметках времени, которые logman помещает в свои файлы журнала. Работает все, начиная с Windows XP и выше. Вероятно, он никогда не будет использоваться кем-либо, включая меня, но это еще один способ ...
@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 комментарий, которого правильно выше формат времени будет работать только , если ваша дата / возвращает 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
такой, используйте верхний MM для месяца и обратную косую черту, чтобы избежать буквальных символов.
Из-за того, что формат даты и времени - это информация о местоположении, получение их из переменных% 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
Это расширение ответа Джои, чтобы включить время и заполнить части нулями.
Например, результат будет 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, который требует обходных решений для многих простых задач? Почему мы должны использовать неправильный инструмент для работы?