I have plenty of columns with timestamps in the following nvarchar format '2016-11-22T20:16:32.573000Z' or 'yyyy-MM-ddThh:mm:ss.[sss]Z' and I need to convert the column type into date and time format.
I know there have been many questions asked about converting string to datetime conversions in SQL Server (Azure) using CAST or CONVERT. But I seem to be unable to identify the right style:
CONVERT ( data_type [ ( length ) ] , expression [ , style ] )
The format looks like ISO 8601 style but e.g. style numbers 126 and 127 don't see to work. So which style should I use to be able to successfully convert the column?
That format is unambiguous but has more digits of precision than datetime can accommodate.
CONVERT(datetime2,'2016-11-22T20:16:32.573000Z') works fine without specifying a style, and you should be avoiding datetime in new work anyway. (Specifying styles 126 or 127 at this point is also fine if you want to, but unnecessary)
Don't know if an update SQL statement with something like this in it might help to populate a new date field and a new time field:
SUBSTRING(MyLongDateTimeStringField,1,10) AS MyNewDateField,
SUBSTRING(MyLongDateTimeStringField,12,8) AS MyNewTimeField
Related
I think it's no doubt that in sql "2019-10-30" is valid date format, and looks like "2019/10/30" accepted as well.
What about "10-30-2019" and "10/30/2019"?
I tried them in mariaDB and they're wrong format, but somehow I think I did see them in some sql tables. Please help me clarify the date format. Thanks
In MariaDB, the format for dates is yyyy-mm-dd. But MariaDB is quite lax and other formats are accepted; from the documentation:
A DATE string is a string in one of the following formats: 'YYYY-MM-DD' or 'YY-MM-DD'. Note that any punctuation character can be used as delimiter. All delimiters must consist of 1 character. Different delimiters can be used in the same string. Delimiters are optional (but if one delimiter is used, all delimiters must be used).
A DATE literal can also be an integer, in one of the following formats: YYYYMMDD or YYMMDD.
All the following DATE literals are valid, and they all represent the same value:
'19940101'
'940101'
'1994-01-01'
'94/01/01'
'1994-01/01'
'94:01!01'
19940101
940101
So, for the examples that you provided:
2019-10-30 -- ok: default format
2019/10/30 -- ok: format with alternative delimiter
10-30-2019 -- NOT ok
10/30/2019 -- NOT ok
You can translate a string to a date with function str_to_date().
str_to_date('10-30-2019', '%m-%d-%Y')
str_to_date('10/30/2019', '%m/%d/%Y')
What you are really doing is converting from a string representation of a date to an internal date time representation or data type. The format you are referring to is ISO 8601. The ISO date (2019-10-30 with hyphens or parentheses) format is usually the native or default string conversion that most databases use, that's why those formats work even if you don't specify the conversion. If you intend to convert from other formats you probably would need to specify them. Your default representation for your local settings might work too, but that depends on the specific database.
select convert (date,'27-07-2019',105)
results in 2019-07-27 while I would expect 'DD-MM-YYYY).
Why?
select convert (date,'27-07-2019',105)
You are converting to a date, which is stored and presented using the internal representation and defaults of the server.
The default presentation is YYYY-MM-DD, which is not only a SQL Server standard but also an ISO standard for representing dates. It is simply the best way to represent dates as a string (notably because it sorts correctly as a string).
If you want a bepoke string format, then convert the value to a string, not to a date.
I have a scenario to cast string date into date format. But the date string is not in a straight format, so the conversion throws error. So what I tried is
set dateformat dmy
before the casting in sql and it worked without any issue.
But the trouble is I need this to implement in a view or function. But the disappointing part, function or view doesn't support set dateformat with which it says as side effecting operator
So how can I specify the date format of the given string before casting in a function or view?
The third parameter of CONVERT() allows to provide a format type.
Assuming your SET DATEFORMAT DMY I take you've to deal with dates like "1/2/2000", meaning the first of February in 2000.
Try this:
DECLARE #d VARCHAR(100)='1/2/2000';
SELECT CONVERT(DATE,#d,104)
The 104 is the German type with a 4-digit year. If this does not fit your needs, you can follow the link to find a better suiting format.
If you need further help, please provide samples of your actual dates.
Hint: You should always store a value in a column with the appropriate type. Storing dates as strings will make things slow and opens a lot of error sources...
As Damien wrote in his comment to the question, ideally you should not mess around with string representations of datetime in the first place - you should be using proper data types - and since you asked about creating a view, it can only mean that somewhere in your database there's a datetime value stored as a string.
The solution to this situation is to change the way you are storing this value - use DateTime2 for datetime values, Date for date-only values, or Time for time-of-day values.
Further reading - Aaron Bertrand's Bad habits to kick : choosing the wrong data type
Assuming you can't change the database design, read the rest of this answer.
You can't use set dateformat on a view or a function, but you can use convert instead of cast to change the string representation of a datetime value into an actual datetime value, assuming the string representation has one of the supported date formats (there are quite a few of them, so usually it shouldn't be a problem).
If your string representation of the datetime is in a format that is not supported by the built in convert function, you might need to do some extra work in the form of string manipulation to either change it into a supported format, or (in the harder case) separate the string representation to parts and then use datetimefromparts.
If you could provide the actual format you are using in your string representation of the datetime format I can probably edit this answer to show you exactly how to do it.
SELECT CONVERT(varchar(10),CAST('07/01/2018' AS DATE),23)
Result
2018-07-01
Not sure what you mean by, "date string is not in a straight format". Examples will help.
Have you tried parsing, instead of casting?
SELECT
TRY_PARSE(thedate AS datetime) as justParse
,TRY_PARSE(thedate AS datetime USING 'en-US') as parseUS
,TRY_PARSE(thedate AS datetime USING 'en-GB') as parseGB
,try_cast(thedate as date) as tryCast
FROM (values
('07/01/2018')
,('01/07/2018')
,('07 jan 2018')
,('jan 07 2018')
,('Monday, 7 January 2019')
)d(thedate)
I have a view in SQL Server 2012 and there is a column of containing dates×. I have been trying to convert the date column as '20/10/2018 18:00' format (no second) by using this feature and lots of approaches on Stackoverflow and other web sites:
FORMAT(StartDate, 'dd.mm.yyyy hh:mm')
However, as the data type of this column is Varchar (String) rather than DateTime, I encountered some problems in C# side and I want to perform this conversion on the database side without changing the data type of the generated format). Is there any way to achieve this?
SQL Server doesn't have a "date format" per se. The formatting of datetime fields is only performed when presenting the datetime to an output - that is, when converting it to a string.
There is a default format for presentation that is controlled by the server's collation setting. However, internally the date is stored as a numeric value (actual format varies by type, as datetime and datetime2 have different internal formats), and that value has no associated formatting.
You can store your date without seconds by using a smalldatetime field, or by manipulating the input data to trim off the seconds value. But, unless you store your date as a string, which is absolutely not recommended, you will not be able to save an output format different from the default collation-driven format in a datetime field.
I would migrate that column to a datetime (or some variant) if possible. Alternatively if that would affect too many things, you could make a computed column on the table which converts the string date you have to a datetime. That way the database doesn't have to care about the formatting at all; it just works with the proper DateTime data type.
If neither of those is an option, you can just pas the string to C# and use DateTime.TryParse() to convert it to a C# DateTime object.
In either case, it's preferable to work with the date as a DateTime up until the very last minute where you need to format it for display somewhere.
I know that it is possible to reformat the DateTime data type of the current date and time by using select convert. However, I havent been able to find a method to reformat an existing column (DateTime data type) to: hh:mm:ss yyyy/mm/dd. Or even better, I would like to reformat it to show time only. I dont want to simply convert to time data type because I am working with a chart that accepts either Date or Date time. But what I really want to display on that specific axis of the chart is time. Is there any way to reformat DateTime to my requirements? Thanks.
SQL Server's convert function can take an optional style argument depending upon the datatype. This is how you can get a datetime converted to a string in a variety of formats. For example, try running:
select convert(varchar(30), getdate(), 108) -- returns hh:mi:ss
You can replace getdate() in this example with a column name as well.
There are many styles available, as shown in the documentation.
Note that you will be returning a varchar, so you may want to sort by the original column's datatype.
You can use SET DATEFORMAT but this will change all DateTime's on your SQL Server. You can do some custom formatting, but it will convert the DateTime into a VarChar, so you won't be able to treat it as a DateTime.
SET DATEFORMAT: http://msdn.microsoft.com/en-us/library/ms189491.aspx
I'm not sure if you will be able to use the format you're asking about, though.