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

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

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

Если писать программу обработки на 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

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

Именно им призван помочь описанный здесь скрипт, сохраняющий письма с бесплатных ящиков на локальный диск.... »»»

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

во-первых, процедуру копирования нужно вызвать из программы на VisualBasic, а во-вторых, у пользователя нет прав на запись в каталог... »»»

Рекомендую

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

Copyright notice

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

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

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

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

Счётчики

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