CMD/BAT: работа с датой и временем в командной строке
Чтобы отправить ответ, вы должны войти или зарегистрироваться
Сообщения 1
1 Тема от Rumata 2010-01-21 22:48:50 (изменено: Rumata, 2010-01-22 19:42:40)
- Rumata
- Разработчик
- Неактивен
- Рейтинг : [ 33 | 0 ]
Тема: CMD/BAT: работа с датой и временем в командной строке
Эта тема родилась почти два года назад. Нам потребовалось самыми простыми средствами ТОЛЬКО командной строки получит временной слепок в формате ГГГГММДД_ччммсс (Год, Месяц, День, часы, минуты, секунды). В дальнейшем этот слепок предполагалось использовать в именах файлов для предотвращения путаницы в создаваемых однотипных файлах. Решение было найдено и использовалось некоторое время (решение опубликовано в виде статьи Подстановка текущих даты/времени в имя файла стандартными средствами командной строки Windows).
Впоследствии обнаружилась незавершенность алгоритма — ночное и утреннее время (промежуток между 00:00 и 10:00) в зависимости от региональных настроек может содержать ведущий пробел вместо нуля (» 9:59″ вместо «09:59»). Для исправления этой ошибки была добавлена одна строка, и алгоритм заработал вновь.
Примерно через год возникла необходимость вернуться к этому алгоритму, и был найден более простой вариант решения проблемы — подстановки даты и времени в имя файла. Появилась заметка Дата и время в имени файла (подстановка стандартными средствами командной строки Windows). В заметке описывается суть нового алгоритма, использующего особенности метода раскрытия переменных и свойства конструкции for /f. Рассмотрим каждый из них в отдельности. В конце будет показан еще один пример использования этой методики.Недостатки
Вначале хотелось бы сказать о существующих недостатках. Есть одна особенность, о которой следует помнить. Этот скрипт хорошо работает даже с таким форматом даты как М/Д/ГГГГ, например для даты 14 февраля 2010. Однако это никогда не проверялось, например, для дат неделей раньше. Об этом сказано в записи от 14 февраля 2009 на странице архива Роба ван дер Вуда. Однако в большинстве случаев это работает.Раскрытие переменных
Конструкции вида %VAR:str1=str2% указывают интерпретатору раскрыть значение переменной VAR и произвести замену всех подстрок str1 на str2 во всей строке. Это хорошая особенность, которой мы можем воспользоваться — переменная %TIME% может содержать ненужный нам ведущий пробел и нам необходимо заменить его нулемВ данном случае str1 — это пробел, str2 — символ «ноль». Поэтому между двоеточием и знаком равенства один пробел. На всякий случай аналогичное проделываем и с переменной DATE.
Конструкция for /f
В зависимости от региональных настроек порядок элементов даты может варьироваться. Например, у нас принят формат ДД.ММ.ГГГГ, в некоторых англоговорящих странах ММ.ДД.ГГГГ. Для решения нашей проблемы надо выбрать каждую часть времени и отсортировать в нужном нам порядке — разбить строку на части по разделителям (точка «.», пробел » «, слеш «/», запятая «,», тире «-«, двоеточие «:»), полученные части записать в переменные цикла и сохранить в нужном нам порядкеРассмотрим, как же эта конструкция поможет нам. for /f рассматривает входной поток (текстовая строка. файл на диске или вывод команды). В данном случае это строка, например дата и время создания этой темы 21.01.2010 21:48:50,23 (согласно настроек на моей системе). Эта строка анализируется и разбивается разделителями на отдельные фрагменты (токены).
Обратите внимание на пробел в списке разделителей — «/-. «. Так как входная строка содержит только целочисленную информацию, разделенную разделителями, то в строке всего 7 токенов.
Для того чтобы все токены были переданы внутрь цикла указываем количество и список токенов — «tokens=1-7», то есть все семь — с первого по седьмой. Чтобы все семь токенов попали в цикл на обработку будут выделено семь переменных цикла. В заголовке цикла указано имя первой переменной %%a. Следующие переменные получат последовательно имена %%b, %%c, %%d, %%e, %%f, %%g. В первую переменную %%a попадет первый токен, во вторую, %%b — второй токен, и т.д.
И так. В этом примере порядок следующий (работает на моем компьютере, у вас может быть другой)
— %%a — день
— %%b — месяц
— %%c — год
— %%d — часы
— %%e — минуты
— %%f — секунды
— %%g — сотые
Так как время 21.01.2010 21:48:50,23 из формата ДД.ММ.ГГГГ чч:мм:сс,сд надо перевести в формат ГГГГММДД_ччмм, надо взять значения переменных из списка выше в следующем порядке
— %%c — год
— %%b — месяц
— %%a — день
— %%d — часы
— %%e — минутыВ результате получим строку вида 20100121_2148.
Этот скрипт не универсальный, он системно-зависимый: порядок отдельных частей даты и времени зависит от текущих установок на компьютере (национальные, пользовательские настройки).
Aнализ текущего времени
На форуме был задан вопрос как проанализировать текущее время:. нужно в процессе выполнения скрипта проанализировать текущее время, если текущее время меньше 15:00 , то пропускаем (по goto) определённую строку (блок).
Используем раскрытие переменных с заменой подстроки — берем значение переменной TIME, производим замену пробела нулем и полученную строку сравниваем с заданной строкой времени. Так как сравнение производится лексикографически (википедия), то алгоритм выполнится корректно
Источник
Засекаем время в bat/cmd
При всех моих стараниях уйти от Windows везде и навсегда не получается. Есть компьютер на работе, компьютеры друзей, собственный нетбук, с которым неохота возиться настолько кардинально. При этом, ряд задач в принципе выполняется из командной строки проще и удобнее, чем «оконно-мышевым» способом. Особенно если это задачи из тех, что имеют прямое отношение к Linux, например, работа с утилитами из комплекта gnuwin32.
Запуская однажды уже упомянутую упаковку/распаковку при помощи windows-реализации tar, я захотел однажды засечь время. Ну, не секундомером же это делать… Сделал командный файл, в котором вывожу время, запускаю архиватор, снова вывожу время.
Получается ерунда. Команда time \t выдает время с точностью до минуты. Ладно, можно использовать переменную среды %time% :
Чуть получше, но все равно очень плохо. Во-первых, если архиватору добавить ключ -v, и он начнет выдавать в консоль имена архивируемых объектов, то время начала стремительно унесется за пределы экрана. Во-вторых, чтобы понять, сколько процесс занял времени, все равно придется считать, а компьютер на что?
Однако переменная %time% хитроформатированная, скорее текст, чем число, и ее в лоб не получится использовать для вычитания времени начала из времени окончания. Тем более, командный интерпретатор cmd.exe работает с целочисленными значениями, а время идет с точностью до сотых секунды (ну, или до десятков миллисекунд, как хотите).
Ладно, разберем время на составляющие. При помощи конструкции set t1_m=%t1:
3,2% которая присваивает переменной t1_m два знака из t1, пропустив первые три, получим часы, минуты, секунды и сотые доли секунды:
Напоминаю, что ключик /a позволяет оператору set не только присваивать значение переменной, но и выполнять некоторые операции (подробнее — set /? ).
В результате получили в s1 время в сотнях миллисекунд, допустим, из времени начала операции. Можно сделать аналогичным образом s2 из времени окончания. Эти две переменные целочисленные и прекрасно складываются, вычитаются и все такое. Нам надо разность, и, чтобы избежать неожиданностей со знаками, можно сразу определить, что из них больше, и потом вычитать:
Ключик /i расширяет возможности оператора сравнения, позволяя ему не только выполнять сравнение строк на тождественность (чем он занимался изначально), но и сравнивать числа на больше/меньше/равно ( if /? )
Получили s3 — разность времени в десятках миллисекунд. Надо разобрать на составляющие, а потом склеить обратно в удобочитаемом виде. Все несложно, используем остаток от деления, чтобы избавиться, например, от часов при извлечении минут, и деление (целочисленное, другого тут нет), чтобы избавиться от секунд, примерно так:
Тут надо не забыть забавную тонкость: в командном интерпретаторе символ процента — подводный камень. Иногда он ставится по обе стороны от переменной, и тогда при выполнении интерпретатор отбрасывает эту пару, а имя переменной заменяет значением. Иногда он стоит перед переменной цикла. Иногда он используется в виде оператора получения остатка от целочисленного деления. Так вот, там, где процент непарный, его надо не забывать удваивать, а то его отбросят и будут безуспешно искать пару.
Получили часы, минуты, секунды и десятки миллисекунд в отдельных переменных. Можно их использовать, как числа, а можно — как строки, поэтому их легко склеить в одно значение времени и выдать его в стандартный поток ввода-вывода, «на консоль»:
Все это можно засунуть в отдельный файл, чтобы использовать в разных местах. Тогда время надо будет передавать файлу в виде параметров. Тут есть два варианта: либо
и передавать параметры в двойных кавычках (а тильда раскроет кавычки), либо
и передавать без кавычек, потому что в символьном представлении времени , по крайней мере, с русской локалью (в другой не проверял), десятки миллисекунд отделяются от секунд запятой, а запятая вместе с пробелом разделяет и параметры командной строки, так что сотые доли секунды будут уже другим параметром.
Итого, получился такой командный файл, скажем, timecalc.bat:
Теперь об использовании. Допустим, есть такой батничек, запускающий архивацию с засечкой времени:
В переменных a и b имеем время начала и окончания операции соответственно. Можно передать их нашему скрипту, непременно валяющемуся тут же рядом, в этой же папке:
И он выведет в консоль затраченное время третьей строчкой, после «start » и «stop ». Но хотелось бы добавить, допустим, «упаковано за » или «распаковано за », так что ввести соответствующие строки в файл «подпрограммы» не получится. Передавать этот строковый «довесок» в виде еще одного параметра и не особо красиво, и при желании дописать текст после времени (а не перед) опять потребует лезть в вызываемый файл. А как перехватить вывод вызываемого файла для использования в вызывающем?
Я просто обалдел, когда узнал. Внезапно, при помощи оператора цикла. О, сколько нам открытий чудных готовит for /? …
Расширение синтаксиса /F позволяет выковыривать переменную цикла из разного рода наборов: файлов, символьных строк, команд. Чтобы понять, что используется для цикла, применяются (или не применяются) кавычки. Без кавычек в скобках пишем файл или набор файлов. А применение кавычек зависит от того, установлена или нет опция usebackq: при установленной в двойных кавычках пишем строку, в простых — команду. При снятой опции строку пишем в простых кавычках, а команду — в обратных (которые обычно на клавише с буквой Ё). При этом, команда вполне может быть одна, и проход цикла тоже один, и в теле цикла получаем нужный нам вывод команды, который засунем в переменную для дальнейшего использования (хотя можно и использовать сразу):
И, кстати, не забываем, что переменная цикла должна быть односимвольной. Нигде этого не прочитал, вывел экспериментально путем ошибок и проб. Может, читал невнимательно, а может, не знал где…
Итого получаем такой командный файл, скажем, tar_time.cmd, который принимает в качестве параметра пакуемую папку, засекает время и пишет его в консоль и в лог-файл:
Аналогичным образом написал почти то же для распаковки, поправив пару строчек.
Конечно, можно кое-что оптимизировать, например, все вычисления с константами сделать на калькуляторе (или в уме), преобразование времени в сотые доли секунды вынести в «функцию» и вызывать ее через call , но так удобочитаемее, а на скорость выполнения влияет мало. Еще можно вместо своры собак ( @ ) поставить один раз в начале файла @echo off , дело вкуса. И, конечно, можно повнимательнее относиться к регистру символов и писать либо везде прописными, либо везде строчными. Но, как уж получилось…
Возможности команд Windows (тяжелое наследие DOS), конечно, довольно ограничены, но даже с их помощью можно делать интересные и полезные штучки. Вот только иногда фиг догадаешься, описание какой команды для твоей цели нужно смотреть и где именно искать…
Источник
Командная строка вывести время
Отображает или задает системное время. Если используется без параметров, то время отображает текущее системное время и предлагает ввести новое время.
Чтобы изменить текущее время, необходимо быть администратором.
Синтаксис
Параметры
Параметр Описание [: [: [. ]]] [am | pm] Устанавливает системное время на новое указанное время, где чч — в часах (обязательно), mm — в минутах, а SS — в секундах. Nn может использоваться для указания сотых долей секунды. Необходимо разделять значения чч, mm и SS с помощью двоеточий (:). SS и nn должны быть разделены точкой (.). Если параметр AM или PM не указан, по умолчанию используется 24 -часовой формат .
/t Отображает текущее время без запроса на новое время. /? Отображение справки в командной строке. Remarks
Допустимые значения чч : от 0 до 24.
Допустимые значения mm и SS : от 0 до 59.
Примеры
Если расширения команд включены, для вывода текущего системного времени введите:
Чтобы изменить текущее системное время на 5:30 PM, введите один из следующих элементов:
Чтобы отобразить текущее системное время, а затем ввести новое время, введите следующую команду:
Для сохранения текущего времени и возврата в командную строку нажмите клавишу ВВОД. Чтобы изменить текущее время, введите новое время и нажмите клавишу ВВОД.
Источник