Формат даты и времени в пакетном скрипте Windows

193

В пакетном скрипте Windows (Windows XP) мне нужно отформатировать текущую дату и время для последующего использования в именах файлов и т. Д.

Это похоже на вопрос переполнения стека Как добавить дату в пакетных файлах , но также со временем.

У меня есть это до сих пор:

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%

который дает:

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

Можно ли как-то разрешить однозначный час в% TIME%, чтобы я мог получить следующее?

2009_07_28__08_36_01
Laurie
источник
Вы можете заменить пустые места в своей datetimefпеременной и вместо этого поставить 0. На вашем примере:SET datetimef=%datetimef: =0%
SebaGra

Ответы:

148

Я закончил с этим сценарием:

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%

:: На WIN2008R2, например, мне нужно было сделать ваш «установленный месяц =% date: ~ 3,2%», как показано ниже :: в противном случае 00 появляется для MONTH

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
источник
11
К вашему сведению, в Windows Server 2003 и Windows 7 этот сценарий дал мне «201200Mo_085806» (правильный год и время).
sfuqua
50
Как примечание для тех, кто приедет сюда из Google (например, я): это зависит от локали, поэтому для работы на неанглийской Windows может потребоваться настройка!
PiotrK
я сделал это следующим образом: 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% fDate% -> 201310170928
Лед
Что делает% time: ~ 0,2%, где находится некоторая документация по структуре: ~,%?
user1605665
6
Все это можно сделать всего за 2 строки, используя обычную замену строк: stackoverflow.com/a/23558738/1879699
Андреас
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
STH
источник
2
На Windows Server 2003 и Windows 7 это дало мне правильную строку. Гораздо элегантнее, чем то, что я построил в прошлом, так что спасибо!
sfuqua
3
Вот что он дает мне в Windows 7 с русским языком. Текущее время: 2013-05-03T02: 22: 51, но скрипт выводит: «2013-5.-01_02_22_51»
ночной кодер
7
% Date% даст другую строку с другой локалью.
AechoLiu
2
возвращает мне 20146.0._173502 (чешский язык)
Muflix,
2
64-битное окончание win7, неверное время: 20140.01_131612, должно быть (2014.10.26_131612)
waza123
67

Вот как я генерирую имя файла журнала (на основе 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
источник
5
лучший ответ на SO для вопросов о независимой от локали генерации метки времени в партии.
Майк Кэмпбелл
2
Потрясающие! Должен быть способ пометить это как решение
Rado
49

Я обычно делаю это таким образом, когда мне нужна строка даты / времени:

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

Это для немецкого формата даты / времени (дд.мм.гггг чч: мм: сс). По сути, я объединяю подстроки и, наконец, заменяю все пробелы нулями.

Краткое объяснение того, как работают подстроки:

%VARIABLE:~num_chars_to_skip,num_chars_to_keep%

Таким образом, чтобы получить год от даты, такой как «29.03.2018», используйте:

%DATE:~6,4%
       ^-----skip 6 characters
         ^---keep 4 characters 
Andreas
источник
7
безусловно, самое элегантное решение, когда вам просто нужна чистая временная метка (без пробелов и других символов)
jvdneste
1
Не могу согласиться с @jvdneste, спасибо, что поделились
mrt
1
абсолютно великолепно - и работает [требуемый синтаксис очень запутанный, но вряд ли это проблема
автора
38

Если установлен PowerShell, вы можете легко и надежно получить дату / время в любом формате, который вам нравится, например:

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

Конечно, в наше время PowerShell всегда устанавливается, но в Windows XP вы, вероятно, захотите использовать эту технику, только если ваш пакетный скрипт используется в известной среде, где вы знаете, что PS доступен (или проверьте в своем пакетном файле, если PowerShell доступен ...)

Вы можете разумно спросить: зачем вообще использовать командный файл, если вы можете использовать PowerShell, чтобы получить дату / время, но я думаю, что есть несколько очевидных причин: (a) вы не очень хорошо знакомы с PowerShell и по-прежнему предпочитаете делать большинство По-старому, с пакетными файлами, или (b) вы обновляете старый скрипт и не хотите переносить все это на PS.

Г. Ломбард
источник
(а) в моем случае, и это работает отлично (летучая мышь только для моей среды, но у меня смешанные локали на разных ПК). Спасибо!
ccalboni
30

Сегодня я столкнулся с этой проблемой и решил:

SET LOGTIME=%TIME: =0%

Он заменяет пробелы на 0 и, в основном, на ноль в час.

После некоторого быстрого поиска я не узнал, требовались ли для него расширения команд (все еще работал с SETLOCAL DISABLEEXTENSIONS).

opello
источник
ОК, замена в переменных. Теперь - как заменить двоеточие ( :)?
Томаш Гандор
@ TomaszGandor Это работает для меня: echo %TIME: =:%но если это не так, возможно, попытаться избежать :с ^подобным echo %TIME: =^:%(что также работает для меня).
opello
1
+1 для простоты. Двоеточия недействительны в именах файлов. set theTime =% Time :: =% удаляет их. Можете ли вы заменить 0 пробелом, удалить двоеточия и укоротить до 6 символов (удалив, таким образом, десятичную часть) в одном выражении? Это не так уж важно, если он занимает две или три строки. Мне просто любопытно.
riderBill
Не то чтобы я знал. Пожалуйста, продолжайте, если найдете такую!
opello
21

Как уже было отмечено, синтаксический анализ даты и времени полезен только в том случае, если вы знаете формат, используемый текущим пользователем (например, MM / dd / yy или dd-MM-yyyy, просто чтобы назвать два). Это может быть определено, но к тому времени, когда вы выполните все операции выделения и анализа, у вас все равно останется некоторая ситуация, когда используется непредвиденный формат, и потребуется больше настроек.

Вы также можете использовать некоторую внешнюю программу, которая будет возвращать слаг даты в выбранном вами формате, но у этого есть недостатки, связанные с необходимостью распространения утилиты вместе с вашим скриптом / пакетом.

Существуют также пакетные приемы, использующие часы CMOS довольно сырым способом, но это слишком близко к оголенным проводам для большинства людей, а также не всегда предпочтительное место для получения даты / времени.

Ниже приведено решение, которое позволяет избежать вышеуказанных проблем. Да, это создает некоторые другие проблемы, но для моих целей я обнаружил, что это самое простое, понятное и портативное решение для создания меток даты в файлах .bat для современных систем Windows. Это всего лишь пример, но я думаю, вы увидите, как изменить другие форматы даты и / или времени и т. Д.

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
источник
3
Как раз то, что я искал. Что-то, что работает в любой локали. Спасибо!
Lost_DM
+1 за «современные системы Windows», с которыми мы имеем дело :) Шутки в сторону, это очень изобретательный и, как вы сказали, переносимый способ решения проблемы.
Зак Янг
9
Это ужасное решение. Если это не удается, то глобальные настройки постоянно изменяются. Это также вводит условия гонки с другими приложениями.
MikeKulls
Вы можете использовать эту reg query "HKCU\Control Panel\International" /v sShortDateчасть, не изменяя настройки реестра (упражнение оставлено читателю!).
Трикасс
9

Следующее может быть не прямым ответом, а близким?

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%

По крайней мере, это может быть вдохновляющим.

ufukgun
источник
9

Если вам не нужен этот формат:

2009_07_28__08_36_01

Затем вы можете использовать следующие 3 строки кода, которые используют% date% и% time%:

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

Примечание. Символы /и :удаляются, а символ .и пробел заменяются подчеркиванием.

Пример выходных данных (взятый в среду, 5/5/15 в 12:49 с 50 секундами и 93 миллисекундами):

echo %mytimestamp%
Wed_08052015_124950_93
Джесси
источник
если час меньше 12, установите mydate =% date: / =% set mytime =% time :: =% set mytime =% mytime: = 0% set mytimestamp =% mydate: = _% _% mytime:. = _ %
рагче
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%
Майк Рейнхем
источник
6

offset:lengthФорматирование поддерживается с SETкомандой в Windows , не позволит вам с планшетом , 0как вам кажется, быть заинтересованы в.

Тем не менее, вы можете написать скрипт BATCH, чтобы проверить, что час меньше, 10и
дополнить его другой echoстрокой.

По этой ссылке вы найдете информацию о SETкоманде .


Вы также можете перейти на другие методы программирования, чтобы получить здесь.

В Unix Bash (доступно с Cygwin для Windows) довольно просто сказать:

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

И это всегда правильно.

Nik
источник
6

Я сделал это так:

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

лед
источник
Он работает на английском сервере (Имя ОС: Microsoft (R) Windows 2003 Server Standard x64 Edition, версия ОС: 5.2.3790 с пакетом обновления 2, сборка 3790)
Ice
1
а также протестировано на немецком сервере (Betriebssystemname: Microsoft® Windows Server® 2008 Enterprise, Betriebssystemversion: 6.0.6002 с пакетом обновления 2, сборка 6002)
Ice
1
Даже с этим не все в порядке: (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%  

Первая строка всегда выводит в этом формате
соотношения часового пояса: 20150515150941.077000 + 120
Это оставляет вас просто отформатировать выходные данные в соответствии с вашими пожеланиями.

Kees
источник
4

Этот файл bat (сохранить как datetimestr.bat) создает строку datetime 3 раза: (1) длинную строку datetime с днем ​​недели и секундами, (2) короткую строку datetime без них и (3) короткую версию кода.

@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

Чтобы отдать должное, я объединил концепции Питера Мортенсена (18 июня 14 года в 21:02) и Опелло (25 августа 2011 года в 14:27).

Вы можете написать это намного короче, но эта длинная версия облегчает чтение и понимание кода.

cadvena
источник
4

Я действительно новичок в пакетных файлах, и это мой код! (Я не уверен почему, но я не мог объединить дату / t и время / t вместе, и я не мог использовать % date% и % time% напрямую без переменной ...)

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

Это как бы повторно используется другими (вопрос заключался в том, чтобы получить отформатированную дату для использования в качестве имени файла).

Келли
источник
4

Есть еще один простой способ сделать это:

set HH=%time:~0,2%
if %HH% LEQ 9 (
set HH=%time:~1,1%
)
Виджей
источник
3

Для создания YYYY-MM-DD hh:mm:ss(24-часовой) метки времени я использую:

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%)
М. Дадли
источник
Предполагает ли это конкретную региональную настройку?
Питер Мортенсен
1
В соответствии с ss64.com/nt/syntax-variables.html%TIME% и %DATE%переменные используют один и тот же формат , как TIMEи DATEкоманды, соответственно. В моей системе переменные не соответствуют моим региональным настройкам.
М. Дадли
3

Этот пакетный скрипт будет делать именно то, что хочет OP (протестировано на Windows XP SP3).

Я также использовал этот хитрый трюк в реестре, описанный ранее «jph», который, IMHO, является самым простым способом получения 100% согласованного форматирования даты в "yyyy_MM_dd"любой системе Windows, новой или старой. Изменение одного значения реестра для этого является мгновенным временным и тривиальным; он длится всего несколько миллисекунд, прежде чем он немедленно возвращается обратно.

Дважды щелкните по этому пакетному файлу для мгновенной демонстрации, появится окно командной строки и отобразится ваша метка времени. , , , ,

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: 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
источник
Работает на Windows 2019 тоже. Я буду держать ваше решение рядом, мне это нравится :)
user225479
Вопрос, я только что обнаружил, что после полуночи конечный «0» сбрасывается на выходе. Есть идеи, почему? Мой вывод с вашим скриптом дает: Ваша метка времени: 2019_09_16__0_58_07 вместо ..00_58_07. Но после 1 часа он работает как положено (и выдаст результат: ..01_01_56).
user225479
Я добавил IF% HOUR% == 0 (SET HOUR = 00) в инструкцию ELSE. Это должно исправить это, я надеюсь :)
user225479
Спасибо за отзыв @ user225479. Я исправил код. Все возможные перестановки переменной HOUR, преобразованной в формат 24 HOUR, теперь будут работать правильно. Я также изменил макет, чтобы его было легче читать.
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%
Будет Ву
источник
2

Создайте файл с именем «search_files.bat» и поместите содержимое ниже в файл. Затем дважды щелкните по нему. Временная переменная% THH% была введена для надлежащей обработки AM. Если в первых 2 цифрах времени присутствует 0, Windows игнорирует оставшуюся часть имени файла 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
МакГайвер
источник
2

Мне нравится короткая версия поверх @Lorax, но для других языковых настроек она может немного отличаться.

Например, в настройках немецкого языка (с натуральным форматом даты: dd.mm.yyyy) запрос месяца должен быть изменен с 4,2 до 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
источник
1

Это мои 2 цента за datetime string. На MM DD YYYYсистемах переключаются первая и вторая %DATE:~записи.

    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%
случай
источник
1

Я попробовал принятый ответ, и он работает довольно хорошо. К сожалению, американский формат времени выглядит как H: MM: SS.CS, а отсутствующий 0 на передней панели вызывал проблемы с синтаксическим анализом до 10 часов утра. Чтобы преодолеть это препятствие, а также разрешить разбор большинства форматов мирового времени, я придумал эту простую процедуру, которая, кажется, работает достаточно хорошо.

: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

Приятно, что в этой подпрограмме вы передаете строку времени в качестве первого параметра, а имя переменной среды, в которой вы хотите указать время (в сантисекундах), в качестве второго параметра. Например:

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

(*Крис*)

TheChrisPratt
источник
1

Может быть, что-то вроде этого:

@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 Касимов
источник
1

В подобных ситуациях используется простой стандартный подход к программированию: вместо огромных усилий по анализу неизвестного объекта просто сохраните текущую конфигурацию, сбросьте ее до известного состояния, извлеките информацию и затем восстановите исходное состояние. Используйте только стандартные ресурсы Windows.

В частности, форматы даты и времени хранятся в разделе реестра HKCU \ Control Panel \ International \ in [значения MS] "values": "sTimeFormat" и "sShortDate". Reg - консольный редактор реестра, включенный во все версии Windows. Для изменения ключа 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

Просто, понятно и должно работать для всех регионов.

По причинам, которые я не понимаю, сброс значения «sShortDate» вступает в силу немедленно в окне консоли, но сброс очень похожего значения «sTimeFormat» НЕ вступает в силу, пока не откроется новое окно консоли. Однако единственное, что можно изменить, - это разделитель - позиции цифр являются фиксированными. Аналогично, маркер времени «HH» должен предшествовать начальным нулям, но это не так. К счастью, обходные пути просты.

ArtK
источник
-1 «Вместо добавления начального нуля, почему бы вам не нарушить конфигурацию машины, не изменить ее на свою случайную потребность, а затем выполнить свою задачу?» Этот подход не из этого мира, требует значительных усилий и может привести к бесконечному числу нежелательных последствий. И я даже не хочу начинать обсуждение читабельности и стандартного ожидаемого поведения кода. престижность.
Вайтрафра
Сброс sTimeFormatформата времени бесполезен . Нет. Поскольку это влияет на последующее приглашение консоли, примените его, используяfor /f "delims=" %%G in ('cmd /C echo SET "DateTime=%%date%%__%%time%%"') do %%G
JosefZ
1

В этом сценарии используется интерфейс WMI, доступ к которому осуществляется через первичный инструмент WMIC, который является неотъемлемой частью Windows начиная с Windows XP Professional (также поддерживается версия Home, но по умолчанию инструмент не устанавливается). Сценарий также реализует обход отсутствующего инструмента WMIC, создавая и вызывая vbscript WSH для доступа к интерфейсу WMI и записи в консоль времени, выводимого в том же формате, что и инструмент 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
Петр Матлас
источник
1

Хорошим трюком в одну строку, чтобы избежать раннего расширения переменной, является использование cmd /c echo ^%time^%

cmd /c echo ^%time^% & dir /s somelongcommand & cmd /c echo ^%time^%
tresf
источник
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
:: =============================================================
Христо
источник
0

Для очень простого решения для числовой даты для использования в именах файлов используйте следующий код:

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
Томас Бумер
источник
0

Разделите результаты команды date по косой черте, после чего вы можете переместить каждый из токенов в соответствующие переменные.

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
источник