SQL Convert Military time to Time - sql

I have a sql database where clock in times are displayed as military time, but in number format. E.g. 907 is 09:07am, or 1514 is 15:14pm
Is there any way of converting this in SQL?
Currently I output into excel and use the below formula to calculate but would prefer to do all this in SQL
TIMEVALUE(LEFT(IF(LEN(L30)=4,L30,CONCATENATE(0,L30)),2)&":"&MID(IF(LEN(L30)=4,L30,CONCATENATE(0,L30)),3,2)&":"&RIGHT(IF(LEN(L30)=4,L30,CONCATENATE(0,L30)),2))
Any help you be appropriated
Thanks

If you want the output as a time value:
select convert(time, dateadd(second, t/100 * 60 + t % 100, 0))
from (values (907), (1514)) v(t);
If you just want a string returned:
select stuff(right('0' + convert(varchar(255), t), 4), 3, 0, ':')
from (values (907), (1514)) v(t);

Related

SQL solution to extract total number of hours from a string column

I have a varchar(255) column in table1:
time
--------------------------
Monday|10:00-18:00
Tuesday|10:00-16:00
Friday|10:00-20:00
How do I extract the number of hours from the above column using SQLite? I tried using varchar() and datetime() none of which worked. Should I be using regex to get the time?
Thank you in advance.
You can extract the time values using:
select substr(time, -11, 5), substr(time, -5)
You can then use julianday() to get the difference in seconds (or any other unit):
select round((julianday(substr(time, -5)) - julianday(substr(time, -11, 5))) * 60 * 60 * 24) as seconds_diff
from t;
Here is a db<>fiddle.

I have column x in hh:mm format of datatype varchar in SQL Server and I want to perform sum on that 'x' column

I have column x in hh:mm format of datatype varchar in SQL Server and I want to perform sum on that x column.
I created a user-defined function to convert total min into hh:mm format.
Then I tried to perform sum to calculate total duration:
sum(cast(new_totalmin AS Int))
also i want total of HH:mm exactly as example
4:20
+1:10
5:30
5 hour: 30 minute
or i can do one thing here insted hh:mm i keep column as it is which is totalmin as int once sum cal insted of hh:mm (hh.mm which is in decimal also ok for me PSB it will be ok for me ':' or '.' format )
(60 min --> 1:00 --> 1.00
90 min --> 1:30 -->1.30
---------------------------------
sum --> 150 min -->2:30 --> 2.30)
but it did not work.
I got an error like
Conversion failed when converting the varchar value '01:00' to data type int
DECLARE #SampleData AS TABLE (HourMinutes VARCHAR(10));
INSERT INTO #SampleData VALUES ('4:32');
INSERT INTO #SampleData VALUES ('5:28');
INSERT INTO #SampleData VALUES ('6:00');
INSERT INTO #SampleData VALUES ('7:10');
SELECT * FROM #SampleData
SELECT SUM(datediff(minute, 0, HourMinutes)) TotalMinute
FROM #SampleData
You will get following output
hh:mm is a varchar data and applying SUM will not work on it.
As you are telling that you are already having a function, I would suggest you to perform sum of the minutes and then later convert them to hh:mm
SELECT ... , YourUserDefinedFunction(sum(minuteData)) as minutesInHHMM_Format
FROM ...
WHERE ...
GROUP BY ...
I would recommend that you store numeric values -- such as the number of minutes -- as a number rather than a string.
The challenge is converting the value back to an HH:MM format. SQL Server does not support time values of 24 hours or greater, so you need to use string manipulations.
Assuming that your values are all less than 24 hours, you can use:
select sum(datediff(minute, 0, hhmm)) as num_minutes,
concat(sum(datediff(minute, 0, hhmm)) / 60, ':',
format(sum(datediff(minute, 0, hhmm)) % 60, '00')
)
from t;
The result here is a string, so this can exceed 24 hours.
A more general solution eschews date/times altogether:
select sum(v.minutes) as num_minutes,
concat(sum(v.minutes) / 60, ':',
format(sum(v.minutes) % 60, '00')
)
from t cross apply
(values (left(t.hhmm, charindex(':', t.hhmm) - 1) * 60 + right(t.hhmm, 2))
) v(minutes);
Here is a db<>fiddle.

How do I convert a 5 or 6 digit decimal to a date in sql

I've got a column that shows the date as a decimal such as 101118 for 10-11-18 and 90118 for 09-01-18. I am trying to create a simple report that would give me all reservations yesterday.
So for example
Select playerid, datereservationmade
from dbo.lms
normally there is very simple and I would just do
Select playerid, datereservationmade
from dbo.lms
where datereservationmade >= dateadd(day,datediff(day,1,GETDATE()),0)
AND datereservationmade < dateadd(day,datediff(day,0,GETDATE()),0)
That does not work in this case because the datereservationmade field is a decimal and if its a month 1-9 it leaves off the 0 and makes it a 5 digit decimal then if its 10-12 it is a 6 digit decimal.
Someone please help me figure out how to convert this!
If at all possible, you really should fix your schema so that dates are actually being stored as dates.
If you need to work with the decimal data type, you can use something like the following...
IF OBJECT_ID('tempdb..#TestData', 'U') IS NOT NULL
BEGIN DROP TABLE #TestData; END;
CREATE TABLE #TestData (
decimal_date DECIMAL(6, 0) NOT NULL
);
INSERT #TestData (decimal_date) VALUES (101118), (90118), (101718);
--==============================================
SELECT
td.decimal_date,
dd.date_date
FROM
#TestData td
CROSS APPLY ( VALUES (RIGHT('0' + CONVERT(VARCHAR(6), td.decimal_date), 6)) ) cd (char_date)
CROSS APPLY ( VALUES (CONVERT(DATE, STUFF(STUFF(cd.char_date, 5, 0, '/'), 3, 0, '/'), 1)) ) dd (date_date)
WHERE
dd.date_date = CONVERT(DATE, DATEADD(DAY, -1, GETDATE()));
Convert the decimal to varchar(6) by adding a zero in front and getting the RIGHT 6 characters.
Then convert the string to a date from its parts, which are substrings in your varchar(6). This is made easier in SQL Server 2012 with the DATEFROMPARTS function.
Using the DATEFROMPARTS, as Tab Alleman suggested, you might get something like this:
-- Example of the arithmetic
SELECT 101118 / 10000 AS Month, (101118 % 10000) / 100 AS Day, (101118 % 100) AS Year
-- Using the math in DATEFROMPARTS
SELECT DATEFROMPARTS((101118 % 100) + 2000, 101118 / 10000, (101118 % 10000) / 100 )
However, I'm skeptical that you've provided all the correct information. What happens on January first? Your decimal value won't start with zero (as you stated). Will your day always pad with zero? If not, then 1119 won't produce the same result as 10119. If, however, your day does start with zero, then the equation above should work fine.

Trouble converting from time to decimal time

Part of the task I have been given involves performing calculations on a few columns, 2 of which are in the format of hh.mi.ss and they're varchar. In order for the calculations to work, I need to get them into a time decimal format, whereby 1:30 would be 1.5 . Since I'm currently using SQL Server 2005, I don't have the time or data types built-in and I'm unable to get an upgraded version (not my choice). Working with what I have, I've searched around online and tried to convert it but the result isn't accurate. For example, 13.28 becomes (roughly) 13.5, which is great, however, the seconds go to 100 instead of ending at 60 (since I'm converting it to a float).
For example, using 12.57.46,
CAST(DATEPART(HH, CAST(REPLACE([OASTIM], '.', ':') AS DATETIME)) AS FLOAT) +
(CAST(DATEPART(MI, CAST(REPLACE([OASTIM], '.', ':') AS DATETIME)) AS FLOAT)/60) +
(CAST(DATEPART(SS, CAST(REPLACE([OASTIM], '.', ':') AS DATETIME)) AS FLOAT)/3600)
gave me 12.962...
whereas
CAST(SUBSTRING([OASTIM], 1, 2) AS FLOAT) +
((CAST(SUBSTRING([OASTIM], 4, 5) AS FLOAT) +
CAST(SUBSTRING([OASTIM], 7, 8) AS FLOAT)/60)/60)
gave me 12.970....
and when I tried something simpler,
DATEPART(HOUR, CAST(REPLACE([OASTIM], '.', ':') AS DATETIME))+
(DATEPART(MINUTE, CAST(REPLACE([OASTIM], '.', ':') AS DATETIME))/60)
flopped out and gave me only 12
It's my first exposure to Windows SQL and T-SQL, I've been struggling with this for a few hours. As horrible as it sounds, I'm at the point where I'd be happy with it working even it it means sacrificing performance.
You don't explain what "time decimal" format is. From your example, I'll guess that you mean decimal hours.
A key function in SQL Server for date differences is datediff(). You can convert the time to seconds using a trick. Add the time to a date, then use datediff() to get the number of seconds after midnight. After that, the conversion to decimal hours is just arithmetic.
Here is an example:
select datediff(second,
cast('2000-01-01' as datetime),
cast('2000-01-01 ' + '00:00:59' as datetime)
)/3600.0 as DecimalHours
Note the use of the constant 3600.0. The decimal point is quite important, because SQL Server does integer division on integer inputs. So, 1/2 is 0, rather than 0.5.
You said,
CAST(SUBSTRING([OASTIM], 1, 2) AS FLOAT) +
((CAST(SUBSTRING([OASTIM], 4, 5) AS FLOAT) +
CAST(SUBSTRING([OASTIM], 7, 8) AS FLOAT)/60)/60)
gave me 12.970....
12.970 is wrong for an input of '12.57.46'. The problem is that you are using the SUBSTRING function incorrectly. The 3rd argument represents the number of characters, not the ending character position.
Take a look at this code:
Declare #Sample varchar(20)
Set #Sample = '12.57.46'
select CAST(SUBSTRING(#Sample, 1, 2) AS FLOAT) +
CAST(SUBSTRING(#Sample, 4, 5) AS FLOAT) / 60 +
CAST(SUBSTRING(#Sample, 7, 8) AS FLOAT) / 60 / 60,
SUBSTRING(#Sample, 1, 2),
SUBSTRING(#Sample, 4, 5),
SUBSTRING(#Sample, 7, 8),
CAST(SUBSTRING(#Sample, 1, 2) AS FLOAT) +
CAST(SUBSTRING(#Sample, 4, 2) AS FLOAT) / 60 +
CAST(SUBSTRING(#Sample, 7, 2) AS FLOAT) / 60 / 60
Notice that the minutes is coming out as 57.46 because you are asking for 5 characters. The seconds are coming out correctly because eventhough you are asking for 8 characters, there are only 2 characters left in the string so only those 2 characters are returned.
BTW, I would solve this problem the same way that Gordon did, except I would remove the date stuff so it would look like this:
Select DateDiff(Second,
0,
Convert(DateTime, Replace([OASTIM], '.',':'))) / 3600.0
Here is a simple way to convert time to DecimalHours.
SELECT cast(cast('12.57:46' as datetime) as float) * 24
Result:
~12.963

Converting Milliseconds to Days, hours, minutes and seconds

i have a bigint field in Microsoft SQL Server 2008R2 filled with ticks (A single tick represents one hundred nanoseconds or one ten-millionth of a second. There are 10,000 ticks in a millisecond.)
http://msdn.microsoft.com/en-us/library/system.datetime.ticks.aspx
and i need to convert the sum of all records to Days:Hours:Minutes:Seconds:Milliseconds.
it works for a single record:
SELECT CONVERT(TIME, DATEADD(ms, duration/10000, 0)) FROM tblMediaFileProperties WHERE FileId = '6C0A849D-95B4-4755-A923-B9DD8F1AF23E'
but if a sum it up to all records using:
SELECT CONVERT(TIME, DATEADD(ms, SUM(duration/10000), 0)) FROM tblMediaFileProperties
i get a:
Arithmetic overflow error converting expression to data type int.
i know the overflow comes from the CONVERT to Data Type TIME Function...
help's appreciated, thanks!
It's too big for DATEADD which only accepts an int.
Break it into two parts: seconds, then milliseconds.
SELECT CONVERT(TIME,
DATEADD(ms, SUM(duration/10000 % 1000),
DATEADD(ss, SUM(duration/10000000), 0)))
FROM tblMediaFileProperties
And if your total duration goes above 1 day, you can use this to get the days and hr:min:sec:ms separately. It's a matter of cast and string concat if you actually want the result in textual form.
declare #duration bigint
set #duration = 1230000000
SELECT #duration/10000/1000/60/60/24 DAYS,
CONVERT(TIME,
DATEADD(ms, SUM(#duration/10000 % 1000),
DATEADD(ss, SUM(#duration/10000000), 0))) HR_MIN_SEC