CONVERT(VARCHAR(11),Enrollment.[Enroll End],106)
I thought the above was supposed to return a date like '12 Jan 2016', it is instead returning dates like '15 Oca 2016'. Does anyone know why this is happening? I originally thought maybe the language was set incorrectly but it was not.
https://msdn.microsoft.com/en-us/library/ms187928.aspx denotes 106 with this
1 These style values return nondeterministic results. Includes all (yy) (without century) styles and a subset of (yyyy) (with century) styles.
I'm not sure if the above has something to do with it - though I am not entirely sure what they mean by nondeterministic results
Thanks for the help!
The values returned are non-deterministic because they rely on the locale settings of the user connection. In other words, you can run the same exact code from two different computers and get different results - you can't determine the result based solely on the parameters.
Make sure that your client machine is set to an English locale.
I hope this helps..
if local setting are different. always use dateformat
set dateformat dmy
declare #date datetime = '12-01-2016'
select CONVERT(VARCHAR(11),#date,106)
Related
I have a report to do, so I need to return a date from a datetime column, but it need to come only with the date from the column.
I am using the Microsoft SQL Server 2014. I've already tried to use CONVERT(name_of_the_column, GETDATE()) but I realised the it only works to return the current datetime from the server.
How can I do that?
Use CONVERT(DATE, <expression>).
create table t (dt datetime);
insert into t (dt) values ('2022-10-20 12:34:56');
select *, CONVERT(DATE, dt) from t;
Result:
dt (No column name)
----------------------- ----------
2022-10-20 12:34:56.000 2022-10-20
See example at db<>fiddle.
I prefer to use CAST instead.
CAST(name_of_the_field AS DATE)
I need to return a date from a datetime column
There are several things to cover in order to fully answer this.
First, if that really is a datetime column, something to understand here is datetime values will ALWAYS have a time component. It's even right there in the name. There is no way to return a datetime value that does not have a time portion. The closest you can get is casting to a string or date, but that's not really the same thing. Typically what happens instead is the time portion is truncated back to midnight (all 0s)... but that time portion is still there. That's where you see answers like this:
dateadd(dd, datediff(dd,0, name_of_the_column), 0)
or this:
CONVERT(varchar(10), name_of_the_column,101)
The next to thing to understand is the one thing you should not do is convert the date value to a string, as in the second example.
Because of cultural/internationalization issues, converting datetime or numeric values to and from strings is much slower and more error-prone than you'd like to believe. It's something to avoid, and probably best left to your client code or reporting tool.
A final consideration is datetime values NEVER have any time zone awareness (that would involve datetime2). So if there's anything on the client to show this in a local time it may be picking the wrong offset. Do that with a value where the time portion was already truncated, and you can end up with unexpected results.
Put all this together, and what you should do is CAST() to a DATE:
CAST(name_of_the_column AS DATE)
Now I have seen this comment on another answer with this recommendation:
keeps turning back time
This could be the time zone mismatch I've already mentioned, or it could also be that name_of_the_column is not really a datetime column in the first place, but rather a string/varchar column pretending to be a datetime column. In that case, the CAST() may be parsing the values with different cultural rules than you expect. It goes back to that whole "slower and more error-prone/something to avoid" thing again. Also in this is the case the schema is considered broken, and you really should fix it to use actual datetime or datetime2 values.
Speaking of "fix it", I also noticed the SQL Server 2014 tag. SQL Server 2014 has been fully end of life since 2019. That means it has not received any updates — not even critical security patches! — for several years now. It's dangerous and irresponsible to still be using it. Updating to a supported version is job #1 here.
I don't know why, but the only way that have returned the result I want to reach was using
CONVERT(VARCHAR, TB.COLUM, 103) AS 'NAME'.
But as mentioned before, this is not a good practice, and than I resolved to made do the convertion in the report tool of the system that am I working
Don't know why but while running the command
select CONVERT(datetime, getdate(),101)
gets '2016-10-27 15:53:12.743', which is the desired result.
However when the same command is run in a Stored Procedure like
if #CodeFilter2 is not null
select #CodeFilter2=CONVERT(datetime,GETDATE(),101)
yields 'Oct 27 2016 3:55PM'.
Please help me understand as to why is this happening.
Thanks in advance!
You're converting a datetime to a datetime? Are you expecting that the format used in convert sticks around? It's just ignored, since it has no meaning for the conversion you're doing. If you want to convert a datetime to a varchar, you need to use something like convert(varchar(max), getDate(), 101), which will give you the correct output 10/27/2016 - I have no idea why you'd expect either of your samples to be correct; they simply happen to work that way because the default conversion (based on locale and other context, which is very variable) happens to be your desired result (in the first case).
If you need to rely on specific formatting you must use explicit formatting. Or let the application handle it instead of the DB server. The proper format for the ODBC cannonical form (which seems to be the one you desire) is 121. Make sure you're converting to varchar or nvarchar, not datetime.
I realise that you can use SET DATEFORMAT to alter the way that a string is parsed but is the following unambiguous:
SELECT CONVERT(DATE, '02Oct15')
Is there any circumstances that this would be interpreted as 15th October 2002?
The century conversion will be an issue in 35 years (the y2k50, there is an amusing thought), but until then it's unambiguous. Any attempt to pass an invalid date in the first section results in a conversion error rather than it treating the third section as a date instead of a year.
Finally changing the default language (which changes the default date format) uses the same conversion (British), or causes it error out (Italian). Still as others have mentioned, storing dates in this format is a bad idea, however unless I miss my guess this seems like your importing data from a report, so you probably don't have much control over it. Anyway hope that helps and good luck.
I was not able to make 02Oct15 to become October 15, 2002. However, if all three date components are numbers, it's easy to make that cast:
SET DATEFORMAT YMD
SELECT CONVERT(DATE, '02Oct15'), -- October 2, 2015
CONVERT(DATE, '021015') -- October 15, 2002
I suspect that once you introduce natural language to the string, SQL Server use culture-specific rules to convert the date components. But in the end, only Microsoft knows what SQL Server's string-to-date algorithm is.
The conversion of a char data type to a datetime data type resulted in an out-of-range datetime value.
When I run the SQL query on my desktop machine, its fine. No errors or anything. However, when I execute the same code on the server that will be running it, it fails.
I've determined this is the section of SQL causing the issue. DateOfRun is a DateTime field.
,(SELECT intField
FROM tableA
WHERE RowIdentifier= ParentTable.RowIdentifier
AND DateOfRun = Convert(Varchar(10),ParentTable.OfferOutcomeDateTime,120)) AS Days
Why would this work on one machine, but not the other?
That's definitively odd and likely to do with regional settings but its like the old joke
A man goes to a doctor's office. He
says, "Doctor, it hurts when I raise
my arm over my head." The doctor
replies, "Then don't raise your arm
over your head."
So don't do that. Do this instead
WHERE RowIdentifier= ParentTable.RowIdentifier
AND DateOfRun =
DATEADD(DAY, DATEDIFF(DAY, 0, ParentTable.OfferOutcomeDateTime), 0)
Its the best way to go see Thomas' answer to Most efficient way in SQL Server to get date from date+time?
Then it will work regardless of regional settings because it never gets represented as a string
My guess would be that DateTime conversion from string fails because of different cultures on the local and server environments.
You don't mention your flavour of SQL, but the most likely candidate is a discrepancy between the input format of the char field and the system's locale settings.
"3/30/2011" is the 30th of March in the US, but makes no sense in the UK.
"30/3/2011" is the 30th of March in the UK, but makes no sense in the US.
This would work on one machine and not the other if the data is different on the different machines.
It would also not work if your regional settings are different.
You should do something like
SET DATEFORMAT dmy to set the format you want to use.
You could also convert/cast your date to local settings before you convert it to a varchar - http://msdn.microsoft.com/en-us/library/ms187928.aspx
I require a SQL script to validate a VARCHAR field in a table in a SQL Server 2005 database that contains DateTime values, in the format DD/MM/YYYY, or NULL values. I would like to identify all invalid dates. Can anyone suggest a method?
UPDATE
The answer has to make use of T-SQL; for performance reasons, I can't make use of SQLCLR.
Thanks, MagicAndi
Use "ISDATE()" OR "IS NULL": but set the language first to recognise the day-month-year order
SET LANGUAGE british
SELECT ISDATE('12/31/2009'), ISDATE('31/12/2009')
SET LANGUAGE us_english
SELECT ISDATE('12/31/2009'), ISDATE('31/12/2009')
Edit: As mentioned by #edosoft, you can use SET DATEFORMAT too. SET LANGUAGE implicitly sets DATEFORMAT, SET DATEFORMAT overrides SET LANGUAGE
You should specify the dateformat when using ISDATE(). From Books Online:
SET LANGUAGE us_english;
SET DATEFORMAT dmy;
SELECT ISDATE('15/04/2008'); --Returns 1.
You could use the ISDATE() function
you can use the inbuilt T-SQL IsDate() function.
and change the column to be datetime not varchar.
you can't sort or do any date calcualtions on a varchar column.
SQL's date handling isn't great, we wrote a DotNet function to do our DateTime conversions for difficult case.
I have a solution, although it applies only in a certain set of circumstances. Your case may or may not be right for this.
Create a table called ALMANAC with one row for every valid date. You can populate it with ten years of valid dates with only 3,653 rows, more or less. Even if you go for a hundred years, that's still only 36,525 rows, not too terribly big by today's standards.
You can add strange company specific attributes to this table if it's useful. These are attributes like whether the date is a company specific holiday or not, and what fiscal week, fiscal month, fiscal quarter, and fiscal year the date belongs to.
You'll have to write a program to populate this table, and this program will have to have your company specific calendar rules embedded, if you choose the extra attributes.
Then, you can use this table just like you would use any code validation table. You may also be able to use it to make quirky calendar driven reporting criteria absolutely trivial to implement.
This is only a good idea if your dates are limited to a limited time span, like ten years or maybe even a hundred years. But sometimes, it can really be a time saver! I have sometimes used this technique to make my database independent of one vendor's calendar functions.