Программизм
 
Программизм
На главную | Графомания | Программизм | Книги | Всячина | Скачать | Ъ?  

Арифметика дат в скриптах

Наверняка многие сталкивались с задачей обработки файлов по расписанию. Если в имени файла содержится дата создания, то задача проста. Сложность лишь в том, что как правило обрабатывать надо не сегодняшние файлы, а файлы за несколько дней назад.

Если писать программу обработки на C, Pascal или другом языке относительно высокого уровня, то проблем не возникает — для того, чтобы получить дату «несколько дней назад», достаточно вычесть «несколько» из переменной типа date_t или TDateTime. Беда лишь в том, что в известных мне встроенных скриптовых языках (за исключением REXX, но кто ж сегодня использует OS/2) такой возможности нет.

Первый раз мне пришлось решать эту задачу под Windows 2000. О красоте и элегантности NT batch script я уже писал, но, тем не менее, задача не показалась невыполнимой:

@echo off

set DAYSBACK=%1


set CURDATE=%DATE%

REM Для русской версии
set DAY=%CURDATE:~3,2%
set MONTH=%CURDATE:~6,2%
set YEAR=%CURDATE:~9,4%

REM Для английской версии
REM set DAY=%CURDATE:~4,2%
REM set MONTH=%CURDATE:~7,2%
REM set YEAR=%CURDATE:~10,4%


set /A DAY=DAY-DAYSBACK
:startloop
if !DAY! GTR 0 goto endloop
  set /A MONTH=MONTH-1
  if !MONTH! EQU 0 (
    set /A YEAR=YEAR-1
    set MONTH=12
  )
  set DAYSINMONTH=312831303130313130313031
  for /L %%i in (2,1,!MONTH!) do set DAYSINMONTH=!DAYSINMONTH:~2!
  set /A DAY=DAY+!DAYSINMONTH:~0,2!
  set /A RM=YEAR-YEAR/4*4
  if !MONTH! EQU 2 (
    if !RM! EQU 0 set /A DAY=DAY+1
  )
goto startloop
:endloop

set DAY=0!DAY!
set DAY=!DAY:~-2!
set MONTH=0!MONTH!
set MONTH=!MONTH:~-2!

echo !DAY!.!MONTH!.!YEAR!

Очевидно, что глубина «путешествия во времени» регулируется параметром DAYSBACK. Не менее очевидно, что данный скрипт должен запускаться со включенной опцией командного интерпретатора /v:

cmd /v:ON /c date.cmd

Можно намертво происать эту опцию в реестр, но что-то удерживает меня от такого шага.

Ещё одна досадная неприятность состоит в том, что русская версия Windows 2000 выдаёт день недели тремя буквами, а английская — двумя. Поэтому при редактировании скрипта нужно учесть, где этот скрипт будет запускаться. Некрасиво, но что делать — непонятно.

После того, как наш сайт переехал с net.ru на .masterhost, выяснилось, что не везде лог-файлы удаляются автоматически. Поэтому пришлось писать свой скрипт для cron’а. Вспомнив молодость и прочитав руководство по bash, я написал нижеследующее:

#!/bin/bash

DAYSBACK=$1

DAYSINMONTH=(0 31 28 31 30 31 30 31 31 30 31 30 31)

DAY=`date "+%d"`
MONTH=`date "+%m"`
YEAR=`date "+%Y"`

DAY=$(($DAY-$DAYSBACK))

while test $DAY -le 0 
do
  MONTH=$(($MONTH-1))
  if test $MONTH -le 0
  then
    MONTH=12
    YEAR=$(($YEAR-1))
  fi
  DAY=$(($DAY+${DAYSINMONTH[$MONTH]}))
  if test $MONTH -eq 2 && test $(($YEAR%4)) -eq 0
  then
    DAY=$(($DAY+1))
  fi
done

T=00$DAY
DAY=${T:${#DAY}}
T=00$MONTH
MONTH=${T:${#MONTH}}

echo $DAY.$MONTH.$YEAR!

Скрипт выглядит приличнее, но только за счёт синтаксиса bash’а.

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

Пользуйтесь, и не фыркайте презрительно, услышав словосочетание «арифметика дат»!

23.12.2004

Назад | К оглавлению | Для печати | Комментарии | Вперёд
Поиск
См. также

Командный язык Windows NT — всё ещё корявый и хитрый, но уже достаточно мощный инструмент, которым можно и нужно пользоваться... »»»

Для начала следует понять, какие вопросы нас интересуют: pазумеется, хиты и хосты, количество визитов по ссылкам, количество визитов с поисковых серверов — это, фактически, случайные посетители... »»»

Очевидно, что char поместится в int. Во многих моделях памяти размер указателя также равен размеру int. Следовательно, структуру можно заменить массивом... »»»

Рекомендую

e.g.Orius’
Игорь Иртеньев
Вячеслав Шевченко

Copyright notice

ъ) Все материалы, размещённые на странице, являются неотъемлемой собственностью автора с вытекающими отсюда правами, как ©, так и (ъ). Некоммерческое их распространение всячески приветствуется, разумеется, при условии сохранения ссылки на оригинал. Что касается коммерческого использования — пишите письма, договориться можно всегда.

Удивительное рядом

lj userhardsign
Закладки Карта Королёва

Пишите письма

Счётчики

XPEHOMETP™ Рейтинг@Mail.ru