Convert 12 hours to 24 hours from varchar column in SQL Server - sql-server

In my existing SQL Server database, there is a column like this:
Column name and type: meeting_time varchar(22)
Values stored: 02:30:PM
Now I want to convert it into 24 hours format. i.e., it should convert to 14.30
When I tried this:
SELECT
CONVERT(VARCHAR(8), meeting_time, 1)
FROM
group_info
WHERE
MGI_Id = 1
It will return the same value which stored in this column. When I tried with converting it into time or datetime, it throws exception.
Can anyone please help me!
Thanks in advance.

This should work:
select convert(time, stuff(meeting_time, 6, 1, ' '))
Not sure if it works with all locales / languages, so you should check that first.
This assumes that your date is always in the same format, that the extra : is in the 6th character.

Related

string to date conversion issue SQL

I am having an issue with the conversion below:
I am using two main tables client and cli-identifier(this holds the information column)
I have a column in cli-identifier table called information currently holding dates in two ways (only thing changing is the date value):
First: 22/11/16 * Company info A/C
Second: 22/11/2016 * Company info A/C
I use the following query to slice the information out of the column:
left(Substring(ci.information, charindex('[0-9]',ci.information),103)
,charindex('*',ci.information + '*')-2) as datereceived
After which I am receving the follow strings:
example of the two different types showing
22/11/16
22/11/2016
I require these converted date/time or just date but unable to do so with the following code (I have also tried using cast to do this too):
convert(date,left(Substring(ci.information, charindex('[0-9]',ci.information),103),
charindex('*',ci.information + '*')-2),1) as datereceived
Other methods I have tried is to convert this into a temp table and then using the following to cast the date.
select
cast (t AS date()
from #a
I know the confliction lies in the date value being formatted as 22/11/16 any input would be helpful. Only solution I think of is adding to a temp table and making a query to insert the '20' value infront of the 22/11/16 year.
if you are using SQL Server, you can do this, just detect for length of the date string and use style 3 or 103
select CONVERT( DATETIME , '22/11/16', 3),
CONVERT( DATETIME , '22/11/2016', 103)
Okay thank you.
I added the following to count for length of strings.
case when len(left(Substring(ci.information, charindex('[0-9]',ci.information),103),charindex('*',ci.information + '*')-2)) >= 10
then convert(date,left(Substring(ci.information, charindex('[0-9]',ci.information),103),charindex('*',ci.information + '*')-2),103)
else convert(date,left(Substring(ci.information, charindex('[0-9]',ci.information),103),charindex('*',ci.information + '*')-2),3)
end as datereceived
Regards,

Convert One Datetime format to another in SQL Server

I have a datetime2 format in my Database 2015-06-22 06:23:42.790. I need to convert this into the following format 22/06/2015 06:23:42.790.
Is it possible?
Here is one way to do this:
DECLARE #date DATETIME2 = '2015-06-22 06:23:42.790';
SELECT cast(convert(VARCHAR(10), cast(LEFT(#date, 10) AS DATE), 3) AS VARCHAR(10))
+ ' ' + substring(cast(#date AS VARCHAR(50)), 12, 12)
Query breakdown:
First part: take first 10 characters from your datefield and then convert it to date style 3 (dd/mm/yyyy).
Second part: Add a space between date and time.
Third part: cast your datefield as varchar and extract the time which should always start in the 12th position of your string.
Join them all together and there you have it! Hope this helps!
Don't try to convert the database layout. Year Month Day is how SQL server shows the date because it ignores any international date formats.
I notice you want it as 22/06/2015 are you in the UK ? In the USA it would be 06/22/2015 Not such a problem because it's obvious that the 22 is the day. But if the date was 05/06/2015 how would sql or anyone know what day or month you're talking about.
So, get in to the habit of working in the ISO format year month day.
You don't mention what programming language. When reading data out of the database youd read it into a datetime variable. That will convert the date correctly into whatever locale your user is using. Different languages have different ways of getting the date into a datettime variable.
If it's only for display-use you can convert to varchar with FORMAT() function:
DECLARE #tab TABLE
(
datevalue DATETIME2
)
INSERT INTO #tab VALUES(GETDATE())
SELECT datevalue,
FORMAT(datevalue,'dd/MM/yyyy hh:mm:ss.fff') as newformat
FROM #tab

C, unixODBC, oracle and Date queries

I've got a query like
select x from tableName where startDate <= now;
When i query the database without the date fields, everything works as expected. As soon as i start using date or timestamp columns in the oracle Database, my queries return nothing or an error.
What I do:
snprintf(sql, sizeof(sql), "SELECT roomNo, userPass, adminPass, adminFlags, userFlags, bookId, is_locked, running_on_server FROM booking WHERE roomNo = '?' AND startTime <= { ts '?' } AND endTime >= { ts '?' } for update;");
stmt = ast_odbc_prepare_and_execute(obj, generic_prepare, &gps);
the ? will be replaced by values, with following command:
SQLBindParameter(stmt, i + 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(gps->argv[i]), 0, gps->argv[i], 0, NULL);
when I execute the query I get an error that TS is an invalid identifier [this was a recommendation by another board, taken from msdn - which may cause this error]
but even if I remove it and send just a string to the database, I'll get an empty result back. I also tried to bind the parameters as SQL_TIMESTAMP and SQL_DATE, but this didn't help either.
Hopefully somebody can help me.
thanks in advance.
Chris
Are you sending a DATE data type to the Oracle query or a date represented in a string?
From the Oracle side of things, if you send a date in a string variable you'll need to use the oracle "TO_DATE" function (http://www.techonthenet.com/oracle/functions/to_date.php) to then convert thew string back to a date for use in your SQL statement (assuming startDate or startTime/endTime are DATE columns in the database).
Your fist SQL example should be:
SELECT x
FROM tableName
WHERE startDate <= TO_DATE(now, '<date-format>');
If the variable "now" was a string containing '05-OCT-2011 16:15:23' (including a time portion) then the to_date would be:
TO_DATE(now, 'DD-MON-YYYY HH24:MI:SS')
If you compare a string with a date and don't specify the format of that date Oracle will use its default NLS parameters and try to apply that format. Therefore it is always prudent to specify the date format using TO_DATE.
Hope it helps...

unable to convert varchar to date in sql server

in my data a column called 'duedate' which is in the varchar(5) format has dates stored in the following format '20110725' for 25th july 2011, is there a way in which i can convert this to date format
i tried using
cast(duedate as datetime)
which did not work
then i tried to convert it to bigint and then to datetime
cast( cast(duedate as bigint) as datetime)
which said
arithematic overflow error
Sorry for the confusion it was varchar(50) - typo error, and thanks a lot for the help ill try the things you guys mentioned
If the column is really varchar(5), then it can't have values like '20110725', because that would be 8 characters.
Maybe the values were truncated when they were inserted?
'20110725' shortened to 5 characters becomes '20117', and converting that won't work.
I guess the problem is something like that, because as Mladen Prajdic already said, converting '20110725' to datetime works perfectly.
Please see this table of valid date-time conversion codes. The code you will need is 112 which converts from yyyymmdd format.
CONVERT (datetime, duedate, 112)
how didn't it work? doing SELECT cast('20110725' as datetime) works perfectly for me.
Try running this on your table to find the values that aren't dates:
SELECT duedate
FROM your_table
WHERE ISDATE(duedate) = 0;
Like Christian said, a VarChar(5) won't be able to hold the value you're expecting it to either.

Average a time value in SQL Sever 2005

I've got a varchar field in SQL Sever 2005 that's storing a time value in the format "hh:mm"ss.mmmm".
What I really want to do is take the average using the built in aggregate function of those time values. However, this:
SELECT AVG(TimeField) FROM TableWithTimeValues
doesn't work, since (of course) SQL won't average varchars. However, this
SELECT AVG(CAST(TimeField as datetime)) FROM TableWithTimeValues
also doesn't work. As near as I can tell, SQL doesn't know how to convert a value with only time and no date into a datetime field. I've tried a wide variety of things to get SQL to turn that field into a datetime, but so far, no luck.
Can anyone suggest a better way?
SQL Server can convert a time-only portion of a datetime value from string to datetime, however in your example, you have a precision of 4 decimal places. SQL Server 2005 only recognizes 3 places. Therefore, you will need to truncate the right-most character:
create table #TableWithTimeValues
(
TimeField varchar(13) not null
)
insert into #TableWithTimeValues
select '04:00:00.0000'
union all
select '05:00:00.0000'
union all
select '06:00:00.0000'
SELECT CAST(TimeField as datetime) FROM #TableWithTimeValues
--Msg 241, Level 16, State 1, Line 1
--Conversion failed when converting datetime from character string.
SELECT CAST(LEFT(TimeField, 12) as datetime) FROM #TableWithTimeValues
--Success!
This will convert valid values into a DATETIME starting on 1900-01-01. SQL Server calculates dates based on 1 day = 1 (integer). Portions of days are then portions of the value 1 (i.e. noon is 0.5). Because a date was not specified in the conversion, SQL Server assigned the value of 0 days (1900-01-01), which accommodates our need to average the time portion.
To perform an AVG operation on a DATETIME, you must first convert the DATETIME to a decimal value, perform the aggregation, then cast back. For example
SELECT CAST(AVG(CAST(CAST(LEFT(TimeField, 12) as datetime) AS FLOAT)) AS DATETIME) FROM #TableWithTimeValues
--1900-01-01 05:00:00.000
If you need to store this with an extra decimal place, you can convert the DATETIME to a VARCHAR with time portion only and pad the string back to 13 characters:
SELECT CONVERT(VARCHAR, CAST(AVG(CAST(CAST(LEFT(TimeField, 12) as datetime) AS FLOAT)) AS DATETIME), 114) + '0' FROM #TableWithTimeValues
Try this
AVG(CAST(CAST('1900-01-01 ' + TimeField AS DateTime) AS Float))
You really should store those in a datetime column anyway. Just use a consistent date for that part (1/1/1900 is very common). Then you can just call AVG() and not worry about it.
I used Cadaeic's response to get an answer I was looking for, so I thought I should share the code....
I was looking for a query that would average ALL my times together and give me an overall Turn Around Time for all approvals. Below is a nested statement that gives you the AVG TAT for individual id's and and when nested an overall TAT
SELECT
-- calculates overall TAT for ALL Approvals for specified period of time
-- depending on parameters of query
CONVERT(VARCHAR, CAST(AVG(CAST(CAST(LEFT(Tat_mins, 12) as datetime) AS FLOAT)) AS DATETIME), 108) + '0'
from
(
-- tat is for individual approvals
SELECT
dbo.credit_application.decision_status,
dbo.credit_application.application_id,
cast(dbo.credit_application.data_entry_complete as date) as'Data Entry Date',
cast(dbo.credit_application.decision_date as DATE) as 'Decision Date',
avg(datediff(minute, dbo.credit_application.data_entry_complete, dbo.credit_application.decision_date)) as 'TAT Minutes',
convert (char(5), DateAdd(minute, Datediff(minute,dbo.credit_application.data_entry_complete, dbo.credit_application.decision_date),'00:00:00'),108) as 'TAT_Mins'
FROM dbo.credit_application
where Decision_status not in ('P','N')
group by dbo.credit_application.decision_status,
dbo.credit_application.data_entry_complete,
dbo.credit_application.decision_date
--dbo.credit_application.application_id
)bb
How do you think to average on datetime?
I guess that you need to GROUP BY some period (Hour?), and display Count(*)?
SQL Server stores datetime data as 2 4-byte integers, hence a datetime take 8 bytes. The first is days since the base date and the second is milliseconds since midnight.
You can convert a datetime value to an integer and perform mathematical operations, but the convert only returns the "days" portion of the datetime value e.g. select convert(int,getdate()). It is more difficult to return the "time" portion as an integer.
Is using SQL Server 2008 an option for you? That version has a new dedicated time data type.
Thanks, Andy.
I'd work out the difference between all of the dates and an arbitrary point (01/01/1900), average it and then add it back on to the arbitrary point.

Resources