천객만래 [千客萬來] (It has an interminable succession of visitors)

일단, 기초부터 살펴보고 가겠습니다. 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 = "<br>현재 날짜정보 : " + DateTime.Now.ToString();
    Label1.Text += "<br>지정 날짜정보 : " + 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 속성에 저장된 표준을 지정하여 사용할 수도 있습니다. 다시 말해서, 자주 사용되는 서식 패턴이 이미 어느 정도 정의 되어져 있기에, 그 패턴을 사용해도 된다는 이야기이지요. 이미 저장되어져 있는 표준 패턴에는 다음과 같은 것들이 있습니다.여기서는 일부만 보여드립니다.

 

서식 문자 관련 서식 패턴의 예(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 파일을 <globalization > 요소 구역을 다음과 같이 편집하시면 됩니다. 즉, '언어-국가/지역'을 설정하는 culture 의 값을 eu-US로 맞추어주기만 하면 되는 것이죠~

 

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

 

하지만, 여러분 중에는 "난 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월

 

자료출처 : http://taeyo.pe.kr/

쌈꼬쪼려 소백촌닭

Posted by SB패밀리

CAST 및 CONVERT

식을 다른 데이터 형식으로 명시적으로 변환합니다. CAST 및 CONVERT는 비슷한 기능을 제공합니다.

구문

CAST 사용

CAST ( expression AS data_type )

CONVERT 사용

CONVERT ( data_type [ ( length ) ] , expression [ , style ] )

인수

expression

유효한 Microsoft® SQL Server™ 식입니다. 자세한 내용은 을 참조하십시오.

data_type

bigint, sql_variant 등 대상 시스템 제공 데이터 형식입니다. 사용자 정의 데이터 형식은 사용할 수 없습니다. 자세한 내용은 데이터 형식을 참조하십시오.

length

nchar, nvarchar, char, varchar, binary, varbinary 데이터 형식의 선택적 매개 변수입니다.

style

datetime, smalldatetime 데이터를 문자 데이터(nchar, nvarchar, char, varchar, nchar, nvarchar 데이터 형식)로 변환할 때 사용되는 날짜 형식이나 float, real, money, smallmoney 데이터를 문자 데이터(nchar, nvarchar, char, varchar, nchar, nvarchar 데이터 형식)로 변환할 때 사용되는 문자열 형식의 스타일입니다.

SQL Server는 쿠웨이트 알고리즘을 사용하여 아랍어 날짜 형식을 지원합니다.

다음 표에서 왼쪽 두 열은 datetime 또는 smalldatetime을 문자 데이터로 변환하기 위한 style 값을 나타냅니다. 세기가 포함된 네 자리 연도(yyyy)를 구하려면 style 값에 100을 더합니다.

세기 포함 안함
(yy)
세기 포함
(yyyy)

표준

입력/출력**
- 0 또는 100 (*) 기본값 mon dd yyyy hh:miAM(또는 PM)
1 101 USA mm/dd/yy
2 102 ANSI yy.mm.dd
3 103 영국/프랑스 dd/mm/yy
4 104 독일 dd.mm.yy
5 105 이탈리아 dd-mm-yy
6 106 - dd mon yy
7 107 - Mon dd, yy
8 108 - hh:mm:ss
- 9 또는 109 (*) 기본값 + 밀리초 mon dd yyyy hh:mi:ss:mmmAM(또는 PM)
10 110 USA mm-dd-yy
11 111 일본 yy/mm/dd
12 112 ISO yymmdd
- 13 또는 113 (*) 유럽 기본값 + 밀리초 dd mon yyyy hh:mm:ss:mmm(24h)
14 114 - hh:mi:ss:mmm(24h)
- 20 또는 120 (*) ODBC 표준 yyyy-mm-dd hh:mi:ss(24h)
- 21 또는 121 (*) ODBC 표준(밀리초) yyyy-mm-dd hh:mi:ss.mmm(24h)
- 126(***) ISO8601 yyyy-mm-dd Thh:mm:ss:mmm(공간 없음)
- 130* 쿠웨이트 dd mon yyyy hh:mi:ss:mmmAM
- 131* 쿠웨이트 dd/mm/yy hh:mi:ss:mmmAM

*     기본값(style 0 또는 100, 9 또는 109, 13 또는 113, 20 또는 120, 21 또는 121)은 항상 세기(yyyy)를 반환합니다.

밑에 예제는 Convert함수와 날짜함수를 사용하여서 뽑아온것입니다.

 

1) 오늘 작성된 글중 Top 10개

SELECT TOP 10 m_no, m_table, a.cat_num, m_subject, m_insertdate, m_read, b.binfo_type
from m_board a inner join m_binfo b on a.m_table = b.binfo_table
where convert(varchar(40), m_insertdate, 110) = convert(varchar(40),getdate(), 110) and  m_listnum <> 0 and binfo_type <> 'Fbd' 
order by m_read desc

 

2) 오늘부터 일주일전까지 작성된 글중 Top 10개
SELECT TOP 10 m_no, m_table, a.cat_num, m_subject, m_insertdate, m_read, b.binfo_type
from m_board a inner join m_binfo b on a.m_table = b.binfo_table
where  convert(varchar(40),  m_insertdate, 110) >= convert(varchar(40), Dateadd(day,-7, getdate()), 110) and  m_listnum <> 0 and binfo_type <> 'Fbd' 
order by m_read desc

 

3) 오늘부터 한달전까지 작성된글중 랜덤하게 10개

SELECT TOP 10 m_no, m_table, a.cat_num, m_subject, m_insertdate, m_read, b.binfo_type
from m_board a inner join m_binfo b on a.m_table = b.binfo_table
where  convert(varchar(40),  m_insertdate, 110) >= convert(varchar(40), Dateadd(month,-1, getdate()), 110) and  m_listnum <> 0 and binfo_type <> 'Fbd' 
order by newid()

Posted by SB패밀리