Convert Seconds to Hours and Minutes - sql

I have read all the posts on StackOverflow about converting an integer from seconds to hours and minutes. I am using this statement to achieve the results below:
SELECT EventDate, OriginalSeconds,
LEFT(CONVERT(VARCHAR(5),
DATEADD(second, OriginalSeconds, 0), 108), 5)
I get the following result:
EventDate Seconds Converted Time SHOULD BE
01/13/2011 4860001 06:00 13:30
01/13/2011 4860001 06:00 13:30
01/14/2013 3960001 20:00 11:00
02/03/2011 3960001 20:00 11:00
The only problem, of course, is that the converted Time column has not been calculated correctly. (I placed the correct result in the SHOULD BE column for your re:.)
I am imagining that it is because the seconds column actually has extraneous data at the end. But isn't the LEFT function fixing that?
The SHOULD BE column is what I would like to achieve. What am I doing wrong? I was looking for a simple solution without a function, but not sure I can achieve that.

The correct statement (using your code) is
SELECT EventDate, OriginalSeconds,
LEFT(CONVERT(VARCHAR(5),
DATEADD(second, OriginalSeconds/100, 0), 108), 5)
This gives 13:30 for 4860001
You needed to tell us what part of the original OriginalSeconds column wasn't seconds.
DATEADD(second, #secs/100, 0) turns 4860001 into 1900-01-01 13:30:00.000
CONVERT(VARCHAR(5), 1900-01-01 13:30:00.000, 108) turns it into 13:30
The Left Is probably not needed. I just tried it with 9000001 and got a result of 01:00. So the formula wraps to 24 hours

Related

SQL get last hour from given hour

I wish, from a given date, to be able to have the last hour "round". For example, if it's 8:49 am, I would like a variable to take the value 8:00 am.
Any idea on how to do it ?
You may try offsetting the input by the difference to the start of the hour:
SELECT DATEADD(hour, DATEDIFF(hour, 0, '2020-07-10 08:49:00'), 0);
This returns:
2020-07-10 08:00:00.000

Calculate difference between dates in SQL using datetime fields without converting to char/varchar

I'm currently looking at finding time differences between dates and outputting to hours (00:00). However, I'm then going on to sum this calculation which means I can't convert to char/varchar.
Please see example data below how I would like it to appear.
EMPLOYEE_ID Start End Duration
1 05/06/2015 08:30 05/06/2015 12:12 03:42
1 05/06/2015 13:18 05/06/2015 17:00 03:42
1 06/06/2015 08:30 06/06/2015 12:12 03:42
1 06/06/2015 13:18 06/06/2015 17:00 03:42
Current code for Duration:
CONVERT(varchar(5),DATEADD(minute,DATEDIFF(minute,Start, End),0), 114) as Duration
Obviously, this code is not how I want it as it's varchar and I'd like to go on to sum two durations together. I have looked around but can't find anything which shows how this would be done.
Calculate the duration in minutes:
select datediff(minute, start, end) as duration_min
. . .
This is much easier to work with. Then sum the minutes:
select sum(datediff(minute, start, end)) as duration_min
I would recommend leaving it like this. But if you want it in HH:MM format, then manually convert to a string of the format you want.
Don't use a time data type. It is limited to 24 hours.
SQL Server doesn't currently supoort the ANSI SQL INTERVAL data type so about the best you can do to support aggregation is calculate the duration in a consistent unit of measure (like minutes you used here) and then use the aggregation result to calculate the interval from a fixed datetime value. Although the example below uses the FORMAT function to convert the result to a string, I suggest formatting for display purposes be done in the presentation layer rather than T-SQL.
CREATE TABLE dbo.EmployTimeRecord (
EMPLOYEE_ID int NOT NULL
, StartTime smalldatetime NOT NULL
, EndTime smalldatetime NOT NULL
, DurationMinutes AS DATEDIFF(minute, StartTime, EndTime)
);
INSERT INTO dbo.EmployTimeRecord(EMPLOYEE_ID, StartTime, EndTime)
VALUES
(1, '2015-05-06T08:30:00', '2015-05-06T12:12:00')
, (1, '2015-05-06T13:18:00', '2015-05-06T17:00:00')
, (1, '2015-05-06T08:30:00', '2015-05-06T12:12:00')
, (1, '2015-05-06T13:18:00', '2015-05-06T17:00:00');
SELECT
EMPLOYEE_ID
, FORMAT(DATEADD(minute, SUM(DurationMinutes), ''), 'HH:mm') AS Duration
FROM dbo.EmployTimeRecord
GROUP BY EMPLOYEE_ID;

T-SQL : convert(datetime) to include/exclude certain hours

Using date range to select values, but also need to use an hour range to determine if a record should be selected. The date ranges and time ranges are not necessarily associated.
game_time (between 6 am and 6 pm)
have tried straight between statement and datepart, but cannot get anything to capture what we need.
create table gametime(name varchar, start_time datetime, end_time datetime)
insert assorted name, start_times and end_times
Desired results
name start_time end_time
name1 8:00 AM 10:00 AM
name2 8:00 AM 11:30 AM
name3 4:00 PM 5:30 PM
name4 6:00 PM 9:00 PM
datetime is used is storage, but not needed in presentation.. only times are needed in presentation.
Selected games should only start between the hours of 6:00 AM and 6:00 PM.
Any and all suggestions and insight appreciated......
Using
LTRIM(RIGHT(CONVERT(VARCHAR(20), start_time, 100), 7))
to get the correct format for presentation,
but when I try to use
LTRIM(RIGHT(CONVERT(VARCHAR(20), start_time, 100), 7)) > 6
I get conversion errors.
I would use DATEPART rather than relying on converting to/comparing strings:
WHERE DATEPART(hour,start_time) BETWEEN 6 AND 18
Try CONVERT(VARCHAR(5),start_time,108) BETWEEN '06:00' AND '18:00'. Right now you're trying to compare a string to an integer.
Here's another way, provided you're on SQL Server 2008 or higher and have the TIME type available:
SELECT *
FROM gametime
WHERE CAST(start_time AS TIME) BETWEEN '06:00:00' and '18:00:00'
This can be a bit more flexible when your time range is not anchored to exact hours. It also is sarg-able -- i.e. it will use an index, where calling DATEPART will prevent that.

t-sql convert datetime to time only with NO SECONDS

There are many t-sql CONVERT strings to produce quite a variety of date and or time strings. But I cannot find the solution to needing no date and no seconds.
We want to return the time only from a datetime field, and eliminate the seconds. It would not matter if the seconds were truncated or rounded, but we need to show no seconds.
desired results- from any DATETIME field
10:00 AM
11:00 AM
4:59 PM
any and all insights or suggestions appreciated!!
Would this do it?
select CONVERT(varchar(15),CAST(GETDATE() AS TIME),100)
Just change out GETDATE() with your date variable.
Try this:
SELECT LTRIM(RIGHT(CONVERT(VARCHAR(20), GETDATE(), 100), 7))
Put your DATETIME field instead GETDATE()
If you want a space then the AM /PM try this:
SELECT
Left(CONVERT(varchar(15),CAST(GETDATE() AS TIME),100),(len(CONVERT(varchar(15),CAST(GETDATE() AS TIME),100))-2)) +' ' + right((CONVERT(varchar(15),CAST(GETDATE() AS TIME),100)),2) as NiceTimeAMPm
NiceTime
7:35 AM
3:00 PM

Sql query to get range of values

I have a table called TimeList
SlotID SlotStartTime SlotEndTime
(int identity) (varchar(10)) (varchar(10))
1 8:00AM 8:15AM
2 8:15AM 8:30AM
3 8:30AM 8:45AM
4 8:45AM 9:00AM
5 9:00AM 9:15AM
6 9:15AM 9:30AM
7 9:30AM 9:45AM
8 9:45AM 10:00AM
If I am passing SlotStartTime and SlotEndTime I want to get times in between.
I used the following query to get timeslots in b/w slotStarttime 8:00AM amd slotEndTime 9:00AM
select * from TimeList1 where StartTime >='8:00AM' and EndTime <= '9:00AM'
Here the result is coming as:
SlotID SlotStartTime SlotEndTime
1 8:00AM 8:15AM
2 8:15AM 8:30AM
3 8:30AM 8:45AM
8 9:45AM 10:00AM
I want to get slotstarttime starting from 8:00AM and slotendtime ending 9:00AM means
expected result is:
SlotID SlotStartTime SlotEndTime
1 8:00AM 8:15AM
2 8:15AM 8:30AM
3 8:30AM 8:45AM
4 8:45AM 9:00AM
What change do I have to make in my query to get the result as above?
When you're using varchars (or strings in most languages), you'll find that "10:00" < "9:00" just because of character sequencing rules (since "1" < "9").
You should be storing date and time values in date and time columns. If you must use varchars, you'll need to convert them to fixed-size 24-hour format to do it properly (e.g., "01:30", "12:15", "18:25").
But my advice is to store them as proper DB date and time values. Your queries will be easier and faster.
The following solution may get you what you want if I understand your data storage (one entry per quarter hour) but my professional opinion is to fix the column types, since that will allow for far more expressive conditions in your select statements:
select * from TimeList1
where left(StartTime,1) = '8'
and right(StartTime,2) = 'AM'
Part of the problem, as has been noted, is that you are using strings to represent times. The other part of your problem is that the AM/PM notation is completely ghastly for computational purposes. Remember, the sequence is:
12:00AM
12:15AM
12:30AM
12:45AM
1:00AM
1:15AM
...
9:45AM
10:00AM
10:15AM
...
11:30AM
11:45AM
12:00PM
12:15PM
12:30PM
12:45PM
1:00PM
1:15PM
...
The 24-hour clock has many merits. If you used:
00:00
00:15
00:30
00:45
01:00
01:15
...
09:45
10:00
10:15
...
11:30
11:45
12:00
12:15
12:30
12:45
13:00
13:15
...
(for the same set of numbers) then your VARCHAR strings could be made into CHAR(5) and would automatically sort correctly in time sequence. You would still have to phrase your queries correctly, including the leading zero(es) on times less than 10:00, but the values would sort correctly and compare correctly.
Some DBMS provide support for sub-sets of time. In IBM Informix Dynamic Server, you could use DATETIME HOUR TO MINUTE as the type for the column. That would give you back the flexibility of dropping leading zeroes.
See also Convert 12-hour date/time to 24-hour date/time.
Your query is correct. But it's your data types that are wrong.
10:00AM indeed comes before 9:00AM considering they are string, not datetime values.
So if you can't change the data types now, your best luck is to try this query :
Select * from TimeList1
where StartTime >= Cast('8:00AM' as datetime)
and EndTime <= Cast('9:00AM' as datetime)
//make sure StartTime and EndTime is type of datetime
Try this:
SELECT *
FROM TimeList1
WHERE (CONVERT(datetime, CONVERT(varchar, GETDATE(), 103) + ' ' + StartTime) >=
CONVERT(datetime, CONVERT(varchar, GETDATE(), 103) + ' ' + '8:00AM'))
AND
(CONVERT(datetime, CONVERT(varchar, GETDATE(), 103) + ' ' + EndTime) <=
CONVERT(datetime, CONVERT(varchar, GETDATE(), 103) + ' ' + '9:00AM'))
select *
from TimeList1
where StartTime >= '8:00AM'
and EndTime <= '9:00AM'
Less than or equal, not greater than or equal.
Though really, that doesn't work like you expect when your columns are of type varchar. Use a time or datetime type.
The first two paragraphs don't explain a thing as far as I can see. The last paragraph contains a flimsy explanation of the problem. – Jonathan Leffler
In the original post, before you edited it, the OP had as his select statement,
select *
from TimeList1
where StartTime >= '8:00AM'
and EndTime >= '9:00AM'
I was responding to that.
My response may be "flimsy", but I wanted to address the obvious problem and get the guy moving forward.