Given a specific DateTime, and using just SQL, how can I determine if Daylight Savings Time will be in effect on that day? This is purely for "local" use, so I don't need to worry about it working on different environments or locales, just my own SQL Server 2008R2 server.
So, for example,
declare #myDate datetime='2 Jun 2014 14:00'
and then somehow evaluating #myDate would return a result that indicates "yes, this is in DST", where as
declare #myDate datetime='2 Dec 2014 14:00'
... would be "no, this isn't in DST".
The datetime specified will only be during working hours (8am-8pm), so I'm not too concerned about values that fall "in between" DST and non-DST. I'm in the UK, which goes between UTC and UTC+1.
Seems to be answered here:
Get Time zones in SQL Server 2008 R2
Essentially you need to load the Olson timezone database, or some subset of it, into your SQL server database and then you can access it using SQL.
I've cobbled together the following code, which makes the (British) assumptions that DST starts on the last Sunday in March, and ends in the last Sunday in October. It's fairly specific to my requirements, but seems to do the job - if anyone knows of a more elegant solution...
declare #myDate datetime='2 Jun 2014'
-- Declare October in this year
declare #october datetime=DATEADD(month,9, DATEADD(yy, DATEDIFF(yy,0,#myDate), 0))
-- Declare March in this year
declare #march datetime=DATEADD(month,3, DATEADD(yy, DATEDIFF(yy,0,#myDate), 0))
-- Find last Sunday in March
declare #DSTStart datetime=DATEADD(dd,
-DATEPART(WEEKDAY,
DATEADD(dd, -DAY(DATEADD(mm, 1, #march)),
DATEADD(mm, 1, #march))) + 1,
DATEADD(dd, -DAY(DATEADD(mm, 1, #march)), DATEADD(mm, 1, #march)))
-- Find last Sunday in October
declare #DSTEnd datetime= DATEADD(dd,
-DATEPART(WEEKDAY,
DATEADD(dd, -DAY(DATEADD(mm, 1, #october)),
DATEADD(mm, 1, #october))) + 1,
DATEADD(dd, -DAY(DATEADD(mm, 1, #october)), DATEADD(mm, 1, #october)))
if (#mydate BETWEEN #DSTStart and #DSTEnd) print 'DST'
Related
I need to get the start of next Minute value, that means suppose I got the output for GETDATE() is 19.11.2019 12:52:51 but I need to get 19.11.2019 12:53:00
This is my code:
DECLARE #date DATETIME
SET #date = GETDATE()
DECLARE #increase int = 1;
SELECT DATEADD(mi, #increase,#date) as nextminutedate;
You want to round the date down. One method in SQL Server is:
select dateadd(minute, 1+datediff(minute, 0, getdate()), 0)
This is a little inscrutable. The datediff() calculates the number of minutes from a time of 0 for the current date/time. The dateadd() adds this back in.
Note: This works for minutes. You might have overflow problems with seconds or milliseconds.
For this reason, I rather prefer:
select dateadd(minute, 1+datediff(minute, '2000-01-01', getdate()), '2000-01-01')
I find this is clearer in the intention.
Besides writing a custom UDF to support this issue, is there any known methods of achieving this? I'm currently using Hive 0.13.
Starting with Hive 1.2, you can also do it like this:
select next_day(date_sub('2019-01-01', 7), 'MON')
Output:
2018-12-31
date_sub(m.invitationdate,pmod(datediff(m.invitationdate,'1900-01-07'),7))
This expression gives the exact solution to my question.
Regards,
Boris
This is the easiest and the best solution for fetching 1st day of the week's date:
For Current timstamp:
select date_sub(from_unixtime(unix_timestamp()), cast(from_unixtime(unix_timestamp(), 'u') AS int)) ;
For any given date or column:
select date_sub(from_unixtime(unix_timestamp('2017-05-15','yyyy-MM-dd')), cast(from_unixtime(unix_timestamp('2017-05-15','yyyy-MM-dd'), 'u') AS int)) ;
select date_sub(from_unixtime(unix_timestamp(colname,'yyyy-MM-dd')), cast(from_unixtime(unix_timestamp(colname,'yyyy-MM-dd'), 'u') AS int)) ;
Yes, you can do this without writing a UDF. If you look at at the Hive documentation under datetime functions, there is a function from_unixtime() that takes a unix timestamp and a string pattern. A couple of functions down on the documentation page, there is a link that explains the different patterns you can use in this function. So, from your timestamp, you can extract the day of the week and proceed accordingly.
Example Data:
1445313193
1445313100
1445313146
1445040000
1445040023
1445040111
The first three are Monday, 2015-10-19 and the last three are Friday, 2015-10-16.
Query:
select day_of_week
, date_var
, case when day_of_week = 'Sun' then date_var
when day_of_week = 'Sat' then date_sub(date_var, 6)
when day_of_week = 'Fri' then date_sub(date_var, 5)
when day_of_week = 'Thu' then date_sub(date_var, 4)
when day_of_week = 'Wed' then date_sub(date_var, 3)
when day_of_week = 'Tue' then date_sub(date_var, 2)
when day_of_week = 'Mon' then date_sub(date_var, 1)
else NULL
end as first_day_of_week_date
from (
select from_unixtime(timestamp, 'EEE') day_of_week
, from_unixtime(timestamp, 'yyyy-MM-dd') date_var
from db.table ) A
Output:
Mon 2015-10-19 2015-10-18
Mon 2015-10-19 2015-10-18
Mon 2015-10-19 2015-10-18
Fri 2015-10-16 2015-10-11
Fri 2015-10-16 2015-10-11
Fri 2015-10-16 2015-10-11
So, for today it returns yesterday, which was Sunday, and for last Friday, it returns the previous Sunday, the 11th. I am making the assumption that by "first day of a week", you mean Sunday; if not, you can adjust the code to mean Monday. Hope this helps.
I run the below query to check if something ran the previous day. The below query works, but I have to change the date each day to get the results I want. I've tried multiple things that I've found that seem like they should return results, but they don't quite seem to work.
select * from Linking_Results
where Evaluated between '2015-02-04 00:00:01.001' and '2015-02-04 23:59:00.999'
and Linked = '1' order by Evaluated
So my question is, how do I make a dynamic statement for yesterday and keep from having to change the date daily?
You can use the dateadd and getdate functions.
declare #start datetime,
#end datetime
-- subtract one day and cast it as a date to drop the time portion
select #start = cast(dateadd(day, -1, getdate()) as date)
-- add one day and subtract 3ms to get the end of yesterday (apparently SQL rounds)
select #end = dateadd(ms, -3, dateadd(day, 1, #start))
The values would then be
2015-02-04 00:00:00.000
2015-02-04 23:59:59.997
and you can do a between on these two variables. Since you use between which is inclusive, you need to account for the time portion. You could change the where clause to go to the next day and do an exclusive check on #end
select #end = dateadd(day, 1, #start)
where Evaluated >= #start and Evaluated < #end
So my default values for startDate and endDate in SSRS were set up with the following ssrs expressions.
first day of previous month ssrs expression
=DateAdd(DateInterval.Month, -1, DateSerial(Year(Date.Now), Month(Date.Now), 1))
last day of previous month ssrs expression
=DateAdd(DateInterval.Day, -1, DateSerial(Year(Date.Now), Month(Date.Now), 1))
But that won't work alone in my case unless I want to go in on the 16th of every month and generate this report for the people requesting it for the first 15 days of the current month.
So in my default value expression for start date i am trying this iif statement...
= iif(
DatePart(DateInterval.Day, Today() <> "20",
DateInterval.Month, -1, DateSerial(Year(Date.Now), Month(Date.Now), 1),
DateInterval.Month, 1, DateSerial(Year(Date.Now), Month(Date.Now), 1)
)
Not working out so well. So what i'm trying to do is.....
Change the default start and end date based on what day of the current month it is, So if current day of the current month equals 16, make start date 1 of current month and end date 15 of current month, if current day of the month isn’t 16 make start date first of previous month and end date last day of previous month. So then the only thing needed is to get subscription emails and what day to send them out on.
Untested, but what if you try this? (for your start date parameter):
= iif(
DatePart(DateInterval.Day, Today()) <> "16",
DateAdd(DateInterval.Month, -1, DateSerial(Year(Date.Now), Month(Date.Now), 1)),
DateSerial(Year(Date.Now), Month(Date.Now), 1)
)
I'm a bit puzzled on how to get all records from my table where CheckInDate (datetime) occurred THIS WEEK. As in, since Sunday morning at midnight.
To get THIS MONTH was easy:
and year(eci.CheckInDate) = year(getdate())
and month(eci.CheckInDate) = month(getdate())
...but there is no "week" function similar to MONTH() and YEAR(). Can someone give me a code example on how to do this?
Got it:
AND eci.CheckInDate > cast(dateadd(day,1-datepart(dw, getdate()), getdate()) as date)
Here is a solution that can be used to do what you want:
declare #WeekStart datetime = dateadd(week, datediff(week, 0, GetDate()), 0)
select #WeekStart
It's simpler than it looks. Here's what it is doing:
Add to week 0 the number of weeks from 0 to now.
Simple yet effective.
By the way, you can use the same method for truncating to second, minute, hour, day, week, month, quarter, etc.