How do you find the first date of the week in SAS from a date? - date

I have a variable in a SAS dataset that has a number of dates (e.g. 01APR21). What I'm looking to do is create a new variable that shows the date of the first Monday of that week. So using the above example of 01APR21, the output would be 29/03/2021 as that what was when the Monday in that week was. I'm assuming it's using intnx, but I can't get my head around it.
data test;
format date date8.;
format first_day date10.;
date = '01APR21'd;
first_day = ?;
run;

INTNX Parameters:
Interval : WEEK
Increment: 0 (same week)
Alignment: Beginning
(Sunday)
Then add 1 to get to Monday instead of Sunday. You could probably play with the SHIFT INDEX parameter as well.
Monday = intnx('week', dateVariable, 0, 'B') + 1

Related

Subtracting 1 ISO 8601 year from a date in BigQuery

I'm trying to manipulate a date value to go back in time exactly 1 ISO-8601 year.
The following does not work, but best describes what I want to accomplish:
date_add(date '2018-01-03', interval -1 isoyear)
I tried string conversion as an intermediate step, but that doesn't work either:
select parse_date('%G%V%u',safe_cast(safe_cast(format_date('%G%V%u',date '2018-01-03') as int64)-1000 as string))
The error provided for the last one is "Failed to parse input string "2017013"". I don't understand why, this should always resolve to a unique date value.
Is there another way in which I can subtract an ISO year from a date?
This gives the corresponding day of the previous ISO year by subtracting the appropriate number of weeks from the date. I based the calculation on the description of weeks per year from the Wikipedia page:
CREATE TEMP FUNCTION IsLongYear(d DATE) AS (
-- Year starting on Thursday
EXTRACT(DAYOFWEEK FROM DATE_TRUNC(d, YEAR)) = 5 OR
-- Leap year starting on Wednesday
(EXTRACT(DAY FROM DATE_ADD(DATE(EXTRACT(YEAR FROM d), 2, 28), INTERVAL 1 DAY)) = 29
AND EXTRACT(DAYOFWEEK FROM DATE_TRUNC(d, YEAR)) = 4)
);
CREATE TEMP FUNCTION PreviousIsoYear(d DATE) AS (
DATE_SUB(d, INTERVAL IF(IsLongYear(d), 53, 52) WEEK)
);
SELECT PreviousIsoYear('2018-01-03');
This returns 2017-01-04, which is the third day of the 2017 ISO year. 2018-01-03 is the third day of the 2018 ISO year.

SAS date swap year and day

I am working with a dataset containing a date variable with the format MMDDYY10..
The problem is, that the day, month and the year have been swapped.
The data set as it looks now:
Obs Date
1 11/01/1931
2 11/06/1930
3 12/02/2003
4 12/07/2018
What I would like is a date variable with the format DDMMYY10., or a similar:
Obs Date
1 31/01/2011
2 30/06/2011
3 03/02/2012
4 18/07/2012
Observation 1 is hence written as the 1st of November 1931, but really it is the 31st of January 2011.
Does anyone know how I can change this?
Looks like you read the original raw data using the wrong INFORMAT. Most likely you had data in YYMMDD format and you read it as MMDDYY. You can use the PUT() and INPUT() functions to attempt to reverse it.
data have ;
input date mmddyy10.;
newdate = input(put(date,mmddyy6.),yymmdd6.);
format date newdate yymmdd10. ;
put (date newdate) (=);
cards;
11/01/1931
11/06/1930
12/02/2003
12/07/2018
;;;;
Results:
date=1931-11-01 newdate=2011-01-31
date=1930-11-06 newdate=2011-06-30
date=2003-12-02 newdate=2012-02-03
date=2018-12-07 newdate=2012-07-18

MS Access 2010 (Design View): return Monday of the current week with Monday as 1st day of the week

I need to make my Access query always return the Monday of the current week. I have seen a few solutions on Google/StackOverflow but they are written in SQL and I am a beginner in creating Access queries (I am using the Design view to make them).
Goal: The week should be considered as M T W T F S S. Then, the query should always return the Monday of the current week. Therefore, if it is Sunday, it should still return the Monday before, NOT the next week's Monday. Can anyone explain how to do this using the Design View in Access 2010?
Keep in mind that in this context we are working with dates, so if we do Date() - 1, we will get 1 day prior to today.
Date() ~ Today's date
DatePart(
"w" - Weekday
Date() - Today's date
2 - vBMonday (Access assumes Sunday is the first day of the week, which is why this is necessary.)
1 - vbFirstJan1 - This gets into using the first week of the year. We could have omitted this, as 1 is the default.
)
-1 - Subtract 1 from the DatePart value.
Values
Date() = 4/27/2015 (at time of this writing)
DatePart("w",Date(),2,1) = 1
DatePart("w",Date(),2,1)-1 = 0
So we have Date()-0... Okay, what's so great about that? Well, let's look at a more useful scenario where today's date is a day other than Monday.
Let's act like today is 4/28/2015 (Tuesday)
Date() = 4/28/2015
DatePart("w",Date(),2,1) = 2
DatePart("w",Date(),2,1)-1 = 1
So, from the outside, in; give me the current weekday value. (1 = Monday, 2 = Tuesday, etc.), and subtract 1 from that -> that's how many days we need to subtract from the current date to get back to the weekday value of 1 (Monday).
Here's a function that will do this:
Public Function DatePrevWeekday( _
ByVal datDate As Date, _
Optional ByVal bytWeekday As VbDayOfWeek = vbMonday) _
As Date
' Returns the date of the previous weekday, as spelled in vbXxxxday, prior to datDate.
' 2000-09-06. Cactus Data ApS.
' No special error handling.
On Error Resume Next
DatePrevWeekday = DateAdd("d", 1 - Weekday(datDate, bytWeekday), datDate)
End Function
As vbMonday is 2 and your date is today, you can use the core expression in a query:
PreviousMonday: DateAdd("d",1-Weekday(Date(),2),Date())

Finding last Sunday and going 4 weeks backward every week in SAS

I have a SAS job that runs every Thursday, but sometime it need to run on Wednesday, and maybe Tuesday evening. The job collects some data in 4 week intervals up until the closest Sunday. For example, today we have 19Mar2015, and I need data until 15Mar2015.
data get_some_data;
set all_the_data;
where date >= '16Feb2015' and date <= '15Mar2015';
run;
Next week I have to manually change the date parameters too
data get_some_data;
set all_the_data;
where date >= '23Feb2015' and date <= '22Mar2015';
run;
Anyway I can automate this?
I'll expand on the suggestion from #user667489 as it could take you a while to work it out. The key is to use the week time interval, which by default starts on a Sunday (you can change this with a shift index, read this for further details)
So your query just needs to be :
where intnx('week',today(),-4)<date<=intnx('week',today(),0);
Use the INTNX function to regress the date back to last Sunday:
data get_some_data;
set all_the_data;
lastsun=intnx('week',today(),0);
/*where date >= '23Feb2015' and date <= '22Mar2015';*/
where date between lastsun-27 and lastsun;
run;
You can try getting the last sunday date using weekday function and then using INTNX get the 4 week back date from that sunday date. Check the below ref code :
data mydata;
input input_date YYMMDD10.;
/* Loop to get the last sunday date, do the processing
and get out of loop */
do i =0 to 7 until(last_sunday_date>0);
/* Weekday Sunday=1 */
if weekday(sum(input_date,-i))=1 then do;
last_sunday_date=sum(input_date,-i);
/* INTNX to get the 4 week back date */
my_4_week_start=intnx('week',last_sunday_date,-4);
end;
end;
format input_date last_sunday_date my_4_week_start yymmdd10.;
datalines4;
2015-03-01
2015-03-07
2015-03-14
2015-03-21
2015-03-28
2015-04-05
2015-04-13
2015-04-20
;;;;
run;
proc print data=mydata;run;
let me know if this helps!

Check if the difference between dates is exactly 'n' months in expression SSRS

In my quarterly report Im trying to validate the two parameters StartDate and EndDate.
I first check if the difference between the dates is 2 months:
Switch(DateDiff(
DateInterval.Month, Parameters!StartDate.Value, Parameters!EndDate.Value) <> 2,
"Error message")
Then I try to add whether the StartDate is the first day of month AND EndDate is last day of month:
And (Day(Parameters!StartDate.Value) <> 1
And Day(DATEADD(DateInterval.Day,1,Parameters!EndDate.Value)))
So the whole expression looks like this:
Switch(DateDiff(DateInterval.Month, Parameters!StartDate.Value, Parameters!EndDate.Value) <> 2
And
Parameters!IsQuarterly.Value = true
And
Day(Parameters!StartDate.Value) <> 1
And
Day(DATEADD(DateInterval.Day,1,Parameters!EndDate.Value))<>1),
"Error: Quarterly report must include 3 months")
But It works wrong when the difference between dates is still 2 months, but StartDate and EndDate are not first and last day of the whole period.
I'd appreciate any help :)
I would say just change the implementation Add another two Parameter With Quarter and Year
Quarter like Q1,Q2,Q3 & Q4 with Value 1,2,3 & 4 respectively and year 2012,2013,2014 & so on
Now based on the parameter selected Qtr & Year set Default value of start & End Date
=DateSerial(Parameters!Year.Value), (3*Parameters!Qtr.Value)-2, 1) --First day of Quarter
=DateAdd("d",-1,DateAdd("q",1,Parameters!Year.Value, (3*Parameters!Qtr.Value)-2, 1))) --Last day of quarter
Doing this no need to do any validation bcz its always get the correct Date Difference.
Other Reference
First day of current quarter
=DateSerial(Year(Now()), (3*DatePart("q",Now()))-2, 1)
Last day of current quarter
=DateAdd("d",-1,DateAdd("q",1,DateSerial(Year(Now()), (3*DatePart("q",Now()))-2, 1)))