<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
	<title type="html"><![CDATA[Серый форум &mdash; CMD/BAT: работа с датой и временем в командной строке]]></title>
	<link rel="self" href="http://forum.script-coding.com/extern.php?action=feed&amp;tid=4106&amp;type=atom" />
	<updated>2010-01-21T18:48:50Z</updated>
	<generator>PunBB</generator>
	<id>http://forum.script-coding.com/viewtopic.php?id=4106</id>
		<entry>
			<title type="html"><![CDATA[CMD/BAT: работа с датой и временем в командной строке]]></title>
			<link rel="alternate" href="http://forum.script-coding.com/viewtopic.php?pid=32497#p32497" />
			<content type="html"><![CDATA[<p>Эта тема родилась почти два года назад. Нам потребовалось самыми простыми средствами <strong>ТОЛЬКО</strong> командной строки получит временной слепок в формате ГГГГММДД_ччммсс (Год, Месяц, День, часы, минуты, секунды). В дальнейшем этот слепок предполагалось использовать в именах файлов для предотвращения путаницы в создаваемых однотипных файлах. Решение было найдено и использовалось некоторое время (решение опубликовано в виде статьи <a href="http://debugger.ru/articles/windatetime">Подстановка текущих даты/времени в имя файла стандартными средствами командной строки Windows</a>). <br />Впоследствии обнаружилась незавершенность алгоритма - ночное и утреннее время (промежуток между 00:00 и 10:00) в зависимости от региональных настроек может содержать ведущий пробел вместо нуля (&quot; 9:59&quot; вместо &quot;09:59&quot;). Для исправления этой ошибки была добавлена одна строка, и алгоритм заработал вновь. <br />Примерно через год возникла необходимость вернуться к этому алгоритму, и был найден более простой вариант решения проблемы - подстановки даты и времени в имя файла. Появилась заметка <a href="http://debugger.ru/blog/windatetime">Дата и время в имени файла (подстановка стандартными средствами командной строки Windows)</a>. В заметке описывается суть нового алгоритма, использующего особенности метода раскрытия переменных и свойства конструкции <strong>for /f</strong>. Рассмотрим каждый из них в отдельности. В конце будет показан еще один пример использования этой методики. </p><p><strong>Недостатки</strong><br />Вначале хотелось бы сказать о существующих недостатках. Есть одна особенность, о которой следует помнить. Этот скрипт хорошо работает даже с таким форматом даты как М/Д/ГГГГ, например для даты 14 февраля 2010. Однако это никогда не проверялось, например, для дат неделей раньше. Об этом сказано в записи от 14 февраля 2009 на странице <a href="http://www.robvanderwoude.com/newsarchives2009q1.php">архива Роба ван дер Вуда</a>. Однако в большинстве случаев это работает. </p><p><strong>Раскрытие переменных</strong><br />Конструкции вида <strong>%VAR:str1=str2%</strong> указывают интерпретатору раскрыть значение переменной <strong>VAR</strong> и произвести замену всех подстрок <strong>str1</strong> на <strong>str2</strong> во всей строке. Это хорошая особенность, которой мы можем воспользоваться - переменная <strong>%TIME%</strong> может содержать ненужный нам ведущий пробел и нам необходимо заменить его нулем </p><div class="codebox"><pre><code>%TIME: =0%</code></pre></div><p>В данном случае <strong>str1</strong> - это пробел, <strong>str2</strong> - символ &quot;ноль&quot;. Поэтому между двоеточием и знаком равенства один пробел. На всякий случай аналогичное проделываем и с переменной <strong>DATE</strong>. <br /></p><div class="codebox"><pre><code>set now=%DATE: =0% %TIME: =0%</code></pre></div><p><strong>Конструкция for /f</strong><br />В зависимости от региональных настроек порядок элементов даты может варьироваться. Например, у нас принят формат ДД.ММ.ГГГГ, в некоторых англоговорящих странах ММ.ДД.ГГГГ. Для решения нашей проблемы надо выбрать каждую часть времени и отсортировать в нужном нам порядке - разбить строку на части по разделителям (точка &quot;.&quot;, пробел &quot; &quot;, слеш &quot;/&quot;, запятая &quot;,&quot;, тире &quot;-&quot;, двоеточие &quot;:&quot;), полученные части записать в переменные цикла и сохранить в нужном нам порядке<br /></p><div class="codebox"><pre><code>for /f &quot;tokens=1-7 delims=/-:., &quot; %%a in ( &quot;%now%&quot; ) do (
    set now=%%c%%b%%a_%%d%%e
)</code></pre></div><p>Рассмотрим, как же эта конструкция поможет нам. <strong>for /f</strong> рассматривает входной поток (текстовая строка. файл на диске или вывод команды). В данном случае это строка, например дата и время создания этой темы <strong>21.01.2010 21:48:50,23</strong> (согласно настроек на моей системе). Эта строка анализируется и разбивается разделителями на отдельные фрагменты (токены). <br />Обратите внимание на пробел в списке разделителей - <strong>&quot;/-:., &quot;</strong>. Так как входная строка содержит только целочисленную информацию, разделенную разделителями, то в строке всего 7 токенов. <br />Для того чтобы все токены были переданы внутрь цикла указываем количество и список токенов - <strong>&quot;tokens=1-7&quot;</strong>, то есть все семь - с первого по седьмой. Чтобы все семь токенов попали в цикл на обработку будут выделено семь переменных цикла. В заголовке цикла указано имя первой переменной %%a. Следующие переменные получат последовательно имена %%b, %%c, %%d, %%e, %%f, %%g. В первую переменную %%a попадет первый токен, во вторую, %%b - второй токен, и т.д. <br />И так. В этом примере порядок следующий (работает на моем компьютере, у вас может быть другой) <br />-- %%a - день<br />-- %%b - месяц<br />-- %%c - год<br />-- %%d - часы<br />-- %%e - минуты<br />-- %%f - секунды<br />-- %%g - сотые<br />Так как время <em>21.01.2010 21:48:50,23</em> из формата <strong>ДД.ММ.ГГГГ чч:мм:сс,сд</strong> надо перевести в формат <strong>ГГГГММДД_ччмм</strong>, надо взять значения переменных из списка выше в следующем порядке<br />-- %%c - год<br />-- %%b - месяц<br />-- %%a - день<br />-- %%d - часы<br />-- %%e - минуты<br /></p><div class="codebox"><pre><code>set now=%%c%%b%%a_%%d%%e</code></pre></div><p>В результате получим строку вида <em>20100121_2148</em>. </p><p>Этот скрипт не универсальный, он системно-зависимый: порядок отдельных частей даты и времени зависит от текущих установок на компьютере (национальные, пользовательские настройки). </p><p><strong>Aнализ текущего времени</strong><br />На форуме был задан вопрос как <a href="http://forum.script-coding.com/viewtopic.php?pid=32446#p32446">проанализировать текущее время</a>: <br /></p><div class="quotebox"><cite>SANIOK_AV пишет:</cite><blockquote><p>...нужно в процессе выполнения скрипта проанализировать текущее время, если текущее время меньше 15:00 , то пропускаем (по goto) определённую строку (блок)...</p></blockquote></div><p>Используем раскрытие переменных с заменой подстроки - берем значение переменной TIME, производим замену пробела нулем и полученную строку сравниваем с заданной строкой времени. Так как сравнение производится <a href="http://ru.wikipedia.org/wiki/%D0%9B%D0%B5%D0%BA%D1%81%D0%B8%D0%BA%D0%BE%D0%B3%D1%80%D0%B0%D1%84%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D0%B9_%D0%BF%D0%BE%D1%80%D1%8F%D0%B4%D0%BE%D0%BA">лексикографически (википедия)</a>, то алгоритм выполнится корректно<br /></p><div class="codebox"><pre><code>if &quot;%TIME: =0%&quot; lss &quot;15:00:00,00&quot; goto end</code></pre></div>]]></content>
			<author>
				<name><![CDATA[Rumata]]></name>
				<uri>http://forum.script-coding.com/profile.php?id=24846</uri>
			</author>
			<updated>2010-01-21T18:48:50Z</updated>
			<id>http://forum.script-coding.com/viewtopic.php?pid=32497#p32497</id>
		</entry>
</feed>
