메뉴 건너뛰기

Dev tips

ASP.NET 날짜 문자열 편집방법

taknim 2005.09.29 02:24 조회 수 : 7705 추천:1819

Taeyo's ASP.NET

   강좌 최초 작성일 : 2003년 02월 20일
   강좌 최종 수정일 : 2003년 02월 21일

   강좌 읽음 수 : 20844 회

   작성자 : Taeyo(김 태영)
   편집자 : Taeyo(김 태영)

   강좌 제목 : 아는 것이 빠워 : [.NET] 날짜 문자열을 내맘대로 만들기

강좌 전 태오의 잡담>

슬그머니... 이야기하는 건데요... 태오 사이트는 뭔가 새로와질 준비를 하고 있답니다 ^^;


Hi~ 방가방가~~~   태옵니다 .

이번에는요...  ASP.NET에서 현재의 날짜와 관계된 정보를 우리가 원하는 형태로 얻어오는 방법에 대해서 알아볼까 합니다.

많은 분들이 알고 계시다시피, 날짜 정보를 얻어오기 위해서는 .NET에서 제공하는 DateTime 구조체를 이용하면 됩니다. DateTime 구조체는 일반적으로 날짜와 시간으로 표시된 시간 값을 갖는데요. 이는 서기 1년 1월 1일 자정부터 9999년 12월 31일 오후 11시 59분 59초까지의 날짜와 시간으로 나타냅니다.

DateTime 구조체에 대한 구체적인 설명은 여러분의 PC에 [VS.NET 도움말]이 설치되어져 있을 경우 다음 링크에서 확인해 보실 수 있습니다

ms-help://MS.VSCC/MS.MSDNVS.1042/cpref/html/frlrfsystemdatetimeclasstopic.htm

자~~ 다음은 DateTime 구조체가 제공하는 속성들의 목록 일부입니다.

속성 설명
Date 날짜 정보를 가져옵니다.
Day 월의 일 수를 가져옵니다.
DayOfWeek 주(週)의 일 수를 가져옵니다.
DayOfYear 일 수를 정수로 가져옵니다.
Hour 날짜의 시간 정보를 가져옵니다.
Millisecond 날짜의 밀리초 정보를 가져옵니다.
Minute 날짜의 분 정보를 가져옵니다.
Month 날짜의 월 정보를 가져옵니다.
Now 컴퓨터의 현재 날짜와 시간 DateTime을 가져옵니다.
이는 정적(static) 속성입니다
Second 날짜의 초 정보를 가져옵니다.
Ticks 날짜와 시간을 나타내는 틱 수를 가져옵니다.
참고로, 틱은 천만분의 1 초 단위를 의미합니다
Today 현재 날짜를 가져옵니다.
Year 날짜의 연도 정보를 가져옵니다.

다음은 DateTime 구조체가 제공하는 메서드들의 목록 일부입니다.

메서드 설명
AddDays 지정된 날 수를 현재 DateTime 값에 더합니다.
AddHours 지정된 시간 값을 현재 DateTime 값에 더합니다.
AddMilliseconds 지정된 밀리초 수를 현재 DateTime 값에 더합니다
AddMinutes 지정된 분 수를 현재 DateTime 값에 더합니다.
AddMonths 지정된 월 수를 현재 DateTime 값에 더합니다.
AddSeconds 지정된 초 수를 현재 DateTime 값에 더합니다
AddTicks 지정된 틱 수를 현재 DateTime 값에 더합니다.
AddYears 지정된 연도 수를 현재 DateTime 값에 더합니다.
IsLeapYear 지정된 연도가 윤년인지 여부를 나타냅니다.
이는 정적(static) 메서드입니다
ToLongDateString 현재 DateTime 값을 긴 날짜 문자열 표현으로 변환합니다.
ToLongTimeString 현재 DateTime 값을 긴 시간 문자열 표현으로 변환합니다.
ToShortDateString 현재 DateTime 값을 짧은 날짜 문자열 표현으로 변환합니다.
ToShortTimeString 현재 DateTime 값을 짧은 시간 문자열 표현으로 변환합니다
ToString 재정의(Overload)되었습니다.
현재 DateTime 값을 문자열 표현으로 변환합니다.

완전한 기능 목록이 궁금하시다면, 다음 링크를 참고해 보세요 ^^

단, 이 설명은 여러분의 PC에 [VS.NET 도움말]이 설치되어져 있을 경우에만 확인해 보실 수 있습니다

ms-help://MS.VSCC/MS.MSDNVS.1042/cpref/html/frlrfsystemdatetimememberstopic.htm

"이건 MSDN에 다 나와있는 내용이잖아~~  오늘 네가 하고싶은 이야기는 뭔데??"

라고 말씀하신다면...  -_-+ 솔직히 Set PizimMode = true 로 돌입하기는 합니다만, 그래도 꿋꿋이 설명을 드리면 이번 시간에 하고픈 이야기는 ToString() 메서드를 적절히 사용하여 원하는 날짜 문자열 얻어내는 방법에 대한 이야기입니다.

일단, 기초부터 살펴보고 가겠습니다. DateTime 구조체를 사용하여 현재의 시간을 얻어오고 싶다면 어떻게 하면 될까요? 그렇습니다. 아주 간단하게도 다음과 같이 코드를 작성하기만 하면 됩니다.

DateTime.Now

DateTime 구조체의 Now라는 정적 속성이 현재의 날짜정보를 알려주니까요.  ^^;  현재의 날짜 시간정보를 알아내기 위해서 굳이 DateTiem의 인스턴스를 만들 필요는 없답니다.

그렇다면, 특정 날짜와 시간을 지정하여 그 날짜에 해당하는 값을 얻어오고 싶다면 어떻게 해야 할까요? 다음과 같이 그 값을 생성자의 인자로써 지정해 주면 됩니다. 인자는 순서대로 년, 월, 일, 시, 분, 초가 되니까요 ^^

DateTime dateTime = new DateTime(1973, 11, 22, 9, 10, 23);

위의 코드는 1973-11-22 9:10:23 의 날짜 정보를 갖는 DateTime 구조체를 만든 것이 됩니다. 아주 간단하죠? 코드로써 확인하고 들어가겠습니다

여러분의 프로젝트에(ASP.NET 응용 프로그램) 웹 폼 페이지를 하나 새로이 추가하시구요(저는 DateTimeEx01.aspx라는 이름을 지정해 보았습니다). 웹 폼위에 Label 컨트롤을 하나 올려주세요. 그러면, 그 Label 컨트롤의 아이디는 기본적으로 Label1 이라고 지정될 겁니다. 그 기본값 그대로 두시구요..  ^^

코드 비하인드 페이지로 이동해서 Page_Load 이벤트 처리기에 다음과 같은 코드를 작성해 보도록 하세요

private void Page_Load(object sender, System.EventArgs e)
{
    DateTime dateTime = new DateTime( 1972,        // Year
                                                               11,        // Month
                                                               18,        // Day
                                                               03,        // Hour
                                                               20,        // Minute
                                                               12);       // Second

    Label1.Text = "
현재 날짜정보 : " + DateTime.Now.ToString();
    Label1.Text += "
지정 날짜정보 : " + dateTime.ToString();
}

그리고, 페이지를 컴파일하고 실행해 보세요. [솔루션 탐색기]에서 현재의 웹 폼 파일을 선택하고, 마우스 우측 클릭!! [빌드 및 찾아보기]를 클릭하시면 됩니다.

보시다시피, 현재의 날짜와 우리가 조작한 날짜의 정보가 멋지게 출력되는 것을 확인할 수 있습니다.

하지만, 제가 하려는 이야기의 본문은 이게 아닙니다. 이야기하려는 부분은 이렇게 구성된 날짜 정보를 우리가 원하는 형태로 어떻게 조합할 수 있느냐는 것입니다.

예를 들어, 우리는 가끔 어떤 목적에 의해 현재의 년,월,일,시,분,초 값을 주욱 하나의 문자열로 나열한 값을 얻어내고 싶을 수도 있습니다. 즉, 현재를 2003-02-20 오전 11:19:34 이라고 가정한다면,

20030220111934

와 같은 값을 얻어내고 싶을 수 있다는 것이죠.

혹은, 년,월,일,시,분,초 값을 .(쩜)을 구분자으로 하여 나열하는 다음과 같은 값을 얻어오고 싶을 경우도 있습니다.

2003.02.20.11.19.34

그렇습니다. 이번 팁은 바로 이러한 문자열을 쉽게 얻어오는 방법에 대한 것입니다. 날짜정보를 이렇게 원하는 포맷으로 얻어오는 방법에는 크게 두 가지 방법이 있습니다

하나는 엄청난 코드량의 압박(!)을 느끼면서 무지하게 많은 코드를 작성하는 방법으로 DateTime.Now로부터 각각의 년,월,일,시,분,초 값을 개별적으로 얻어와 문자열 결합을 하는 방법이구요.(개인적으로는 비추천하는 방법입니다)

또 다른 하나는 DateTime 구조체의 ToString() 메서드를 아주 효과적으로 사용하는 방법입니다.

그렇다면, 하나씩 알아보도록 하죠. ASP에 익숙하거나 VB를 조금 할 줄 아는 사람들이라면 아마도 가장 먼저 첫번째 방법을 생각해 냈을 것이라 생각합니다. 예를 들면, 코드를 다음과 같이 작성하는 것이죠

private void Page_Load(object sender, System.EventArgs e)
{
     // 첫번째 방법 - 엄청난 코드량의 압박이 느껴진다.
     string strYear = DateTime.Now.Year.ToString() ;
     string strMonth = DateTime.Now.Month.ToString() ;
     string strDay = DateTime.Now.Day.ToString() ;
     string strHour = DateTime.Now.Hour.ToString() ;
     string strMinute = DateTime.Now.Minute.ToString() ;
     string strSecond = DateTime.Now.Second.ToString() ;

     if(strMonth.Length == 1 ) strMonth = "0" + strMonth;
     if(strDay.Length == 1 ) strDay = "0" + strDay;
     if(strHour.Length == 1 ) strHour = "0" + strHour;
     if(strMinute.Length == 1 ) strMinute = "0" + strMinute;
     if(strSecond.Length == 1 ) strSecond = "0" + strSecond;

     Label1.Text = strYear + "." + strMonth + "." + strDay + "." +
                          strHour + "." + strMinute + "." + strSecond;
}

코드를 작성하셨다면, 컴파일하고 실행하여 결과를 확인해 보도록 하세요. 물론, 결과는 만족스럽게 나오고 있을 겁니다

하지만, 코드는 그다지 만족스럽지 못합니다. 너무 복잡해 보이기 때문이지요. 코드는 현재 년, 월, 일, 시, 분, 초 값을 각각 별도로 구해서 별도의 string 변수에 그 얻어진 값을 넣고, 만일 그 값이 혹 1~9 까지의 한자리 숫자일 경우는 두자리로 맞춰주기 위해서 "0" 이라는 문자열을 기존의 값 앞에 더하는 로직도 들어 있습니다. 물론, 이 코드가 나쁘다는 것은 아니지만 조잡함과 가독성의 저하가 존재한다는 것을 부정하지는 못할 것입니다.

"난 이게 가독성이 더 좋고, 유지 보수하기 더 좋다고 생각해~~!!!" 라고 우기신다면, 어쩌겠습니까? 자신이 좋아하는 코드를 사용해야 하겠죠. 하지만, 프로젝트는 혼자서 진행하는 것이 아니기에, 자기에게 편리한 코드보다는 범용적으로 보편화된 코드를 사용하는 것이 좋을 것입니다.

그렇다면, 과연 두번째 방법은 무엇일지 궁금하지 않습니까? 공개합니다. 이것이 바로 심플함의 예술성이 느껴지는 ToString() 메서드의 오버로드 버전을 이용하는 방법입니다

private void Page_Load(object sender, System.EventArgs e)
{
     // 두번째 방법 - 심플함의 파워를 느낄 수 있다.
     string strDate = DateTime.Now.ToString("yyyy.MM.dd.HH.mm.ss");
     Label1.Text = strDate;
}

DateTime 구조체의 ToString() 메서드는 포맷 문자열을 지정할 수 있는 오버로드된 버전을 제공하기에 이러한 구성이 가능합니다. ToString() 메서드의 첫 번째 인자로 쓰인 문자열이 바로 포맷 문자열인데, 위 코드의 경우는 우리가 그 포맷 문자열을 사용자 정의한 것입니다 문자열에서 yyyy는 4자리의 년도를 의미하고, MM은 두자리의 월을, dd는 두자리의 날짜값을 의미합니다. 또한, HH는 24시간 기준의 현재 시간 값이구요. mm과 ss는 각각 두자리의 현재 분, 초 값을 의미하는 것이 됩니다.(이 각각의 키워드들에 대해서는 곧 알아보게 됩니다)

사실, 위에서 이야기한 두가지 방법의 성능적인 차이는 매우 미비한 편입니다. 사실, 의외이기는 했지만 제 노트북에서의 테스트 결과 거의 차이가 없었습니다. 다음은 그 화면을 캡춰한 것인데요

첫번째 스타일인 일명 '코드량 압박 코드'의 처리 시간은 0.000062 , 그리고 두번째 스타일인 '심플 코드'의 경우는 0.000053 임을 볼 수 있습니다. 현재 캡춰한 화면은 이러하지만, 여러번 테스트를 반복해보니 그 시간의 차이는 거의 없는 편이더라구요... -_-+ 제 노트북에서의 테스트 기준으로 평균 차이가 0.00001 내인 편이었거든요...

고로, 두 방법의 성능상의 차이는 크게 없다고 생각해도 되겠지만, 여전히 첫번째 방법은 코드의 량도 많고, 유지보수가 힘들고, 가독성이 떨어진다는 단점이 존재합니다. 해서, 저는 여러분에게 두번째 방법을 소개하고 있구요. 그것을 추천하는 것이죠.

그렇다면, 그 두 번째 방법, 즉, 출력 포맷을 우리가 지정해서 사용할 수 있는 방법에 대해서 조금 더 알아보도록 해요. 일단, 그 포맷 문자열에 사용할 수 있는 키워드(공식 명칭은 '서식 패턴')에는 어떠한 것들이 있는지 한번 표로써 살펴보시죠~

서식 문자 출력 값
d 일(日)자. 숫자 하나인 일자에는 앞에 0이 붙지 않습니다.

예 : 1, 2, 3, 4, 10, 12, 33 (엇? 갑자기 로또가 떠오른다!!)
dd 두개의 문자로 구성되는 일(日)자.

예 : 01, 02, 07, 12, 44, 45
ddd 약식 요일 이름

예(국가/언어 설정이 '영어'인 경우) : "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
예(국가/언어 설정이 '한국어'인 경우) : "일", "월", "화", "수", "목", "금", "토"
dddd 자세한 요일 이름

예(국가/언어 설정이 '영어'인 경우) :
"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"
예(국가/언어 설정이 '한국어'인 경우) :
"일요일", "월요일", "화요일", "수요일", "목요일", "금요일", "토요일"
M 월(月) 숫자. 숫자 하나인 경우 앞에 0이 붙지 않습니다.

예 : 1, 2, 3, 4, 10, 12
MM 두개의 문자로 구성되는 월(月) 숫자.

예 : 01, 02, 07, 12
MMM 약식 월 이름

예(국가/언어 설정이 '영어'인 경우) :
"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
예(국가/언어 설정이 '한국어'인 경우) :
"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"
MMMM 자세한 월 이름

예(국가/언어 설정이 '영어'인 경우) :
"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"
예(국가/언어 설정이 '한국어'인 경우) :
"1월", "2월", "3월", "4월", "5월", "6월", "7월", "8월", "9월", "10월", "11월", "12월"
y 세기 표시 제외 연도로 연도의 마지막 한자리 숫자를 의미한다.
세기 부분을 제외한 연도가 10보다 작은 경우 연도 앞에 0이 붙지 않는다.

예 : 1, 2, 5, 9
yy 세기 표시 제외 연도로 연도의 뒤쪽 두자리 숫자를 의미한다
세기 부분을 제외한 연도가 10보다 작은 경우 연도 앞에 0이 붙는다

예 : 01, 02, 05, 09
yyyy 세기를 포함한 네 자리 숫자 연도

예 : 2003
h 12시간제 시간. 숫자 하나인 시간에는 앞에 0이 붙지 않습니다.

예 : 1, 2, 05, 09
hh 12시간제 시간. 숫자 하나인 시간에는 앞에 0이 붙습니다.

예 : 01, 02, 05, 09
H 24시간제 시간. 숫자 하나인 시간에는 앞에 0이 붙지 않습니다.

예 : 1, 2, 16, 23
HH 24시간제 시간. 숫자 하나인 시간에는 앞에 0이 붙습니다.

예 : 01, 02, 16, 23
m 분. 숫자 하나인 분에는 앞에 0이 붙지 않습니다.

예 : 1, 7, 34, 59
mm 분. 숫자 하나인 분에는 앞에 0이 붙습니다.

예 : 01, 07, 34, 59
s 초. 숫자 하나인 초에는 앞에 0이 붙지 않습니다.

예 : 1, 7, 34, 59
ss 초. 숫자 하나인 초에는 앞에 0이 붙습니다.

예 : 01, 07, 34, 59

위의 경우는 우리가 출력될 날짜 포맷을 직접 정의해 보았지만, 사실 DateTime 값의 형식은 위와 같은 사용자 지정 패턴 말고도, DateTimeFormatInfo 속성에 저장된 표준을 지정하여 사용할 수도 있습니다. 다시 말해서, 자주 사용되는 서식 패턴이 이미 어느 정도 정의 되어져 있기에, 그 패턴을 사용해도 된다는 이야기이지요. 이미 저장되어져 있는 표준 패턴에는 다음과 같은 것들이 있습니다.여기서는 일부만 보여드립니다. 완전한 목록은 다음 MSDN 링크를 참고해 보시기 바랍니다. ^^

ms-help://MS.VSCC/MS.MSDNVS.1042/cpref/html/frlrfsystemglobalizationdatetimeformatinfoclasstopic.htm

서식 문자 관련 서식 패턴의 예(en-US) 설명
d MM/dd/yyyy  
D dddd, dd MMMM yyyy  
f dddd, dd MMMM yyyy HH:mm 전체 날짜 및 시간
F dddd, dd MMMM yyyy HH:mm:ss 자세한 날짜와 자세한 시간
g MM/dd/yyyy HH:mm 간단한 날짜와 간단한 시간
G MM/dd/yyyy HH:mm:ss 간단한 날짜와 자세한 시간
m, M MMMM dd  
r, R ddd, dd MMM yyyy HH':'mm':'ss 'GMT'  
s yyyy'-'MM'-'dd'T'HH':'mm':'ss  
t HH:mm  
T HH:mm:ss  
u yyyy'-'MM'-'dd HH':'mm':'ss'Z'  
U dddd, dd MMMM yyyy HH:mm:ss  
y, Y yyyy MMMM  

이를 사용하기 위해서는 각 표준 패턴에 해당하는 '서식 문자'를 ToString() 메서드의 첫번째 인자로 지정해 주시면 됩니다. 예를 들어, 기존의 코드를 다음과 같이 바꾸면

private void Page_Load(object sender, System.EventArgs e)
{
     // 두번째 방법 - 심플함의 파워를 느낄 수 있다.
     string strDate = DateTime.Now.ToString("d");
     Label1.Text = strDate;
}

이는 위의 표에서 이야기한대로, MM/dd/yyyy 형태의 날짜 포맷을 나타내게 되는 것입니다. ^^; 해서 결과는 다음과 같아지죠.

엇? 나의 경우는 위와 같이 나오지 않고, 다음과 같이 나온다??? 이게 어찌된 일이지? 하시는 분들도 있을 겁니다

차이가 생기는 이유는 간단합니다. 위의 표에서 설명드린 포맷은 여러분의 웹 어플리케이션(ASP.NET 프로그램)이 'en-US' 이라는 '언어-국가/지역 코드'를 가질 경우의 포맷이기 때문이죠. 하지만, 여러분은 대부분 Korean 버전의 .NET Framework를 사용하고 있을 것이기에, 기본적인 '언어-국가/지역 코드'가 ko-KR 로 설정되어 있어서 출력 문자 포맷이 다른 것 뿐입니다.

만일, "그렇다면, 나두 '언어-국가/지역 코드'를 'en-US'인 상태로 결과를 확인하고 싶어요~" 라고 한다면... 다음과 같이 현재 웹 어플리케이션의 web.config 파일을 요소 구역을 다음과 같이 편집하시면 됩니다. 즉, '언어-국가/지역'을 설정하는 culture 의 값을 eu-US로 맞추어주기만 하면 되는 것이죠~

     requestEncoding="utf-8"
     responseEncoding="utf-8"
     culture="en-US" />

'언어-국가/지역'별 culture 의 코드 값은 다음 링크에서 확인하실 수 있습니다

ms-help://MS.VSCC/MS.MSDNVS.1042/cpref/html/frlrfSystemGlobalizationCultureInfoClassTopic.htm

하지만, 여러분 중에는 "난 en-US 기준의 출력 포맷은 관심없어, ko-KR 기준의 포맷을 알려달라구~" 하시는 분들이 있을 수도 있을 것 같습니다. 사실, 그 부분은 여러분이 직접 각각의 '서식 문자'를 지정해서 출력되는 결과를 확인함으로써 알아보시기를 추천합니다. 그 정도의 성의는 보여주셔야 할 것이라는 생각이거든요.

하지만, 또.. 뭐 야박하게 여러분에게만 그것을 떠넘기자는 그것도 좀 그러네요. 어차피 이 결과는 자주 찾아보게 될 것 같다는 생각두 있구요... 해서, 정리해 보았습니다. ^^

다음은 ko-kR culture 일 경우의 패턴 문자열이옵니다. ^^;

서식 문자 출력 값
d 2003-02-20
D 2003년 2월 20일 목요일
f 2003년 2월 20일 목요일 오후 1:29
F 2003년 2월 20일 목요일 오후 1:29:24
g 2003-02-20 오후 1:29
G 2003-02-20 오후 1:29:24
m 혹은 M 2월 20일
r 혹은 R Thu, 20 Feb 2003 13:29:24 GMT
s 2003-02-20T13:29:24
t 오후 1:29
T 오후 1:29:24
u 2003-02-20 13:29:24Z
U 2003년 2월 20일 목요일 오전 4:29:24
y 혹은 Y 2003년 2월

참고하시옵소서~