添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

How do I convert a string of format mmddyyyy into datetime in SQL Server 2008?

My target column is in DateTime

I have tried with Convert and most of the Date style values however I get an error message:

'The conversion of a varchar data type to a datetime data type resulted in an out-of-range value.'

OP wants mmddyyyy; select convert(datetime,'12312009') -->>>_Msg 242, Level 16, State 3, Line 1 The conversion of a char data type to a datetime data type resulted in an out-of-range datetime value. KM. Oct 2, 2009 at 15:04

OP wants mmddyy and a plain convert will not work for that:

select convert(datetime,'12312009')
Msg 242, Level 16, State 3, Line 1 
The conversion of a char data type to a datetime data type resulted in 
an out-of-range datetime value

so try this:

DECLARE @Date char(8)
set @Date='12312009'
SELECT CONVERT(datetime,RIGHT(@Date,4)+LEFT(@Date,2)+SUBSTRING(@Date,3,2))

OUTPUT:

-----------------------
2009-12-31 00:00:00.000
(1 row(s) affected)
                +1, but wouldn't it be nice to not have to splice strings? techonthenet.com/oracle/functions/to_date.php
– dwerner
                May 17, 2012 at 19:05
                @dwerner, if you don't want to have to do stuff like that then don't store in an incorrect datatype.
– HLGEM
                Jan 28, 2013 at 16:42
                Correct me if I'm wrong, but that was the problem proposed by the question. My suggestion is to use a function tailored to the purpose.
– dwerner
                Jan 29, 2013 at 0:37
                Your "suggestion" seems like run-of-the-mill corporate shilling to me. Is a suggestion to use a totally different database technology useful or practical to virtually every database developer, even the one who are lead architects? Not really. Seems like it might be easier to simply store the information not as a varchar string, or at least as an ISO-formatted one.
– Lucas Leblanc
                Aug 13, 2018 at 19:53
                @LucasLeblanc, you must consider what the OP is asking for.  The OP does not elaborate on WHY the need this, possibly they are interfacing with things they can not change.  Also, I would never advise you store dates as strings, that is how you end up with problems like this.
– KM.
                Aug 23, 2018 at 12:56

SQL Server can implicitly cast strings in the form of 'YYYYMMDD' to a datetime - all other strings must be explicitly cast. here are two quick code blocks which will do the conversion from the form you are talking about:

version 1 uses unit variables:

BEGIN 
DECLARE @input VARCHAR(8), @mon CHAR(2), 
@day char(2), @year char(4), @output DATETIME
SET @input = '10022009'   --today's date
SELECT @mon = LEFT(@input, 2), @day = SUBSTRING(@input, 3,2), @year = RIGHT(@input,4)
SELECT @output = @year+@mon+@day 
SELECT @output 

version 2 does not use unit variables:

BEGIN 
DECLARE @input CHAR(8), @output DATETIME
SET @input = '10022009' --today's date 
SELECT @output = RIGHT(@input,4) + SUBSTRING(@input, 3,2) + LEFT(@input, 2)
SELECT @output

Both cases rely on sql server's ability to do that implicit conversion.

Likely you have bad data that cannot convert. Dates should never be stored in varchar becasue it will allow dates such as ASAP or 02/30/2009. Use the isdate() function on your data to find the records which can't convert.

OK I tested with known good data and still got the message. You need to convert to a different format becasue it does not know if 12302009 is mmddyyyy or ddmmyyyy. The format of yyyymmdd is not ambiguous and SQL Server will convert it correctly

I got this to work:

cast( right(@date,4) + left(@date,4) as datetime)

You will still get an error message though if you have any that are in a non-standard format like '112009' or some text value or a true out of range date.

After doing some testing on a million random date strings in the mmddyyyy format like the OP has, this turns out to be both the fastest to run and easiest to code. There are other methods that will tie it for performance but, out of all the code that actually works as the OP asked on this thread, this one wins every time. It's not by more than 25ms on a million rows but, considering the ease of coding and the load of other methods I tested, this one wins. – Jeff Moden Jun 10, 2020 at 2:30

I found this helpful for my conversion, without string manipulation. https://learn.microsoft.com/en-us/sql/t-sql/functions/cast-and-convert-transact-sql

CONVERT(VARCHAR(23), @lastUploadEndDate, 121)

yyyy-mm-dd hh:mi:ss.mmm(24h) was the format I needed.

But that's not the format the OP has. The OP is stuck with converting mmddyyyy to a datetime. – Jeff Moden Jun 7, 2020 at 3:34

Convert would be the normal answer, but the format is not a recognised format for the converter, mm/dd/yyyy could be converted using convert(datetime,yourdatestring,101) but you do not have that format so it fails.

The problem is the format being non-standard, you will have to manipulate it to a standard the convert can understand from those available.

Hacked together, if you can guarentee the format

declare @date char(8)
set @date = '12312009'
select convert(datetime, substring(@date,5,4) + substring(@date,1,2) + substring(@date,3,2),112)

Look at CAST / CONVERT in BOL that should be a start.

If your target column is datetime you don't need to convert it, SQL will do it for you.

Otherwise

CONVERT(datetime, '20090101')

Should do it.

This is a link that should help as well:

But that's not the format the OP has. The OP is stuck with converting mmddyyyy to a datetime. – Jeff Moden Jun 7, 2020 at 3:35

I'd use STUFF to insert dividing chars and then use CONVERT with the appropriate style. Something like this:

DECLARE @dt VARCHAR(100)='111290';
SELECT CONVERT(DATETIME,STUFF(STUFF(@dt,3,0,'/'),6,0,'/'),3)

First you use two times STUFF to get 11/12/90 instead of 111290, than you use the 3 to convert this to datetime (or any other fitting format: use . for german, - for british...) More details on CAST and CONVERT

Best was, to store date and time values properly.

  • This should be either "universal unseparated format" yyyyMMdd
  • or (especially within XML) it should be ISO8601: yyyy-MM-dd or yyyy-MM-ddThh:mm:ss More details on ISO8601
  • Any culture specific format will lead into troubles sooner or later...

    use Try_Convert:Returns a value cast to the specified data type if the cast succeeds; otherwise, returns null.

    DECLARE @DateString VARCHAR(10) ='20160805'
    SELECT TRY_CONVERT(DATETIME,@DateString)
    SET @DateString ='Invalid Date'
    SELECT TRY_CONVERT(DATETIME,@DateString)
    

    Link:MSDN TRY_CONVERT (Transact-SQL)

    But that's not the format the OP has. The OP is stuck with converting mmddyyyy to a datetime. – Jeff Moden Jun 7, 2020 at 3:36

    I had luck with something similar:

    Convert(DATETIME, CONVERT(VARCHAR(2), @Month) + '/' + CONVERT(VARCHAR(2), @Day)
    + '/' + CONVERT(VARCHAR(4), @Year))
    

    SQL standard dates while inserting or updating Must be between 1/1/1753 12:00:00 AM and 12/31/9999 11:59:59 PM.

    So if you are inserting/Updating below 1/1/1753 you will get this error.

    DECLARE @d char(8)
    SET @d = '06082020'    /* MMDDYYYY means June 8. 2020 */
    SELECT CAST(FORMAT (CAST (@d AS INT), '##/##/####') as DATETIME)
    

    Result returned is the original date string in @d as a DateTime.

    But that's not the format the OP has. The OP is stuck with converting mmddyyyy to a datetime. – Jeff Moden Jun 7, 2020 at 3:40 Thanks for the feedback. Just as an FYI if you don't already know it, the FORMAT function usually take 43 times (or worse) more time to execute than even some of the more complex CAST/CONVERT functionality that people come up with. I generally avoid it like the plague because it's so slow. – Jeff Moden Jun 9, 2020 at 22:33