Date: Tue, 9 Apr 1996 09:44:16 -0500
Reply-To: Dwight Eggers <eusdee1@EXU.ERICSSON.EDU>
Sender: "SAS(r) Discussion" <SAS-L@UGA.CC.UGA.EDU>
From: Dwight Eggers <eusdee1@EXU.ERICSSON.EDU>
Organization: Ericsson Inc.
Subject: Re: Week number calculation?
Juha Kari wrote:
>
> Is there a ready-to-run function to calculate the week number for a certain
day (today)?
>
> Juha Kari
Following is a PROC FORMAT approach for dealing with weeks which I
developed to handle a convention in my company of dates being
represented on input/output to/from sas as year-week values -- for
example, Monday, April 8, 1996 is represented as 9615 (the 15th week
of year 96). The purpose is to keep date values in sas internal
numeric representations of a date, even though i/o is sometimes in
this year-week format.
Dwight Eggers
Ericsson USA
eusdee1@exu.ericsson.se
* Create value/invalue formats to convert between SAS dates and ;
* year-week values. The convention is that a week starts on a Monday,;
* and the first week of the year contains more than three week days ;
* -- i.e., if Jan 1. falls on a Sunday-Wednesday, week #1 of that year;
* begins on Monday of that week / if it falls on a Thursday-Saturday, ;
* week #1 begins on Monday of the following week. ;
*;
* The benefit of using this format is that all dates, whether actual ;
* date or year-week, are carried in sas internal date (numeric) ;
* representatations, yet week values are converted from/to the desired;
* format on input/output. By this approach, it is much easier to ;
* handle the date axes of graphs. A more long-term benefit is when ;
* we get closer to the year 2000 and have projects that span ;
* centuries, from 9952-0001, sorting on date will function properly. ;
*;
* Usage: ;
* 1) To read a year-week value, use the YRWK informat, e.g. ;
* yw=input('9604',yrwk4.) , or ;
* input . . . yw yrwk4. . . . ;
* ;
* 2) To display year-week value on output, use the YRWK format, e.g.;
* text=put('25Jan96'D,yrwk4.) yields text='9604' ;
* ;
* 3) To classify a date to its appropriate yearweek -- in other ;
* words, to round a date to its preceeding Monday when it is not ;
* a Monday -- use the round function ;
* yw=round(date+1,7.)-4 ;
* The '+1' and '-4' are needed to reconcile the base of the sas ;
* date convention (0==Friday, Jan 1, 1960) with the Ericsson ;
* convention of Monday being the 1st day of a year-week. ;
* The effect of this step is to convert the date to the ;
* preceeding Monday, unless it is already a Monday. ;
* A more readable form of this operation is the macro call ;
* yw=%d2yw(date) ;
* convert low 2-digit year values to 21st century ;
option yearcutoff=1950;
* library in which to store this format;
%let fmtlib=library;
* determine the Monday of the start of each year from 1992 to 2010;
data t1;
attrib year length=8 label='2-digit year';
attrib day1 length=8 label='SAS day value of Monday of start of year'
format=date7.;
keep year day1;
do year=92 to 99, 00 to 10;
day1=mdy(1,1,year);
dofweek=weekday(day1);
if dofweek<=4 then day1=day1-dofweek+2;
else day1=day1-dofweek+9;
output;
end;
run;
* interpolate the date range of each week of these years;
data ywin (keep=fmtname type default max start label)
ywout (keep=fmtname type default max start end sexcl eexcl label) ;
set t1 end=done;
retain fmtname 'YRWK' sexcl 'N' eexcl 'Y' default max 4;
length label $6 ;
year=lag1(year);
day0=lag1(day1);
if _n_=1 then return;
week=0;
do day=day0 to (day1-1) by 7;
week+1;
cyrwk=put((100*year+week),z4.);
daymax=day + 7;
* YRWK format;
type='N';
start=put(day,6.);
end =put(daymax,6.);
label=cyrwk;
output ywout;
* YRWK informats;
type='I';
start=cyrwk;
label=put(day,6.0);
output ywin;
end;
if done;
type='N';
start='OTHER';
label=' ';
output ywout;
type='I';
start='OTHER';
label='.';
output ywin;
run;
* informat for yrwk -> date conversion ;
proc format library=work cntlin=ywin; run;
* format for date -> yrwk conversion ;
proc format library=work cntlin=ywout; run;
* test these yrwk formats;
option linesize=100;
data _null_;
put; put "spanning start of 1996"; put;
do dd='20Dec95'd to '10Jan96'd;
weekday=put(dd,weekday1.);
yw=%d2yw(dd) ;
cyw=put(yw,yrwk.);
dd2=input(cyw,yrwk.);
put dd= 6.
dd= weekdate15.
weekday= 2.
yw= 6.
yw= weekdate15.
cyw= $4.
dd2= weekdate15.
;
end;
put; put "1st day of each year"; put;
do year=92 to 99, 0 to 10;
dd=mdy(1,1,year);
weekday=put(dd,weekday1.);
yw=%d2yw(dd) ;
cyw=put(yw,yrwk.);
dd2=input(cyw,yrwk.);
put dd= 6.
dd= weekdate15.
weekday= 2.
yw= 6.
yw= weekdate15.
cyw= $4.
dd2= weekdate15.
;
end;
run;