I need to format a datetime column from
2008-04-28 03:00:00.000
to
20080428T030000
How to get this format? Is there a built-in function for this?
Before SQL Server 2012:
REPLACE(REPLACE(CONVERT(varchar(19), MyDateTimeCol, 126), ':', ''), '-', '')
SQL Server 2012
FORMAT(#MyDateTimeCol, 'yyyyMMddTHHmmss')
I am not aware about a function that accepts a format string. But you can use the functions to extract the time and date parts. This page should give you all the necessary hints. More precisely this part.
I see though no time part (hours, minutes, seconds, milliseconds) extraction, so in that case, SUBSTRING is your friend.
Use the DatePart function to remove each individual element of the date (dd=day, yy=year etc.) and concatenate the outputs into the required format.
The arguments for DatePart can be found here.
Related
I have SQL which I run against the on premises database. In the WHERE clause I am narrowing it down to year
WHERE YEAR(SRCSYS_ADD_DATE_TIME)=2020
and I get the results
In Snowflake work sheet I am using
WHERE EXTRACT(YEAR FROM TO_DATE(SRCSYS_ADD_DATE_TIME))=2020
and I am getting this message
Date '2020-05-28-20.42.09.724117' is not recognized'
Please need help.
Snowflake's automatic date-time parsing isn't recognizing your period separated timestamp formatting.
You'll need to explicitly specify a format to read the string during conversion:
EXTRACT(
YEAR FROM
TO_DATE('2020-05-28-20.42.09.724117', 'YYYY-MM-DD-HH24.MI.SS.FF')
) = 2020
bkan.
The problem is the timestamp format. If you don't specify a timestamp format, Snowflake will try to autodetect. In this case it can't, so you'll have to specify the timestamp format:
select year(to_timestamp('2020-05-28-20.42.09.724117', 'YYYY-MM-DD-HH24.MI.SS.FF6'));
If you don't want to specify the timestamp format, your best option is using YYYY-MM-DD HH24:MM:SS.FFFFF (or some other precision of fractional seconds) like this:
select year('2020-05-28 20:42:09.724117'::timestamp);
The second option reformats the timestamp to the standard format, and the ::timestamp syntax casts it to a timestamp.
In SQL Server, I am getting the error:
Error -2147217913: Conversion failed when converting date an/or time from character string.
Error in converting
I am sure that my fields are in date field, but why this error keeps on showing?
First I validated first if the data type is really a date column:
CASE
WHEN ISDATE(dbo.AdditionalDetailInfo.UserDefined2) = 1
THEN dbo.AdditionalDetailInfo.UserDefined2
ELSE NULL
END AS ReceivedDate
I found out that yes, it's correct. so i proceed with converting this field where UserDefined2 value should always be plus 1 day.
CONVERT(VARCHAR(12), DATEADD(DAY, 1, CONVERT(DATETIME, dbo.AdditionalDetailInfo.UserDefined2)), 103) AS ReceivedDate
Please let me know if there's something wrong with my query as I really can't diagnose what went wrong.
See screenshot:
See this link, the actual data and in SQL server + 1 day
Maybe the field is indeed a date field, so it could be that no conversion is required. Try DATEADD(DAY, 1, dbo.AdditionalDetailInfo.UserDefined2).
If the column is indeed a string column, the you forgot to specify the style parameter when reading the value, you only used it when converting back. Try this instead:
CONVERT(VARCHAR(12), DATEADD(DAY, 1, CONVERT(DATETIME, dbo.AdditionalDetailInfo.UserDefined2, 103)), 103) AS ReceivedDate
MSDN says that date, time and datetime types are not allowed as arguments to ISDATE but in practical terms, passing a date to it:
SELECT ISDATE(getutcdate())
Causes the datetime to be converted to varchar implicitly, passed to ISDATE as varchar, which promptly then returns a 1
As such we've no guarantee that your column really is a date type like you say, so I'm guessing it's probably a string.
Really, what you should do is change your column to be a date type. Don't store dates as strings; if Microsoft had intended you to do this and thought for a second it was a good idea, they wouldn't have implemented other column types than char based ones
If you cannot convert your column to date then you'll need to find the bad value:
select * from table where isdate(column) =0
Note that your attempt to convert style 103 (dd/mm/yyyy) may be failing because you have data that isn't in this style eg Christmas as 12/25/2000
Isdate might not pick this up because your database date format is set to mm/dd/yyyy and isdate thinks it's ok. Change your database date format so that isdate can properly tell what is a good date and what is a bad date
https://learn.microsoft.com/en-us/sql/t-sql/functions/isdate-transact-sql?view=sql-server-2017
And then, please, for the love of doing this properly, use a date typed column, not a string typed one
We need more information. In particular, we need to know what data type the UserDefined2 is. If you tell us that, then we can give better replies.
Just a note that ISDATE is a pretty worthless function since it returns 1 if the string is convertible to datetime. But what if what you really have os datetime2? Or smalldatetime? Because of that, use TRY_CAST instead.
Also, you just gave us pieces of queries, expressions. We don't see the context. There is something called predicate pushing in SQL Server that can mess things up for you (SQL Server pushes a predicate deeper into the query resulting that an expression work over non-datetime values even though you think that you have excluded them in a WHERE clause.
Also, note that how a datetime value is interpreted when you have separators and use the old types (datetime or datetime2) depends on the login's language setting.
More info in http://karaszi.com/the-ultimate-guide-to-the-datetime-datatypes
I have a VB6 application where I insert a set of dates into a SQL-SERVER. Each time I insert a value, it gets inserted as 1978-12-12 00:00:00.000. Is it possible to specify in the INSERT statement, how you want the date to be formatted? VB6 does not seem to recognize CONVERT. I did previously CONVERT date when I loaded it into a MSHFlexGrid like this:
Convert(varchar,tblClient.DOB, 101)
But I did this in a select statement. Will SQL let me insert a value in a format MM/DD/YYYY as I need it later in that format.
The reason why I need the formatting is because I connected all my tables in SQL-SERVER2008 to Access for report generating purposes. So I need it formatted correctly in SQL-SERVER2008 as it dynamically connects to Access.
Ideally, the data type of the column in the database is set to Date or DateTime. Basically, if you want to store a date, then use a date date type.
That being said, in VB6 you usually have to (at least temporarily) store the date as a string so there is almost always a string to date conversion that happens somewhere.
Will SQL let me insert a value in a format MM/DD/YYYY
Yes. But you should not do this. Instead, you should insert the date with the format "YYYYMMDD". Notice that there are no delimiters. The problem with mm/dd/yyyy is that it could accidentally be interpreted as the wrong date. For example, 1/2/2015 would be interpreted as Feb 1, 2015 if you lived in England, or Jan 2, 2015 if you live in the US. However, SQL Server will always interpret 20150102 and Jan 2, 2015.
Once you have the data stored the way you want in the database (as an actual date data type), you should actually return it as a date to your front end (either Access or VB6). In the front end, you should use the format command to display the date. The format command will use the regional settings of the computer to display dates the way the user wants to see it.
Ex:
txtDateOfBirth.Text = Format(rs.Fields.Item("DOB").value, "Short Date")
Doing things this way... you should never have problems with dates.
The best way is not to store formatted dates in your database server.
One way you can get what you want is by using a view where you format your data and use that as input for your report:
CREATE VIEW myreport
SELECT replace(convert(NVARCHAR, mydate, 106), ' ', '/') from mytable
But I would recommend formatting dates on the application level.
You can use VB6s format function prep the date before inserting it into SQL. Here's an example (tested in VBA).
Format(Now(), "YYYY-MM-DD")
I would like to keep my dates as datetime datatype by also be in MM/DD/YYYY format. I know how to do this by converting them to a varchar, but want to keep the datetime format. Can anyone help with this?
Currently I have tried
SELECT CONVERT(datetime, GETDATE(), 101)
which is not working...
There is a basic misunderstanding in your question. Repeat after me: Datetimes don't have a format.
It helps if you think of them as just an array of seven integers (year, month, day, hours, minutes, seconds, milliseconds) with certain constraints. That's not in any way accurate, but it helps to get the notion out of your head that something akin to 12/31/2015 is stored in your database.
Datetimes only get a format when (implicitly or explicitly) being converted to strings. You already know how to set the format when explicitly converting to string, now all that is left to do is to find the implicit conversion that is obviously bothering you and replace it with an explicit one.
Date and datetime Values stored in the database are NOT in any recognizable format. They are stored in binary (1s and 0s) in a proprietary format where one part represents the number of days since a defined reference date (1 jan 1900) in SQL server). and the other part represents the time portion of the value. (in sql server, its the number of 1/300ths of a second since midnight.)
ALL formatting of dates and date times, no matter what format you wish for, is done only after the values have been extracted from the database, before you see them on screen, in whatever application you are using.
You can find all the formats that the SQL Server convert function can use on this MSDN Convert Link
I have a legacy application where the input is a date string, i.e.:
06/12/2009
The format of the input is always a string, and is consistent, it's always dd/mm/yyyy
At the moment the legacy app just INSERTS this in a DateTime fields. Obviously if the Localization Culture settings of the Server change, we have a bug.
Two questions:
One:
Whats the safest way to store Dates in SQLServer in this situation?
Is there a format that will always be correctly interpreted regardless of the order of day and month?
Two:
What settings exactly determines the culture of a SQLServer DB, is it an OS setting, or a setting of that DB, or what?
cheers
Format YYYY-MM-DD is unambiguous, meaning that SQL Server won't confuse the month
and day when converting a string value to DATETIME. (I've never experienced a problem with an implicit conversion using that format using the four digit year.)
The "safest" (and most convenient) way to store date values in SQL Server is to use DATETIME datatype.
Use the CONVERT function to explicitly specify the input and output formats when converting between DATETIME and strings.
SQL Server 2005 Documentation on CONVERT style argument values:
http://msdn.microsoft.com/en-us/library/ms187928(SQL.90).aspx
To convert a string representation to DATETIME datatype:
select CONVERT(datetime, '2009-06-03', 20)
The first argument is datatype to convert to, the second argument is the expression to be converted, the third argument is the style.
(style 20 is ODBC Canonical format = 'YYYY-MM-DD HH:MI:SS' (24 hour clock)
[FOLLOWUP]
To convert a DATETIME expression (e.g. getdate() to VARCHAR in 'YYYY-MM-DD' format:
select CONVERT(varchar(10), getdate(), 20)
Note that specifying varchar(10) gets you just the first 10 characters of the etnire 'YYYY-MM-DD HH:MM:SS' format.
[/FOLLOWUP]
As to what determines the default formats, that's going to be research. We avoid the issues caused by default formats by specifying the formats.
I would recommend storing all dates in UTC time when they are placed into the database. It will be consistent that way.
Storing dates like this seems to work well...
YYYY-MM-DD
See SET DATEFORMAT. The SQL 'culture' is set by SET LANGUAGE at a session level. SQL Server has its own date format settings, independent of the hosting OS. This is for several reasons: ANSI compliance, to prevent OS changes from affecting applications using the database hosted on that host and not least is compatibility, the SQL long predates the OS is currently running on.
Keep in mind that DATA is not its PRESENTATION. In this case that DATA is a DATE or DATETIME, regardless of how you show them.
As for inserting/updating/comparing datetime values, I quote the BOL:
When specifying dates in comparisons
or for input to INSERT or UPDATE
statements, use constants that are
interpreted the same for all language
settings: ADO, OLE DB, and ODBC
applications should use the ODBC
timestamp, date, and time escape
clauses of:
{ ts 'yyyy-mm-dd
hh:mm:ss[.fff] '} such as: { ts
'1998-09-24 10:02:20' }
{ d 'yyyy-mm-dd'} such as: { d '1998-09-24' }
{ t 'hh:mm:ss'} such as: { t '10:02:20'}
I can assure you that, if you use this formats they will always work, regardless of the locale of you server
I'm a bit conservative in these matters, but I prefer to use separate Year / Month / Day fields in the table, rather than a Date field that uses a DBMS-specific data type. It certainly takes more space, but the lack of ambiguity and increased portability is worth it to me.
The price you pay is that you don't get free date/time arithmetic and sorting, but it's easy enough to do yourself or by a slightly more complex "ORDER BY" clause.
I agree with the advice from spencer7593, but please be aware that using cast or convert without a format can give unexpected results. This T-SQL query returns 12, not 1.
set language British
select month(CAST('2016-01-12' AS datetime))
Normally I prefer to insert as
insert into tbl values('yyyyMMdd')
Then, itll be inserted in proper format based on db.