| Date: | Tue, 1 Jun 2004 08:13:51 -0500 |
| Reply-To: | "Dunn, Toby" <tdunn@TEA.STATE.TX.US> |
| Sender: | "SAS(r) Discussion" <SAS-L@LISTSERV.UGA.EDU> |
| From: | "Dunn, Toby" <tdunn@TEA.STATE.TX.US> |
| Subject: | Re: How to save the formatted value of a date |
|
| Content-Type: | text/plain; charset="us-ascii" |
Chang,
Don't feel to bad I figure most of us have at one time or another been
corrected by the great grand mast Ian. I treat it as a great learning
experience. Besides when ever Ian corrects me I am just glad that he
even reads my solutions.
Toby Dunn
-----Original Message-----
From: SAS(r) Discussion [mailto:SAS-L@LISTSERV.UGA.EDU] On Behalf Of
Chang Y. Chung
Sent: Tuesday, June 01, 2004 8:11 AM
To: SAS-L@LISTSERV.UGA.EDU
Subject: Re: How to save the formatted value of a date
On Mon, 31 May 2004 19:08:13 +0000, Ian Whitlock <iw1junk@COMCAST.NET>
wrote:
>On Friday, in response to a Mark Biek
><markb@STEVENSONCOMPANY.COM>
>question about getting dates one week later in formatted form,
>"Chang Y. Chung" <chang_y_chung@HOTMAIL.COM> wrote
>a neat little one liner:
>
>%macro WeekLater(date, week=1, informat=date.,
> format=date.);
>%*-- by chang y. chung on 2004-05-28 --*;
>%*;%sysfunc(putn(%eval(%sysfunc(inputn(&date,&informat.)) +
>(&week.*7)),&format.))
>%mend;
>
>However his tests:
>
>/* usage examples */
>%put NOTE: today : %WeekLater(%sysfunc(today(),
>
date.),
week=0);
>%put NOTE: One week later : %WeekLater('28may2004'd);
>%put NOTE: Two weeks later: %WeekLater(%WeekLater
>
('28may2004'd));
>%put NOTE: One week Later : %WeekLater('28may2004'd,
>
format=mmddyyd10.);
>%put NOTE: One week before: %WeekLater('29may2004'd,
>
week=-1);
>
>produced:
>
>/* on log
>NOTE: today : 28MAY04
>NOTE: One week later : 04JUN02
>NOTE: Two weeks later: 11JUN02
>NOTE: One week Later : 06-04-2002
>NOTE: One week before: 22MAY02
>*/
>
>
>I found it rather scary to see all those dates in the year 2002
>which were suppose to be within 2 weeks of may 28, 2004. I
>never did discover why values were producedI also introduced
>many errors in trying to understand what went wrong.
>
>Here is a more complex form of Chang's macro that returns the
>word ERROR with various incorrect calls to the macro.
>
>%macro WeekLater( date
> , week=1
> , informat=date.
> , format=date.
> );
> %local dt x len ret ;
> %if %index(&date,%str(%'))
> or %index(&date,%str(%")) %then
> %let ret = ERROR ;
> %let x = %sysfunc(indexc(&informat,0123456789)) ;
>
> %if not &x %then
> %do ;
> %if %upcase(&informat) = DATE. %then
> %let len = 7 ;
> %else
> %let len = 8 ;
> %end ;
> %else
> %let len = %sysevalf(%substr(&informat,&x),integer) ;
> %if &len ^= %length(&date) %then
> %let ret = ERROR ;
>
> %if %length(&ret) = 0 %then
> %do ;
> %let dt = %sysfunc(inputn(&date,&informat)) ;
> %if &dt = . %then
> %let ret = ERROR ;
> %else
> %let ret = %sysfunc(putn(%eval(&dt+
>
(&week.*7)),&format)) ;
> %end ;
>
> &ret
>
>%mend WeekLater;
>
>
>Here is my test code with incorrect and correct calls and the results.
>
>535 %put NOTE: One week later : %WeekLater(28may2004);
>NOTE: One week later : ERROR
>536 %put NOTE: One week later : %weekLater('28may2004'd) ;
>NOTE: One week later : ERROR
>537 %put NOTE: One week later : %WeekLater(28may04);
>NOTE: One week later : 04JUN04
>538 %put NOTE: One week later : %WeekLater(28may2004,informat=date9.);
>NOTE: One week later : 04JUN04
>539 %put NOTE: One week later : %WeekLater(28may04,format=mmddyyd8.);
>NOTE: One week later : 06-04-04
>
>Finally, here are the results for Chang's test code with the improved
macro.
>
>542 %put NOTE: today : %WeekLater(%sysfunc(today(),date.),
week=0);
>NOTE: today : 31MAY04
>543 %put NOTE: One week later : %WeekLater('28may2004'd);
>NOTE: One week later : ERROR
>544 %put NOTE: Two weeks later: %WeekLater(%WeekLater('28may2004'd));
>NOTE: Two weeks later: ERROR
>545 %put NOTE: One week Later : %WeekLater('28may2004'd,
format=mmddyyd10.);
>NOTE: One week Later : ERROR
>546 %put NOTE: One week before: %WeekLater('29may2004'd, week=-1);
>NOTE: One week before: ERROR
Hi,
I was such a wretched (and blind) man who committed multiple sins of
macro
programming only to be saved by Master Ian. Thank you very much. As
Master
Ian discovered, my macro could not handle date literals (eg. '28may04'd)
and should be given a string that could be read into a numeric variable
given an appropriate informat. Here is a corrected version and usage
examples.
Cheers,
Chang
%macro WeekLater(date, week=1, informat=date%length(&date.).,
format=date9.);
%*;%sysfunc(putn(%eval(%sysfunc(inputn(&date.,&informat.)) +
(&week.*7)),&format.))
%mend;
/* on log
%put NOTE: today: %WeekLater(%sysfunc(today(),date.), week=0);
NOTE: today: 01JUN2004
%put NOTE: one week later : %WeekLater(28may2004);
NOTE: one week later : 04JUN2004
%put NOTE: two weeks later: %WeekLater(%WeekLater(28may04));
NOTE: two weeks later: 11JUN2004
%put NOTE: one week later: %WeekLater(28may2004, format=mmddyyd10.);
NOTE: one week later: 06-04-2004
%put NOTE: one week before: %WeekLater(28may2004, week=-1);
NOTE: one week before: 21MAY2004
*/
|