Is there a way to preserve locale when format a datetime in SQL? [duplicate] - sql

I have an sql DateTime (ms sql server) and want to extract the same date without the seconds:
e.g. 2011-11-22 12:14:58.000 to become: 2011-11-22 12:14:00.000
How can I do this? I was thinking to use DATEADD in combination with DATEPART but seems very error prone (besides performance issues)

SELECT DATEADD(MINUTE, DATEDIFF(MINUTE, 0, yourcolumn), 0) FROM yourtable
This will be effective, if you don't want a slow conversion between datatypes.

For a solution that truncates using strings try this:
SELECT CAST(CONVERT(CHAR(16), GetDate(),20) AS datetime)
CHAR(16) works only if our variable is converted to ODBC canonical format, as shown above by using 20 as the format specifier.
DECLARE #date DateTime = '2011 Nov 22 12:14:55';
SELECT CONVERT(Char(16), #date ,20) AS datetime
Results:
| datetime |
|------------------|
| 2011-11-22 12:14 |
Then you simply cast back to a DateTime type to continue using the value.
NOTE: This is only viable for data types that do not carry TimeZone info.
Also type conversions to VarChar and back are usually LESS performant than using DateTime functions that use numeric operations internally.
Consider other solutions posted if performance is a concern or if you must retain timezone information.

DECLARE #TheDate DATETIME
SET #TheDate = '2011-11-22 12:14:58.000'
DATEADD(mi, DATEDIFF(mi, 0, #TheDate), 0)
In queries
/* ...all records in that minute; index-friendly expression */
WHERE TheDate BETWEEN DATEADD(mi, DATEDIFF(mi, 0, #TheDate), 0)
AND DATEADD(mi, DATEDIFF(mi, 0, #TheDate) + 1, 0)

Date and time needs carefully and not being converted as TEXT.
My personal solution:
CREATE FUNCTION [dbo].[fnDateTimeTruncated]
(
#datetime DATETIME
)
RETURNS DATETIME
AS
BEGIN
RETURN DATETIMEFROMPARTS ( year(#datetime), month(#datetime), day(#datetime), DATEPART(hh,#datetime), DATEPART(mi,#datetime), 0, 0)
END
Edited:
Regarding http://blog.waynesheffield.com/wayne/archive/2012/03/truncate-a-date-time-to-different-part/, DateAdd has a better performance.
Thanks to t-clausen.dk

With a little fiddling around, this seems to work well:
SELECT CAST(CONVERT(CHAR(17), bl.[time],113) AS varchar(17))
Result given: 2011-11-22 12:14
The exact way I'm using it in my query as part of the selection list :
,CAST(CONVERT(CHAR(17), bl.[time],113) AS varchar(17))
+ ' (UTC +0)' AS [TIME]
Gives me the result: 15 Dec 2017 06:43 (UTC +0)

From SQL Server 2014, You can use Format function for this.
for Ex.
declare #Startdate datetime = '2020-11-07 15:27:50.713'
set #Startdate = Convert(datetime,FORMAT(#Startdate, 'yyyy-MM-dd HH:mm'))
> Result is
2020-11-07 15:27:00.000

If there is no milliseconds, than
DECLARE #dt datetime2 = '2011-11-22 12:14:58.000';
DECLARE #goalDt datetime2 = DATEADD(second,-DATEPART(second,#dt), #dt);
To remove a milliseconds part, add
SET #goalDt = DATEADD(millisecond,-DATEPART(millisecond,#goalDt ), goalDt dt);

To Round Off it:
DECLARE #TheDate DATETIME;
SET #TheDate = '2019-1-2 12:14:58.400';
SELECT CAST(#TheDate AS SMALLDATETIME);
To just Truncate:
DECLARE #TruncTheDate DATETIME;
SET #TruncTheDate = '2019-1-2 12:14:58.400';
SELECT DATEADD(mi, DATEDIFF(mi, 0, #TruncTheDate), 0);

select substring(cast(cast(getdate() as time(0)) as char(8)),0,6)

Related

Time part of a DateTime Field in SQL

How would I be able to extract the time part of a DateTime field in SQL? For my project I have to return data that has a timestamp of 5pm of a DateTime field no matter what the date is
This will return the time-Only
For SQL Server:
SELECT convert(varchar(8), getdate(), 108)
Explanation:
getDate() is giving current date and time.
108 is formatting/giving us the required portion i.e time in this case.
varchar(8) gives us the number of characters from that portion.
Like:
If you wrote varchar(7) there, it will give you 00:00:0
If you wrote varchar(6) there, it will give you 00:00:
If you wrote varchar(15) there, it will still give you 00:00:00 because it is giving output of just time portion.
SQLFiddle Demo
For MySQL:
SELECT DATE_FORMAT(NOW(), '%H:%i:%s')
SQLFiddle Demo
In SQL Server if you need only the hh:mi, you can use:
DECLARE #datetime datetime
SELECT #datetime = GETDATE()
SELECT RIGHT('0'+CAST(DATEPART(hour, #datetime) as varchar(2)),2) + ':' +
RIGHT('0'+CAST(DATEPART(minute, #datetime)as varchar(2)),2)
If you want only the hour of your datetime, then you can use DATEPART() - SQL Server:
declare #dt datetime
set #dt = '2012-09-10 08:25:53'
select datepart(hour, #dt) -- returns 8
In SQL Server 2008+ you can CAST() as time:
declare #dt datetime
set #dt = '2012-09-10 08:25:53'
select CAST(#dt as time) -- returns 08:25:53
I know this is an old question, but since the other answers all
return strings (rather than datetimes),
rely on the internal representation of dates (conversion to float, int, and back) or
require SQL Server 2008 or beyond,
I thought I'd add a "pure" option which only requires datetime operations and works with SQL Server 2005+:
SELECT DATEADD(dd, -DATEDIFF(dd, 0, mydatetime), mydatetime)
This calculates the difference (in whole days) between date zero (1900-01-01) and the given date and then subtracts that number of days from the given date, thereby setting its date component to zero.
Try this in SQL Server 2008:
select *
from some_table t
where convert(time,t.some_datetime_column) = '5pm'
If you want take a random datetime value and adjust it so the time component is 5pm, then in SQL Server 2008 there are a number of ways. First you need start-of-day (e.g., 2011-09-30 00:00:00.000).
One technique that works for all versions of Microsoft SQL Server as well as all versions of Sybase is to use convert/3 to convert the datetime value to a varchar that lacks a time component and then back into a datetime value:
select convert(datetime,convert(varchar,current_timestamp,112),112)
The above gives you start-of-day for the current day.
In SQL Server 2008, though, you can say something like this:
select start_of_day = t.some_datetime_column
- convert(time, t.some_datetime_column ) ,
from some_table t
which is likely faster.
Once you have start-of-day, getting to 5pm is easy. Just add 17 hours to your start-of-day value:
select five_pm = dateadd(hour,17, t.some_datetime_column
- convert(time,t.some_datetime_column)
)
from some_table t
Note that from MS SQL 2012 onwards you can use FORMAT(value,'format')
e.g. WHERE FORMAT(YourDatetime,'HH:mm') = '17:00'
"For my project, I have to return data that has a timestamp of 5pm of a DateTime field, No matter what the date is."
So I think what you meant was that you needed the date, not the time. You can do something like this to get a date with 5:00 as the time:
SELECT CONVERT(VARCHAR(10), GetDate(), 110) + ' 05:00:00'
This should strip away the date part:
select convert(datetime,convert(float, getdate()) - convert(int,getdate())), getdate()
and return a datetime with a default date of 1900-01-01.
you can use CONVERT(TIME,GETDATE()) in this case:
INSERT INTO infoTbl
(itDate, itTime)
VALUES (GETDATE(),CONVERT(TIME,GETDATE()))
or if you want print it or return that time use like this:
DECLARE #dt TIME
SET #dt = CONVERT(TIME,GETDATE())
PRINT #dt
select cast(getdate() as time(0))
returns for example :- 15:19:43
replace getdate() with the date time you want to extract just time from!
SELECT DISTINCT
CONVERT(VARCHAR(17), A.SOURCE_DEPARTURE_TIME, 108)
FROM
CONSOLIDATED_LIST AS A
WHERE
CONVERT(VARCHAR(17), A.SOURCE_DEPARTURE_TIME, 108) BETWEEN '15:00:00' AND '15:45:00'
declare #datetime as datetime
set #datetime = getdate()
select cast(cast(#datetime as time) as varchar(8))
For year:
SELECT DATEPART(YEAR, '2021-03-21' );
For hour:
SELECT DATEPART(HOUR, '2021-03-21 08:50:30' );

A way to extract from a DateTime value data without seconds

I have an sql DateTime (ms sql server) and want to extract the same date without the seconds:
e.g. 2011-11-22 12:14:58.000 to become: 2011-11-22 12:14:00.000
How can I do this? I was thinking to use DATEADD in combination with DATEPART but seems very error prone (besides performance issues)
SELECT DATEADD(MINUTE, DATEDIFF(MINUTE, 0, yourcolumn), 0) FROM yourtable
This will be effective, if you don't want a slow conversion between datatypes.
For a solution that truncates using strings try this:
SELECT CAST(CONVERT(CHAR(16), GetDate(),20) AS datetime)
CHAR(16) works only if our variable is converted to ODBC canonical format, as shown above by using 20 as the format specifier.
DECLARE #date DateTime = '2011 Nov 22 12:14:55';
SELECT CONVERT(Char(16), #date ,20) AS datetime
Results:
| datetime |
|------------------|
| 2011-11-22 12:14 |
Then you simply cast back to a DateTime type to continue using the value.
NOTE: This is only viable for data types that do not carry TimeZone info.
Also type conversions to VarChar and back are usually LESS performant than using DateTime functions that use numeric operations internally.
Consider other solutions posted if performance is a concern or if you must retain timezone information.
DECLARE #TheDate DATETIME
SET #TheDate = '2011-11-22 12:14:58.000'
DATEADD(mi, DATEDIFF(mi, 0, #TheDate), 0)
In queries
/* ...all records in that minute; index-friendly expression */
WHERE TheDate BETWEEN DATEADD(mi, DATEDIFF(mi, 0, #TheDate), 0)
AND DATEADD(mi, DATEDIFF(mi, 0, #TheDate) + 1, 0)
Date and time needs carefully and not being converted as TEXT.
My personal solution:
CREATE FUNCTION [dbo].[fnDateTimeTruncated]
(
#datetime DATETIME
)
RETURNS DATETIME
AS
BEGIN
RETURN DATETIMEFROMPARTS ( year(#datetime), month(#datetime), day(#datetime), DATEPART(hh,#datetime), DATEPART(mi,#datetime), 0, 0)
END
Edited:
Regarding http://blog.waynesheffield.com/wayne/archive/2012/03/truncate-a-date-time-to-different-part/, DateAdd has a better performance.
Thanks to t-clausen.dk
With a little fiddling around, this seems to work well:
SELECT CAST(CONVERT(CHAR(17), bl.[time],113) AS varchar(17))
Result given: 2011-11-22 12:14
The exact way I'm using it in my query as part of the selection list :
,CAST(CONVERT(CHAR(17), bl.[time],113) AS varchar(17))
+ ' (UTC +0)' AS [TIME]
Gives me the result: 15 Dec 2017 06:43 (UTC +0)
From SQL Server 2014, You can use Format function for this.
for Ex.
declare #Startdate datetime = '2020-11-07 15:27:50.713'
set #Startdate = Convert(datetime,FORMAT(#Startdate, 'yyyy-MM-dd HH:mm'))
> Result is
2020-11-07 15:27:00.000
If there is no milliseconds, than
DECLARE #dt datetime2 = '2011-11-22 12:14:58.000';
DECLARE #goalDt datetime2 = DATEADD(second,-DATEPART(second,#dt), #dt);
To remove a milliseconds part, add
SET #goalDt = DATEADD(millisecond,-DATEPART(millisecond,#goalDt ), goalDt dt);
To Round Off it:
DECLARE #TheDate DATETIME;
SET #TheDate = '2019-1-2 12:14:58.400';
SELECT CAST(#TheDate AS SMALLDATETIME);
To just Truncate:
DECLARE #TruncTheDate DATETIME;
SET #TruncTheDate = '2019-1-2 12:14:58.400';
SELECT DATEADD(mi, DATEDIFF(mi, 0, #TruncTheDate), 0);
select substring(cast(cast(getdate() as time(0)) as char(8)),0,6)

SQL HELP... CONVERT(int, CONVERT(datetime, FLOOR(CONVERT(float, getdate())))

I am having a problem adjusting this part of my SQL statement:
HAVING dbo.BOOKINGS.BOOKED = CONVERT(int, CONVERT(datetime,
FLOOR(CONVERT(float, GETDATE()))) + 2)
Normally, the page that uses this statement just lists the amount of sales for today, I want to switch the GETDATE() to a date that I declare. I tried all different formats and none have worked
Use the DATEADD/DATEDIFF method of setting the time portion to midnight of the current date - it's the fastest means, and casting to FLOAT can be unreliable:
HAVING BOOKINGS.dbo.BOOKED = CONVERT(INT, DATEADD(dd, DATEDIFF(dd, 0, GETDATE()), 0))+2
Then, you can set your own date easily if you use a variable (#var in this example, within a stored procedure or function):
DECLARE #var DATETIME
SELECT ...
HAVING BOOKINGS.dbo.BOOKED = CONVERT(INT, DATEADD(dd, DATEDIFF(dd, 0, #var), 0))+2
This assumes #var is a DATETIME data type. Otherwise, you'll need to use a date format SQL Server will implicitly convert to a DATETIME -- or use CAST/CONVERT to explicitly convert the value.
if you want you to give your own date you could do this instead of getdate() which gives current system timestamp.
Cast('2010-11-04 13:28:00.000' as datetime)
How about
declare #myDate as datetime
set #myDate = '11/2/2010'
. . .
HAVING dbo.BOOKINGS.BOOKED = CONVERT(int, CONVERT(datetime,
FLOOR(CONVERT(float, #myDate ))) + 2)
That should do it, and it should automatically do the type conversion on your date string used in the set statement, or you could just pass in a datetime parameter if this is in a stored procedure.

SQL Convert to GMT DateTime

i wan't to convert my records entries from dateTtime+OFFSET to dateTtimeZ directly
(2008-05-11T15:30:00+2--->2008-05-11T13:30:00Z)
with sql functions.
Don't know how to do this :-(
I need to implement this using MySql prefering not using stored procs
Thx
Try this
To convert from GMT to local time:
select DATEADD(hour,DATEDIFF (hour, GETUTCDATE(), GETDATE()),MyGmtDateTime) as LocalDateTime
To convert from local time to GMT:
select DATEADD(hour,DATEDIFF (hour, GETDATE(), GETUTCDATE()),MyLocalDateTime) as GmtDateTime
If I understood your question correctly, there is no way to find out the time zone from time+offset because the mapping is not unique. Several time zones may have the same offset.
Look at this example where multiple time zone have the same offset.
(GMT-06:00) Saskatchewan
(GMT-06:00) Guadalajara, Mexico City, Monterrey - Old
(GMT-06:00) Guadalajara, Mexico City, Monterrey - New
(GMT-06:00) Central Time (US & Canada)
(GMT-06:00) Central America
ADDED: Now I see you asked for something else.
Okay, if the offset in your datetimes is always the same, you can try this transformation.
DECLARE #DateTimeWithOffset datetimeoffset
DECLARE #JustDateTime datetime
SET #DateTimeWithOffset = '2008-05-11 15:30:00 + 02:00'
SELECT #DateTimeWithOffset = SWITCHOFFSET (#DateTimeWithOffset, '00:00')
SELECT #JustDateTime = CAST (#DateTimeWithOffset AS datetime)
This is to give you the idea. I don't have an SQL 2008 right at hand so I haven't tested that. May not work.
I'm pretty rusty with my SQL built-in functions, but in the absence of any standard function, you could write a stored procedure to do the work. Then you could invoke it as part of your SELECT statement:
SELECT to_GMT(invoice_date) from INVOICES
the solution will likely depend of your RDBMS. In Oracle this would work:
SQL> SELECT to_timestamp_tz('2008-05-11T15:30:00+2',
2 'yyyy-mm-dd"T"hh24:mi:ssTZH')
3 AT TIME ZONE 'GMT' gmt_time
4 FROM dual;
GMT_TIME
----------------------------------
11/05/08 13:30:00,000000000 GMT
It is not clear from your question, but I assume you have the values as a string. If so, then extract everything except the offset as a datetime, also get the offset as a datetime, then use the sign to calculate the final result (T-SQL, 2005):
DECLARE #withOffset varchar(30);
SET #withOffset = '2008-05-11T15:30:00+2:00';
PRINT N'Original: ' + CAST(#withOffset AS nvarchar);
DECLARE #dt datetime;
SET #dt = CONVERT(datetime, LEFT(#withOffset, 19), 126);
PRINT N'dt=' + CONVERT(nvarchar, #dt, 127);
DECLARE #ofs datetime;
SET #ofs = CONVERT(datetime, SUBSTRING(#withOffset, 21, LEN(#withOffset) - 21), 108);
PRINT N'ofs=' + CAST(#ofs AS nvarchar);
IF (SUBSTRING(#withOffset, 19, 1) = '+')
BEGIN
SET #dt = DATEADD(hour, DATEPART(hour, #ofs), #dt);
SET #dt = DATEADD(minute, DATEPART(minute, #ofs), #dt);
END
ELSE
BEGIN
SET #dt = DATEADD(hour, -DATEPART(hour, #ofs), #dt);
SET #dt = DATEADD(minute, -DATEPART(minute, #ofs), #dt);
END;
PRINT N'dt=' + CONVERT(nvarchar, #dt, 127);
Use the SQL function CONVERT_TZ(dt,from_tz,to_tz).
CONVERT_TZ() converts a datetime value dt from the time zone given by
from_tz to the time zone given by to_tz and returns the resulting
value.
Example:
UPDATE this_table
SET this_table_date_gmt = (
SELECT CONVERT_TZ(this_date, '+00:00', '-02:00')
)
Reference : https://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_convert-tz

How can I compare time in SQL Server?

I'm trying to compare time in a datetime field in a SQL query, but I don't know if it's right. I don't want to compare the date part, just the time part.
I'm doing this:
SELECT timeEvent
FROM tbEvents
WHERE convert(datetime, startHour, 8) >= convert(datetime, #startHour, 8)
Is it correct?
I'm asking this because I need to know if 08:00:00 is less or greater than 07:30:00 and I don't want to compare the date, just the time part.
Thanks!
Your compare will work, but it will be slow because the dates are converted to a string for each row. To efficiently compare two time parts, try:
declare #first datetime
set #first = '2009-04-30 19:47:16.123'
declare #second datetime
set #second = '2009-04-10 19:47:16.123'
select (cast(#first as float) - floor(cast(#first as float))) -
(cast(#second as float) - floor(cast(#second as float)))
as Difference
Long explanation: a date in SQL server is stored as a floating point number. The digits before the decimal point represent the date. The digits after the decimal point represent the time.
So here's an example date:
declare #mydate datetime
set #mydate = '2009-04-30 19:47:16.123'
Let's convert it to a float:
declare #myfloat float
set #myfloat = cast(#mydate as float)
select #myfloat
-- Shows 39931,8244921682
Now take the part after the comma character, i.e. the time:
set #myfloat = #myfloat - floor(#myfloat)
select #myfloat
-- Shows 0,824492168212601
Convert it back to a datetime:
declare #mytime datetime
set #mytime = convert(datetime,#myfloat)
select #mytime
-- Shows 1900-01-01 19:47:16.123
The 1900-01-01 is just the "zero" date; you can display the time part with convert, specifying for example format 108, which is just the time:
select convert(varchar(32),#mytime,108)
-- Shows 19:47:16
Conversions between datetime and float are pretty fast, because they're basically stored in the same way.
convert(varchar(5), thedate, 108) between #leftTime and #rightTime
Explanation:
if you have varchar(5) you will obtain HH:mm
if you have varchar(8) you obtain HH:mm ss
108 obtains only the time from the SQL date
#leftTime and #rightTime are two variables to compare
If you're using SQL Server 2008, you can do this:
WHERE CONVERT(time(0), startHour) >= CONVERT(time(0), #startTime)
Here's a full test:
DECLARE #tbEvents TABLE (
timeEvent int IDENTITY,
startHour datetime
)
INSERT INTO #tbEvents (startHour) SELECT DATEADD(hh, 0, GETDATE())
INSERT INTO #tbEvents (startHour) SELECT DATEADD(hh, 1, GETDATE())
INSERT INTO #tbEvents (startHour) SELECT DATEADD(hh, 2, GETDATE())
INSERT INTO #tbEvents (startHour) SELECT DATEADD(hh, 3, GETDATE())
INSERT INTO #tbEvents (startHour) SELECT DATEADD(hh, 4, GETDATE())
INSERT INTO #tbEvents (startHour) SELECT DATEADD(hh, 5, GETDATE())
--SELECT * FROM #tbEvents
DECLARE #startTime datetime
SET #startTime = DATEADD(mi, 65, GETDATE())
SELECT
timeEvent,
CONVERT(time(0), startHour) AS 'startHour',
CONVERT(time(0), #startTime) AS '#startTime'
FROM #tbEvents
WHERE CONVERT(time(0), startHour) >= CONVERT(time(0), #startTime)
Just change convert datetime to time that should do the trick:
SELECT timeEvent
FROM tbEvents
WHERE convert(time, startHour) >= convert(time, #startHour)
if (cast('2012-06-20 23:49:14.363' as time) between
cast('2012-06-20 23:49:14.363' as time) and
cast('2012-06-20 23:49:14.363' as time))
One (possibly small) issue I have noted with the solutions so far is that they all seem to require a function call to process the comparison. This means that the query engine will need to do a full table scan to seek the rows you are after - and be unable to use an index. If the table is not going to get particularly large, this probably won't have any adverse affects (and you can happily ignore this answer).
If, on the other hand, the table could get quite large, the performance of the query could suffer.
I know you stated that you do not wish to compare the date part - but is there an actual date being stored in the datetime column, or are you using it to store only the time? If the latter, you can use a simple comparison operator, and this will reduce both CPU usage, and allow the query engine to use statistics and indexes (if present) to optimise the query.
If, however, the datetime column is being used to store both the date and time of the event, this obviously won't work. In this case if you can modify the app and the table structure, separate the date and time into two separate datetime columns, or create a indexed view that selects all the (relevant) columns of the source table, and a further column that contains the time element you wish to search for (use any of the previous answers to compute this) - and alter the app to query the view instead.
Using float does not work.
DECLARE #t1 datetime, #t2 datetime
SELECT #t1 = '19000101 23:55:00', #t2 = '20001102 23:55:00'
SELECT CAST(#t1 as float) - floor(CAST(#t1 as float)), CAST(#t2 as float) - floor(CAST(#t2 as float))
You'll see that the values are not the same (SQL Server 2005). I wanted to use this method to check for times around midnight (the full method has more detail) in which I was comparing the current time for being between 23:55:00 and 00:05:00.
Adding to the other answers:
you can create a function for trimming the date from a datetime
CREATE FUNCTION dbo.f_trimdate (#dat datetime) RETURNS DATETIME AS BEGIN
RETURN CONVERT(DATETIME, CONVERT(FLOAT, #dat) - CONVERT(INT, #dat))
END
So this:
DECLARE #dat DATETIME
SELECT #dat = '20080201 02:25:46.000'
SELECT dbo.f_trimdate(#dat)
Will return
1900-01-01 02:25:46.000
Use Datepart function: DATEPART(datepart, date)
E.g#
SELECT DatePart(#YourVar, hh)*60) +
DatePart(#YourVar, mi)*60)
This will give you total time of day in minutes allowing you to compare more easily.
You can use DateDiff if your dates are going to be the same, otherwise you'll need to strip out the date as above
You can create a two variables of datetime, and set only hour of date that your need to compare.
declare #date1 datetime;
declare #date2 datetime;
select #date1 = CONVERT(varchar(20),CONVERT(datetime, '2011-02-11 08:00:00'), 114)
select #date2 = CONVERT(varchar(20),GETDATE(), 114)
The date will be "1900-01-01" you can compare it
if #date1 <= #date2
print '#date1 less then #date2'
else
print '#date1 more then #date2'
SELECT timeEvent
FROM tbEvents
WHERE CONVERT(VARCHAR,startHour,108) >= '01:01:01'
This tells SQL Server to convert the current date/time into a varchar using style 108, which is "hh:mm:ss". You can also replace '01:01:01' which another convert if necessary.
I believe you want to use DATEPART('hour', datetime).
Reference is here:
http://msdn.microsoft.com/en-us/library/ms174420.aspx
I don't love relying on storage internals (that datetime is a float with whole number = day and fractional = time), but I do the same thing as the answer Jhonny D. Cano. This is the way all of the db devs I know do it. Definitely do not convert to string. If you must avoid processing as float/int, then the best option is to pull out hour/minute/second/milliseconds with DatePart()
I am assuming your startHour column and #startHour variable are both DATETIME; In that case, you should be converting to a string:
SELECT timeEvent
FROM tbEvents
WHERE convert(VARCHAR(8), startHour, 8) >= convert(VARCHAR(8), #startHour, 8)
below query gives you time of the date
select DateAdd(day,-DateDiff(day,0,YourDateTime),YourDateTime) As NewTime from Table
#ronmurp raises a valid concern - the cast/floor approach returns different values for the same time. Along the lines of the answer by #littlechris and for a more general solution that solves for times that have a minute, seconds, milliseconds component, you could use this function to count the number of milliseconds from the start of the day.
Create Function [dbo].[MsFromStartOfDay] ( #DateTime datetime )
Returns int
As
Begin
Return (
( Datepart( ms , #DateTime ) ) +
( Datepart( ss , #DateTime ) * 1000 ) +
( Datepart( mi , #DateTime ) * 1000 * 60 ) +
( Datepart( hh , #DateTime ) * 1000 * 60 * 60 )
)
End
I've verified that it returns the same int for two different dates with the same time
declare #first datetime
set #first = '1900-01-01 23:59:39.090'
declare #second datetime
set #second = '2000-11-02 23:56:39.090'
Select dbo.MsFromStartOfDay( #first )
Select dbo.MsFromStartOfDay( #second )
This solution doesn't always return the int you would expect. For example, try the below in SQL 2005, it returns an int ending in '557' instead of '556'.
set #first = '1900-01-01 23:59:39.556'
set #second = '2000-11-02 23:56:39.556'
I think this has to do with the nature of DateTime stored as float. You can still compare the two number, though. And when I used this approach on a "real" dataset of DateTime captured in .NET using DateTime.Now() and stored in SQL, I found that the calculations were accurate.
TL;DR
Separate the time value from the date value if you want to use indexes in your search (you probably should, for performance). You can: (1) use function-based indexes or (2) create a new column for time only, index this column and use it in you SELECT clause.
Keep in mind you will lose any index performance boost if you use functions in a SQL's WHERE clause, the engine has to do a scan search. Just run your query with EXPLAIN SELECT... to confirm this. This happens because the engine has to process EVERY value in the field for EACH comparison, and the converted value is not indexed.
Most answers say to use float(), convert(), cast(), addtime(), etc.. Again, your database won't use indexes if you do this. For small tables that may be OK.
It is OK to use functions in WHERE params though (where field = func(value)), because you won't be changing EACH field's value in the table.
In case you want to keep use of indexes, you can create a function-based index for the time value. The proper way to do this (and support for it) may depend on your database engine. Another option is adding a column to store only the time value and index this column, but try the former approach first.
Edit 06-02
Do some performance tests before updating your database to have a new time column or whatever to make use of indexes. In my tests, I found out the performance boost was minimal (when I could see some improvement) and wouldn't be worth the trouble and overhead of adding a new index.