SQL Server 문자열을 날짜로 변환


186

다음과 같이 문자열을 변환하고 싶습니다.

'10/15/2008 10:06:32 PM'

SQL Server에서 동등한 DATETIME 값으로

오라클에서는 다음과 같이 말합니다.

TO_DATE('10/15/2008 10:06:32 PM','MM/DD/YYYY HH:MI:SS AM')

이 질문 은 문자열을 표준 형식 중 하나로 구문 분석 한 다음 해당 코드 중 하나를 사용하여 변환 해야 함을 의미합니다 . 그런 평범한 작업에는 우스운 것 같습니다. 더 쉬운 방법이 있습니까?


답변:


28

SQL Server (2005, 2000, 7.0)에는 임의로 구성된 날짜 시간을 문자열 형식으로 가져 와서 날짜 / 시간 데이터 유형으로 변환하는 융통성 또는 융통성이없는 방법이 없습니다.

"임의로"라는 말은, "당신이나 나 또는 지구 반대편에있는 사람은 아니지만, 그것을 쓴 사람이 직관적이고 완전히 명백한 것으로 생각하는 형태"를 의미합니다. 솔직히, 나는 그런 알고리즘이 있는지 확실하지 않습니다.


32
이러한 알고리즘이 있으며 Oracle은 이미이를 구현했으며 SQL Server의 해당 기능이 부족하다는 것은 지속적인 고통입니다.
matao

19
@matao는 오라클을 입력하여 사용자가 입력 한 사용자가 9/6/122012 년 9 월 6 일, 2012 년 6 월 9 일, 2009 년 12 월 6 일 또는 다른 것을 의미 하는지 여부를 어떻게 마법으로 결정 합니까?
Aaron Bertrand

13
걱정하지 마십시오. techonthenet.com/oracle/functions/to_date.php 개발자가 지정한 일관된 형식이어야하지만 MS가 제공하는 소수의 형식 마스크보다 훨씬 더 유연하므로 사용자 지정 구문 분석이 어려움 .
matao

3
@JosphStyons는 샘플에 표시된대로 Oracle의 TO_DATE 함수를 알고있었습니다. 그는 문자열 형식 / 구조를 몰라도 문자열 날짜로 변환하는 방법이 있는지 알고 싶었습니다 . SQL은 그렇게하지 않으며 Oracle의 TO_DATE도 그렇게하지 않는 것으로 보입니다.
Philip Kelley

23
@PhilipKelley 나는 OP가 형식을 알 필요없이 어떻게 해야하는지 알고 싶지 않습니다. 그는 형식을 알고 있으며 SQL Server에 TO_DATE와 같은 것이 있는지, 즉 개발자가 임의의 형식 문자열을 입력 할 수 있는지 묻습니다.
neverfox

306

이 시도

Cast('7/7/2011' as datetime)

Convert(varchar(30),'7/7/2011',102)

자세한 내용은 CAST 및 CONVERT (Transact-SQL) 를 참조하십시오.


14
이것이 올바른 방법이며 정답으로 표시되어야합니다. 참고 Cast('2011-07-07' as datetime)또한 작동하고, 달과 일 주문을 통해 모호성을 제거합니다.
Joe DeRose

월이 12보다 크면 작동하지 않습니다. 형식은 mm / dd / yyyy 형식을 예상합니다
Chakri

dd / mm / yyyy에서 변환 할 때 Convert (varchar (30), '7 / 7 / 2011', 103) 사용
Matias Masso

2
@Chakri 날짜가 일 / 월 / 년을 사용하는 경우 SET DATEFORMAT dmy쿼리하기 전에
나단 그리피스

49

쿼리 프로세서를 통해이를 실행하십시오. 그것은 날짜 및 / 또는 시간과 같은 형식을 지정하며 이것들 중 하나는 당신이 찾고있는 것을 줄 것입니다. 적응하기가 어렵지 않습니다.

Declare @d datetime
select @d = getdate()

select @d as OriginalDate,
convert(varchar,@d,100) as ConvertedDate,
100 as FormatValue,
'mon dd yyyy hh:miAM (or PM)' as OutputFormat
union all
select @d,convert(varchar,@d,101),101,'mm/dd/yy'
union all
select @d,convert(varchar,@d,102),102,'yy.mm.dd'
union all
select @d,convert(varchar,@d,103),103,'dd/mm/yy'
union all
select @d,convert(varchar,@d,104),104,'dd.mm.yy'
union all
select @d,convert(varchar,@d,105),105,'dd-mm-yy'
union all
select @d,convert(varchar,@d,106),106,'dd mon yy'
union all
select @d,convert(varchar,@d,107),107,'Mon dd, yy'
union all
select @d,convert(varchar,@d,108),108,'hh:mm:ss'
union all
select @d,convert(varchar,@d,109),109,'mon dd yyyy hh:mi:ss:mmmAM (or PM)'
union all
select @d,convert(varchar,@d,110),110,'mm-dd-yy'
union all
select @d,convert(varchar,@d,111),111,'yy/mm/dd'
union all
select @d,convert(varchar,@d,12),12,'yymmdd'
union all
select @d,convert(varchar,@d,112),112,'yyyymmdd'
union all
select @d,convert(varchar,@d,113),113,'dd mon yyyy hh:mm:ss:mmm(24h)'
union all
select @d,convert(varchar,@d,114),114,'hh:mi:ss:mmm(24h)'
union all
select @d,convert(varchar,@d,120),120,'yyyy-mm-dd hh:mi:ss(24h)'
union all
select @d,convert(varchar,@d,121),121,'yyyy-mm-dd hh:mi:ss.mmm(24h)'
union all
select @d,convert(varchar,@d,126),126,'yyyy-mm-dd Thh:mm:ss:mmm(no spaces)'

47

SQL Server Denali에서는 원하는 대상에 접근 할 수있는 작업을 수행 할 수 있습니다. 그러나 여전히 임의로 정의 된 엉뚱한 날짜 문자열을 전달할 수 없으며 SQL Server가 수용 할 것으로 기대합니다. 다음은 자신의 답변에 게시 한 내용을 사용한 예입니다. FORMAT () 함수는 로케일을 선택적 인수로 받아 들일 수 있습니다. .Net 형식을 기반으로하므로 대부분의 토큰 형식이 없을 수도 있습니다.

DECLARE @d DATETIME = '2008-10-13 18:45:19';

-- returns Oct-13/2008 18:45:19:
SELECT FORMAT(@d, N'MMM-dd/yyyy HH:mm:ss');

-- returns NULL if the conversion fails:
SELECT TRY_PARSE(FORMAT(@d, N'MMM-dd/yyyy HH:mm:ss') AS DATETIME);

-- returns an error if the conversion fails:
SELECT PARSE(FORMAT(@d, N'MMM-dd/yyyy HH:mm:ss') AS DATETIME);

날짜 입력을보다 세밀하게 관리하고 소독하는 것이 좋습니다. 사람들이 자유 형식의 텍스트 필드에 원하는 형식을 사용하여 날짜를 입력하게하는 시대는 지금 우리 뒤에 있습니다. 누군가가 2011 년 8 월 9 일에 들어가면 8 월 9 일 또는 9 월 8 일입니까? 캘린더 컨트롤에서 날짜를 선택하게하면 앱이 형식을 제어 할 수 있습니다. 사용자의 행동을 얼마나 많이 예측하려고하더라도 계획하지 않은 날짜를 입력하는 멍청한 방법을 항상 파악하게됩니다.

하지만 데날리까지는 @Ovidiu가 지금까지 최고의 조언을 가지고 있다고 생각합니다. 그런 다음 원하는만큼 엉뚱한 비표준 형식의 사례 / 스위치를 작성할 수 있습니다.


@dhergert에 대한 업데이트 :

SELECT TRY_PARSE('10/15/2008 10:06:32 PM' AS DATETIME USING 'en-us');
SELECT TRY_PARSE('15/10/2008 10:06:32 PM' AS DATETIME USING 'en-gb');

결과 :

2008-10-15 22:06:32.000
2008-10-15 22:06:32.000

여전히 다른 중요한 정보가 먼저 있어야합니다. 기본 T-SQL을 사용하여 6/9/20126 월 9 일인지 9 월 6 일인지 확인할 수 없습니다 .


1
질문은 문자열을 날짜 시간이 아닌 날짜 시간으로 변환하는 방법이었습니다.
David Hergert

1
TRY_PARSE가 완벽했습니다. 공유해 주셔서 감사합니다. 'Thu Sep 2016 2016'구문 분석에 문제가있었습니다.
시몬

11

이 문제에 대한 가장 좋은 해결책은 DateTime.Parse 또는 ParseExact 함수 중 하나를 사용하여 지정된 형식으로 DateTime 값을 반환하는 SLR Server 2005의 CLR 함수를 사용하는 것입니다.


11

이것을 사용하십시오 :

SELECT convert(datetime, '2018-10-25 20:44:11.500', 121) -- yyyy-mm-dd hh:mm:ss.mmm

변환 코드 는 공식 문서 의 표를 참조하십시오 .


8

왜 안 해봐

select convert(date,'10/15/2011 00:00:00',104) as [MM/dd/YYYY]

날짜 형식은 SQL Server 도우미> SQL Server 날짜 형식 에서 찾을 수 있습니다.


코드 예제가 작동하지 않습니다. "문자열에서 날짜 및 / 또는 시간을 변환 할 때 변환에 실패했습니다."
César León

5
이어야 select convert(date,'10/15/2011 00:00:00',101)합니다. docs.microsoft.com/en-us/sql/t-sql/functions/…
anotherUser

1
8
명이이

4

누군가를 도울 수있는 경우를 대비하여 이것을 알아 내기 위해 잠시 시간을 보냈습니다.

SQL Server 2012 이상에서는이 기능을 사용할 수 있습니다.

SELECT DATEFROMPARTS(2013, 8, 19);

이 함수에 넣을 날짜 부분을 추출하는 방법은 다음과 같습니다.

select
DATEFROMPARTS(right(cms.projectedInstallDate,4),left(cms.ProjectedInstallDate,2),right( left(cms.ProjectedInstallDate,5),2)) as 'dateFromParts'
from MyTable

3

페이지 에는 CONVERT 함수에서 사용 가능한 모든 지정된 날짜 / 시간 변환에 대한 참조 가 있습니다. 값이 허용 가능한 패턴 중 하나에 속하지 않으면 가장 좋은 방법은 ParseExact 경로를 이용하는 것입니다.


링크가 끊어졌습니다.
Michael Potter

3

벽 형식을 임의로 또는 완전히 벗어난 경우 개인적으로 미리 알고 있거나 앞으로 나올 예정이라면 regexp를 사용하여 원하는 날짜의 섹션을 가져 와서 유효한 날짜 / 날짜 / 시간 구성 요소를 구성하십시오.


1

나는 이것이 많은 답변을 가진 사악한 오래된 게시물이라는 것을 알고 있지만 많은 사람들은 물건을 분리하고 다시 묶어야하거나 OP 원본이 요청한 변환을 암시 적으로 수행 할 방법이 없다고 주장합니다. .

OP는 같은 질문을 가진 다른 사람들에게 쉬운 답변을 검토하고 희망적으로 제공하기 위해 '10 / 15 / 2008 10:06:32 PM '을 DATETIME으로 변환하는 방법을 물었습니다. 이제 SQL Server에는 일시적인 변환에 대한 일부 언어 종속성이 있지만 언어가 영어이거나 이와 비슷한 경우 간단한 문제가됩니다. 변환을 수행하고 형식에 대해 걱정하지 마십시오. 예를 들어 (CONVERT 또는 CAST를 사용할 수 있음) ...

 SELECT UsingCONVERT = CONVERT(DATETIME,'10/15/2008 10:06:32 PM')
        ,UsingCAST   = CAST('10/15/2008 10:06:32 PM' AS DATETIME)
;

... 따라서 다음과 같은 대답을 얻습니다. 둘 다 맞습니다.

여기에 이미지 설명을 입력하십시오

TV 광고에서 말하는 것처럼 "하지만 기다리십시오! 아직 주문하지 마십시오! 추가 비용없이 더 많은 것을 할 수 있습니다!"

DATETIME으로 시간 변환의 진정한 힘을보고 DATETIME2로 알려진 실수를 부분적으로 살펴 보자. DATETIME이 자동으로 처리 할 수 ​​있고 DATETIME2가 처리 할 수없는 왜곡 된 형식을 확인하십시오. 다음 코드를 실행하고 참조하십시오 ...

--===== Set the language for this example.
    SET LANGUAGE ENGLISH --Same a US-English
;
--===== Use a table constructor as if it were a table for this example.
 SELECT *
        ,DateTimeCONVERT  = TRY_CONVERT(DATETIME,StringDT)
        ,DateTimeCAST     = TRY_CAST(StringDT AS DATETIME)
        ,DateTime2CONVERT = TRY_CONVERT(DATETIME2,StringDT)
        ,DateTime2CAST    = TRY_CAST(StringDT AS DATETIME2)
   FROM (
         VALUES
         ('Same Format As In The OP'    ,'12/16/2001 01:51:01 PM')
        ,('Almost Normal'               ,'16 December, 2001 1:51:01 PM')
        ,('More Normal'                 ,'December 16, 2001 01:51:01 PM')
        ,('Time Up Front + Spaces'      ,'   13:51:01  16 December   2001')
        ,('Totally Whacky Format #01'   ,'  16  13:51:01  December   2001')
        ,('Totally Whacky Format #02'   ,'  16    December 13:51:01  2001  ')
        ,('Totally Whacky Format #03'   ,'  16    December 01:51:01  PM 2001  ')
        ,('Totally Whacky Format #04'   ,' 2001 16    December 01:51:01  PM ')
        ,('Totally Whacky Format #05'   ,' 2001    December 01:51:01  PM  16  ')
        ,('Totally Whacky Format #06'   ,' 2001 16    December  01:51:01 PM  ')
        ,('Totally Whacky Format #07'   ,' 2001 16    December  13:51:01 PM  ')
        ,('Totally Whacky Format #08'   ,' 2001 16  13:51:01 PM  December    ')
        ,('Totally Whacky Format #09'   ,'   13:51:01   PM  2001.12/16 ')
        ,('Totally Whacky Format #10'   ,'   13:51:01   PM  2001.December/16 ')
        ,('Totally Whacky Format #11'   ,'   13:51:01   PM  2001.Dec/16 ')
        ,('Totally Whacky Format #12'   ,'   13:51:01   PM  2001.Dec.16 ')
        ,('Totally Whacky Format #13'   ,'   13:51:01   PM  2001/Dec.16')
        ,('Totally Whacky Format #14'   ,'   13:51:01   PM  2001 . 12/16 ')
        ,('Totally Whacky Format #15'   ,'   13:51:01   PM  2001 . December / 16 ')
        ,('Totally Whacky Format #16'   ,'   13:51:01   PM  2001 . Dec /   16 ')
        ,('Totally Whacky Format #17'   ,'   13:51:01   PM  2001 . Dec .   16 ')
        ,('Totally Whacky Format #18'   ,'   13:51:01   PM  2001 / Dec .   16')
        ,('Totally Whacky Format #19'   ,'   13:51:01   PM  2001 . Dec -   16 ')
        ,('Totally Whacky Format #20'   ,'   13:51:01   PM  2001 - Dec -   16 ')
        ,('Totally Whacky Format #21'   ,'   13:51:01   PM  2001 - Dec .   16')
        ,('Totally Whacky Format #22'   ,'   13:51:01   PM  2001 - Dec /   16 ')
        ,('Totally Whacky Format #23'   ,'   13:51:01   PM  2001 / Dec -   16')
        ,('Just the year'               ,' 2001      ')
        ,('YYYYMM'                      ,' 200112      ')
        ,('YYYY MMM'                    ,'2001 Dec')
        ,('YYYY-MMM'                    ,'2001-Dec')
        ,('YYYY    .     MMM'           ,'2001    .     Dec')
        ,('YYYY    /     MMM'           ,'2001    /     Dec')
        ,('YYYY    -     MMM'           ,'2001    /     Dec')
        ,('Forgot The Spaces #1'        ,'2001December26')
        ,('Forgot The Spaces #2'        ,'2001Dec26')
        ,('Forgot The Spaces #3'        ,'26December2001')
        ,('Forgot The Spaces #4'        ,'26Dec2001')
        ,('Forgot The Spaces #5'        ,'26Dec2001 13:51:01')
        ,('Forgot The Spaces #6'        ,'26Dec2001 13:51:01PM')
        ,('Oddly, this doesn''t work'   ,'2001-12')
        ,('Oddly, this doesn''t work'   ,'12-2001')
        ) v (Description,StringDT)
;

그렇습니다. SQL Server DOES는 실제로 모든 종류의 이상한 o 시간 형식을 처리하는 매우 유연한 방법을 가지고 있으며 특별한 처리가 필요하지 않습니다. 24 시간에 추가 된 "PM"을 제거 할 필요조차 없었습니다. "PFM"(Pure Freakin 'Magic)입니다.

LANGUAGE에 따라 상황이 조금씩 다를 수 있습니다. 서버에 대해 선택한 것이지만 그 중 많은 부분이 처리 될 것입니다.

이러한 "자동 매직"변환은 새로운 것이 아닙니다. 그들은 정말로 먼 길을 간다.


사악한 옛 질문에 대한 사악한 새로운 대답. 감사!
JosephStyons

피드백 @JosephStyons에 감사드립니다.
Jeff Moden

0

SQL Server에서 시도하고 알아 내려면 CAST CAST ( 'whatever'AS datetime)를 사용하십시오. 그러나 일반적으로 나쁜 생각입니다. 국제 날짜와 관련된 문제가 있습니다. 알다시피, 이러한 문제를 피하기 위해 날짜의 ODBC 표준 형식을 사용하려고합니다. 형식 번호 120, 20은 2 자리 연도 형식입니다. SQL Server에는 사용자가 지정한 형식을 제공 할 수있는 기본 제공 기능이 없다고 생각합니다. 당신은 당신 자신의 글을 쓸 수 있고 온라인으로 검색하면 하나를 찾을 수도 있습니다.


단일 열에 국제 날짜가있는 경우 형식 번호를 사용하는 것이 좋습니다. 국제 날짜와 미국 날짜가 모두 하나의 열에 혼합되어 있으면 형식을 설명하는 자매 열이없는 한 7/6/2000과 6/7/2000과 같은 차이를 결정할 방법이 없습니다. 그렇기 때문에 소스의 데이터 품질이 반드시 중요해야합니다. 예를 들어, 모든 미국 날짜가 있다는 것을 알고 있다면 암묵적인 전환이 그 일을하도록하십시오. 그들이 실패하면, 당신은 열의 무언가를 수정해야한다는 것을 알고 있습니다.
Jeff Moden

0

암시 적으로 MSSQL에서 문자열을 날짜 / 시간으로 변환

create table tmp 
(
  ENTRYDATETIME datetime
);

insert into tmp (ENTRYDATETIME) values (getdate());
insert into tmp (ENTRYDATETIME) values ('20190101');  --convert string 'yyyymmdd' to datetime


select * from tmp where ENTRYDATETIME > '20190925'  --yyyymmdd 
select * from tmp where ENTRYDATETIME > '20190925 12:11:09.555'--yyyymmdd HH:MIN:SS:MS



안녕하세요, stackoverflow에 오신 것을 환영합니다. 답변 주셔서 감사합니다. 이 코드가 질문에 대한 답을 줄 수는 있지만, 어떤 문제를 해결했으며 어떻게 해결했는지에 대한 설명을 추가 할 수 있습니까? 이것은 미래 독자들이 귀하의 답변을 더 잘 이해하고 그로부터 배우는 데 도움이 될 것입니다.
Plutian

-4
dateadd(day,0,'10/15/2008 10:06:32 PM')

3
StackOverflow에 오신 것을 환영합니다! 제발 답변 편집 코드에 대한 설명을 추가 할 수 있습니다. 이 질문은 거의 11 살 이며 이미 잘 설명되고 공감 된 답변 이 많이 있습니다. 귀하의 답변에 대한 설명이 없으면 다른 사람들에 비해 품질이 훨씬 떨어지며 다운 투표 또는 제거 될 가능성이 큽니다. 이 설명을 추가하면 답변의 존재를 정당화하는 데 도움이됩니다.
Das_Geek

그러나 "잘 설명 된"게시물, 심지어 올린 게시물도 너무 복잡합니다. 여기에 게시 된 것은 실제로 설명이 있거나없는 더 나은 것 중 하나입니다.
Jeff Moden
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.