메뉴 건너뛰기

Dev tips

Windows Server 배치파일에서 날짜 계산하기

taknim 2009.09.29 03:21 조회 수 : 10526 추천:2693

http://qaos.com/article.php?sid=2262

배치파일에서 오늘 날짜를 구하는 방법은 상당히 간단하다. date라는 명령을 이용해서 구할 수도 있지만 간단히 %DATE%라는 환경 변수를 이용해서 구할 수도 있다. 물론 %DATE% 환경 변수는 모든 시스템에서 사용할 수 있는 것은 아니다. 그러나 XP 기반의 OS에서는 모두 사용할 수 있으므로 큰 문제는 없다고 본다. 명령행에서

echo %DATE%

명령을 실행해보면 알 수 있지만 %DATE%YYYY-MM-DD 형태로 날짜를 출력한다. 만약 출력되는 날짜 형식을 변경하고 싶다면 다음과 같은 간단한 배치 파일로 이 문제를 해결할 수 있다.

[today.cmd]

@echo off for /f "tokens=1-3 delims=- " %%A in ('echo %DATE%') do (set YY=%%A&SET MM=%%B&SET DD=%%C)

echo %YY%, %MM%, %DD%

만약 배치 파일에서 어제나 내일의 날짜를 구하고 싶은 경우에는 어떻게 할까? %DD%에서 하루만 빼면 될 것 같지만 사실 그리 간단하지는 않다. 생각해보면 쉽다. 오늘 날짜가 2월 2일이라면 %DD%에서 하루만 빼면된다. 그러나 2월 1일이라면 어제는 1월 31일이므로 %MM%에서도 1를 빼야한다. 만약 1월 1일이라면 어떻게 될까? 이때는 %DD%, %MM%, %YY%에서 1을 빼야한다.


더우기 이렇게 계산해도 오류가 발생한다. 그 이유는 3월 1일을 생각해보면 쉽다. 3월 1일에서 하루를 빼면 2월 28일이 되지만 4년 마다 한번씩 2월 29일이된다. 즉 윤년까지 계산해야 한다는 점이다. 따라서 배치파일에서 어제의 날짜를 계산하는 것은 조금 복잡한 과정을 거쳐야 한다. 다음 어제의 날짜를 계산하는 배치 파일이다.

[yesterday.cmd]

@echo off for /f "tokens=1-3 delims=- " %%A in ('echo %DATE%') do (set YY=%%A&SET MM=%%B&SET DD=%%C)

set /a DD=1%DD%-101 set /a MM=1%MM%-100

if %DD% GTR 0 goto end set /a MM=%MM%-1

if %MM% GTR 0 goto leap

set /a DD=31 set /a MM=12 set /a YY=%YY%-1 REM echo %YY%, %MM%, %DD% -> 2005, 12, 31 goto end

:leap set /a TT=%YY%/4 set /a TT=%TT%*4 if not %YY% equ %TT% goto mon%MM% set /a DD=29 goto end

:mon1 :mon3 :mon5 :mon7 :mon8 :mon10 set /a DD=31 goto end

:mon2 set /a DD=28 goto end

:mon4 :mon6 :mon9 :mon11 set /a DD=30 goto end

:end set /a DD=%DD% + 100 set DD=%DD:~1,2% set /a MM=%MM% + 100 set MM=%MM:~1,2%

echo %YY%, %MM%, %DD%

for /f "tokens=1-3 delims=- " %%A in ('echo %DATE%') 
    do (set YY=%%A&SET MM=%%B&SET DD=%%C)
%DATE% 환경 변수에서 년월일을 %YY%, %MM%, %DD%로 분리하는 루틴이다. echo %DATE%를 실행한 결과를 tokens과 delims를 이용해서 %%A, %%B, %%C로 저장하고 이 값을 다시 %YY%, %MM%, %DD%로 저장하는 순환문이다.

set /a DD=1%DD%-101
set /a MM=1%MM%-100
조금 이해가 가지 않는 문장일 수 있다. 사실 set 명령을 이용하면 간단한 사칙 연산이 가능해진다. 그런데 문제는 %DD%나 %MM%은 01, 02처럼 숫자앞에 0이 추가될 수 있다. 이 경우 %DD%-1과 같은 방법으로 연산을 수행하면 숫자로 처리되지 않고 문자로 처리되기 때문에 1을 빼는 것이 아니라 한 문자를 삭제하게된다. 한 예로 %DD%가 01이고 이 상태에서 %DD%-1을 수행하면 그 결과는 0이된다. 다음 내용을 test.cmd로 저장한 후 그 결과를 시험해보면 쉽게 알 수 있다.
@echo off
set DD=01
set /a DD=%DD%-1
echo %DD%

따라서 이러한 문제를 피하고 %DD%와 %MM%에서 선행되는 0을 제거하기위해 1%DD%-101과 1%MM%-100을 사용한 것이다. 여기서 /a는 계산된 결과를 의미한다. 즉 %DD%가 02이라면 윗식은 102-101=1이므로 최종적으로 %DD%에는 0이 제거된 1이라는 값이 저장된다. %DD%의 경우 101을 빼지만 %MM%에서는 100을 뺀다. 그 이유는 어제의 날짜를 계산하기위해서는 %DD%에서는 1을 빼야하지만 %MM%의 경우 단지 선행되는 0만 제거하면 되기때문이다.

if  %DD% GTR 0 goto end
set /a MM=%MM%-1
계산된 날짜가 0보다 크면 end로 분기한 후 %YY%, %MM%, %DD%를 반환한다. 이러한 경우는 보통 2월 2일처럼 1일 이외의 모든 경우에 해당된다. 만약 2월 1일이라면 어제는 1월 31일이므로 월에서 다시 1을 빼야한다. set /a MM=%MM%-1는 월에서 1을 빼는 과정이며 이전 과정과는 달리 1%MM%-101처럼 사용하지 않은 이유는 전단계에서 %MM%을 숫자로 변환했기때문이다.

if %MM% GTR 0 goto leap

set /a DD=31 set /a MM=12 set /a YY=%YY%-1 goto end

%MM%가 0보다 크면 윤년 계산으로 분기한다. 0인 경우는 1월 1일에 발생한다. 1월 1일의 어제는 전년도 12월 31일이므로 %DD%를 31, %MM%를 12, %YY%는 %YY%-1로 설정한 후 end로 분기한다.

:leap
set /a TT=%YY%/4
set /a TT=%TT%*4
if not %YY% equ %TT% goto mon%MM%
set /a DD=29
goto end
윤년을 계산하는 부분이다. 루틴이 조금 이상할 수 있지만 원리는 간단하다. %YY%/4는 현재 년도를 4로 나눈다. 즉 2006을 4로 나누면 501.5가 나오지만 .5는 잘려진다(4NT의 경우 501.5가 나오며 따라서 별도의 절단 함수를 사용해야 한다). 따라서 첫번째 %TT%에는 501이 저장된다. 이 값에 다시 4를 곱하면 2004가 나오며, 2004는 윤년에 해당된다. 마지막으로 %YY%(2006)이 윤년(2004)인지 검사해서 윤년이 아닌 경우에는 mon%MM%(mon1)로 분기하고 윤년인 경우에는 %DD%를 29로 설정한 후 end로 분기한다.

:mon1
:mon3
:mon5
:mon7
:mon8
:mon10
set /a DD=31
goto end

:mon2 set /a DD=28 goto end

:mon4 :mon6 :mon9 :mon11 set /a DD=30 goto end

윤년이 아닌 경우에 큰달과 작은달, 2월을 설정하는 부분이다. 작은달의 경우 %DD%를 30일로 설정하며, 큰달의 경우 %DD%를 31일로 설정한다. 2월의 경우 윤년이 아니면 28일까지 있으므로 %DD%를 28로 설정한다.

:end
set /a DD=%DD% + 100
set DD=%DD:~1,2%
set /a MM=%MM% + 100
set MM=%MM:~1,2%
이전 단계에서 계산을 위해 %DD%와 %MM%를 숫자로 변한했다. 이 경우 1, 2처럼 숫자앞에 선행하는 0이 없으므로 선행하는 0을 샆입하는 루틴이다. 만약 %DD%가 1이라면 %DD%에는 101이 저장된다. 아울러 두번째 set 명령의 DD=%DD:~1,2%의 의미는 %DD% 변수의 1번째 자리부터 2개의 문자열을 복사(~)하라는 뜻이다. 만약 DD=%DD:~0,2%를 사용한다면 0번째 자리부터 2개의 문자열을 복사하므로 20이 결과 값이된다.

다운로드: 배치 파일의 작성에 익숙하지 않은 사용자는 다음 링크에서 배치 파일을 다운받을 수 있다. 압축 파일에는 현재의 날짜를 출력하는 today.cmd와 어제의 날짜를 출력하는 yesterday.com가 포함되어 있다.


번호 제목 글쓴이 날짜 조회 수
42 윈도우 가상화 이미지 taknim 2016.12.20 31
41 포트쿼리 사용 (PortQry) taknim 2015.06.16 6326
40 FTP 패시브모드 포트 고정 taknim 2014.12.30 2258
39 윈도우7 인터넷 속도제한 해제 (QoS 제한 해제) taknim 2014.10.23 4083
38 findstr 사용법(linux grep 유사) taknim 2014.04.24 3357
37 코드페이지 변경 taknim 2014.02.11 3423
36 윈도7에서 mklink 명령을 이용한 심볼릭 디렉토리 생성하기 taknim 2013.11.15 4147
35 [VBS] WScript 메소드 taknim 2013.01.29 6524
34 [VBS] WshShell.CreateShortcut - 바로가기 생성 taknim 2013.01.29 6177
33 xampp taknim 2012.12.13 4878
32 IIS 로그 분석 개요 및 무료 로그 분석 툴(LogParser) taknim 2012.11.23 7856
31 윈도우 7 정품 인증 secret taknim 2009.11.03 4
» 배치파일에서 날짜 계산하기 file taknim 2009.09.29 10526
29 명령 프롬프트 창이 보이지 않는 배치 파일 실행하기 taknim 2009.07.04 12830
28 알아두면 유용한 윈도우의 환경 변수들 taknim 2009.06.25 8699
27 윈도우 리부팅.끄기.잠금 아이콘 만들기 [1] taknim 2009.01.08 9596
26 Include 파일은 부모 디렉터리를 표시하기 위해 '..'를 사용할 수 없습니다. 와 같은 오류 발생 taknim 2009.01.06 9881
25 USB 메모리의 파일 시스템 FAT32를 NTFS로 변환하는 방법 taknim 2008.12.23 10182
24 윈도우 XP 한 폴더에 저장할 수 있는 파일의 최대 갯수? taknim 2008.12.23 12202
23 윈도우XP 속도를 빠르게 하는 Tip 총정리(21개) taknim 2008.12.21 7342