SQL Find if two UTC Dates are in the same calendar day - sql

I have a table with a DateTime column, this column contains a DateTime in UTC which in local time is always time 00:00:00.000, this is because I only care about Date part, not time but I need to store the Date in UTC.In my local time, the UTC offset is -6 hours, so, all my dates are stored with a time equals to 6, for example, '2017-01-03 06:00:00.000' . The problem is that when I try to compare this:
SELECT (CASE WHEN (CONVERT(DATE, '2017-01-03 06:00:00.000') = CONVERT(DATE, GETUTCDATE())) THEN 1 ELSE 0 END) AS [IsEqual]
If the result of GETUTCDATE is another day but the hour is smaller than 6, for example, '2017-01-04 02:00:00.000', this date in local time still belong to January 3, but the above comparison returns false because is checking if 2017-01-03 = 2017-01-04.
How can I find id this two UTC dates are on the same calendar day?

If your local time is always 6 hours from UTC (meaning no Daylight saving time), you should subtract 6 hours from GETUTCDATE() and then compare to your local time:
SELECT CASE WHEN
CONVERT(DATE, '2017-01-03 06:00:00.000') =
CONVERT(DATE, DATEADD(HOUR, -6, GETUTCDATE())) THEN
1
ELSE
0
END AS [IsEqual]

Related

<Resolved> Fetch last date of a month and last minute of that day

I need to get last day of the month with time like
2023-01-31 23:59:59:000000
I'm able to get only the last day of the month with time stamp as
2023-01-31 00:00:00:000000
As jarlh said your best method is to add a day to the end of the month, then subtract a second (although if you really want the absolute maximum time I think you'd want to subtract 3 milliseconds).
EOMONTH -> Add 1 day -> Cast as datetime -> remove 1 second / 3 milliseconds. You have to cast as datetime because the EOMONTH function implicitly casts to a date
The code will be something like this:
SELECT DATEADD(SECOND, -1, CAST(DATEADD(DAY, 1, EOMONTH(#currentDate)) AS DATETIME))
SELECT DATEADD(MILLISECOND, -3, CAST(DATEADD(DAY, 1, EOMONTH(#currentDate)) AS DATETIME))
There are already similar questions with a lot of answers. You should find your anwer for sure:
Get the last day of the month in SQL
SQL query to display end date of current month
DECLARE #currentDate DATE = GETDATE()
SELECT EOMONTH (#currentDate) AS CurrentMonthED
SQL query to display end date of Next month
DECLARE #currentDate DATE = GETDATE()
SELECT EOMONTH (#currentDate, 1 ) AS NextMonthED

Rounding DateTime in SQL

I have DateTime data in a MS SQL database with the following format:
2020-05-07 22:35:00
I am trying to create a query that only captures data from the last 24 hours of operations. However, our operations KPIs are measured from 6AM-6AM. I would like to round the date based on time. Anything before 6AM will be counted as the day before.
2020-05-07 05:45:00 -> 2020-05-06 (Before 6AM)
2020-05-07 06:30:00 -> 2020-05-07 (After 6AM)
So far I have been successful in pulling the previous days activity, but am struggling to shift the timeframe to round down anything before 6AM
SELECT
end_date
FROM data sint
WHERE sint.end_date >= dateadd(day,datediff(day,1,GETDATE()),0)
AND sint.end_date < dateadd(day,datediff(day,0,GETDATE()),0)
You can add six hours to the current date (without the time) for the comparison:
where int.end_date < dateadd(hour, 6, convert(datetime, convert(date, getdate()))) and
int.end_date >= dateadd(hour, 6 - 24, convert(datetime, convert(date, getdate())))
Note that the conversion to date removes the time component.
first get the time part. Compare the time part with 6AM and run your expression.
In below code the time part is compared with the date '1900-01-01 06:00:00' which is 6AM in default date format.
select
case when cast(date as time(0)) < '1900-01-01 06:00:00'
then cast(date - 1 as date)
else cast(date as date)
end as newdate
from temp_date;
I would do the same as Gordon only the opposite side.
I would subtract 6 hours from end_date and then compare.
where convert(date, dateadd(hour, -6, int.end_date)) = convert(date, getdate())
Though this method might not work well if you're actually using getdate(). It will return nothing if it is ran between midnight and 6 am (unless you have future dates).

Get rows having a datetime less than or equal to today ignoring time

I have a datetime field and would like to select the records having a date less than or equal to today but ignoring the time part of it.
My datetime field is as below:
2019-05-17 13:31:15.900, 2019-05-16 13:32:17.277, 2019-05-24 15:20:03.823
I would like to fetch only the rows with datetime 2019-05-17 13:31:15.900 and 2019-05-16 13:32:17.277 ignoring the time part.
Any idea of how to do that in sql server?
Simply, just cast both, your column and todays date to DATE:
SELECT * FROM MyTable
WHERE CAST(dt AS DATE) <= CAST(GETDATE() AS DATE)
You may try casting GETDATE() to a date type, to compare against tomorrow at midnight:
SELECT *
FROM yourTable
WHERE dt < CAST(DATEADD(day, 1, GETDATE()) AS date);
-- earlier than tomorrow at midnight
The date when this answer was written was 17-June-2019, so the above query would return any record whose datetime is strictly less than 18-June-2019 at midnight. The latest record would therefore be '2019-06-17 23:59:59'.

How to get date of yesterday with the time part 00:00:00 in big query?

In big query how do I get the yesterday date with the time part 00:00:00?
DATE Doesn't have time part
if you want yesterday DateTime with 00:00 as time use:
SELECT DATETIME_TRUNC(DATETIME_SUB(CURRENT_DATETIME(), INTERVAL 1 DAY), DAY) as yesterday;
if you want yesterday date use:
SELECT DATE_SUB(CURRENT_DATE(), INTERVAL 1 DAY) as yesterday;
If you want a time part, then you want either a TIMESTAMP or DATETIME column.
So, either:
SELECT DATETIME(DATE_ADD(CURRENT_DATE(), INTERVAL -1 DAY)) as yesterday_dt,
TIMESTAMP(DATE_ADD(CURRENT_DATE(), INTERVAL -1 DAY)) as yesterday_ts
This code gets you date
SELECT DATEADD(dd, -1, DATEDIFF(dd, 0, GETDATE()));
For different methods check this link
MS SQL Server - How to get Date only from the datetime value?
Below is yet another option for BigQuery standard SQL
#standardSQL
SELECT
TIMESTAMP_SECONDS(86400 * (UNIX_DATE(CURRENT_DATE()) - 1)) yesterday_as_timestamp,
DATETIME(TIMESTAMP_SECONDS(86400 * (UNIX_DATE(CURRENT_DATE()) - 1))) yesterday_as_datetime
with result (as of answer day - April 02, 2019)
Row yesterday_as_timestamp yesterday_as_datetime
1 2019-04-01 00:00:00 UTC 2019-04-01T00:00:00
Note:
DATETIME Represents a year, month, day, hour, minute, second, and subsecond. Range: 0001-01-01 00:00:00 to 9999-12-31 23:59:59.999999.
TIMESTAMP Represents an absolute point in time, with microsecond precision. Range: 0001-01-01 00:00:00 to 9999-12-31 23:59:59.999999 UTC.
A timestamp represents an absolute point in time, independent of any time zone or convention such as Daylight Savings Time.
TIMESTAMP provides microsecond precision.
Unlike Timestamps, a DATETIME object does not refer to an absolute instance in time. Instead, it is the civil time, or the time that a user would see on a watch or calendar.
You can see more details about DATETIME and TIMESTAMP in Data Types doc

Where datetime between 12 am of column time and 10 am next day of column time

I have a column with data type as datetime and the way data is imported is always the previous day to today.
There is not historical data stored in the table - the previous data is deleted before the new data is imported.
That being said I will like to have a where clause written where my ESTEndTime column is between 00:00:00 of the timestamp column and 10:00:00 the next day of the timestamp column.
I've searched but couldn't find anything specific to what I was looking for.
The purpose is to primarily capture the end times of those who work overnight. When the data is exported it always exported as the previous day to the next day, for example October 1 to October 2. This will allow us to see the latest logout times of those who worked overnight. In the example that I just mentioned the data will include everything from 00:00:00 October 1 to 23:59:59 October 2. There is no way for us to limit to a specific time. So using the example when I was hoping to achieve is limit it in a where clause where the time is between 00:00:00 October 1 and 10:00:00 October 2. The problem is I don't want to use those actual dates as my dates are always changing hence why I am here for some help.
Code that I have but not getting the expected results
SELECT timestamp, emp_id, dept, ESTStartTime, ESTEndTime
,CONCAT(emp_id, '-', FORMAT(ESTStartTime, 'yyyy/MM/dd-HH:mm')) AS Index2Start
,CONCAT(emp_id, '-', FORMAT(ESTEndTime, 'yyyy/MM/dd-HH:mm')) AS Index3Stop
,CONCAT(emp_id, '-', FORMAT(ESTEndTime, 'yyyy/MM/dd')) AS Index3StopDay
FROM dbo.[test]
WHERE ESTEndTime BETWEEN DATEADD(DAY, DATEDIFF(DAY, 0, timestamp), 0) + '00:00'
AND DATEADD(DAY, DATEDIFF(DAY, 1, timestamp), 1) + '10:00'
ORDER BY ESTEndTime DESC
Here is another possible way you can try
SELECT DISTINCT ee.*
FROM table ee
CROSS APPLY (
select MIN(timestamp) AS timestamp, NextDate = DATEADD(HOUR,10,DATEADD(DAY,1,MIN(timestamp))) from table
) maxdate
WHERE ee.ESTEndTime BETWEEN maxdate.timestamp AND maxdate.NextDate
See if this will work for you. I declared 2 variables to hold the previous day's date and time and the current day's date and time. I used GETDATE() to get the current date and time. I extracted the date part out of it and subtracted a day for the previous date. Then I converted the date to a VARCHAR and added the time. SQL Server will implicitly convert the string back to a DATETIME value.
--Previous day at 12:00am
DECLARE #prevday DATETIME = CONVERT(VARCHAR,CONVERT(DATE,(DATEADD(DD,-1,GETDATE())))) + ' 12:00AM';
--Current day at 10:00am
DECLARE #currentday DATETIME = CONVERT(VARCHAR,CONVERT(DATE,GETDATE())) + ' 10:00 AM' ;
SELECT timestamp, emp_id, dept, ESTStartTime, ESTEndTime
,CONCAT(emp_id, '-', FORMAT(ESTStartTime, 'yyyy/MM/dd-HH:mm')) AS Index2Start
,CONCAT(emp_id, '-', FORMAT(ESTEndTime, 'yyyy/MM/dd-HH:mm')) AS Index3Stop
,CONCAT(emp_id, '-', FORMAT(ESTEndTime, 'yyyy/MM/dd')) AS Index3StopDay
FROM dbo.[test]
WHERE ESTEndTime BETWEEN #prevday AND #currentday
ORDER BY ESTEndTime DESC