SAS недействительна дата високосного года - PullRequest
4 голосов
/ 18 февраля 2009

Я читаю некоторые необработанные данные, у которых есть пара неверных дат. В частности, кто-то ввел «29 февраля» в високосный год. Например:

data _null_;
input test :yymmdd8.;
format test date9.;
cards;
20270229
run;

Клиент хотел бы, чтобы это вернулось к 28 февраля. Существует ли быстрый / эффективный способ сделать это? например, эквивалент:

IF iserror (date) затем date = date-1; ?

Любые предложения с благодарностью приняты!

Ответы [ 4 ]

4 голосов
/ 21 февраля 2009

Я бы немного более тщательно установил даты. вот один из способов. НТН.

%put sysvlong=&sysvlong sysscpl=&sysscpl;           
/* sysvlong=9.02.01M0P020508 sysscpl=W32_VSPRO */

/* read a date both as character(temp) and numeric(date).
   if the numeric date is missing then check if the
   character date ends with "0229," if so, then change it
   to "0228" and see if it is a valid date. 
   If OK, then that is it. otherwise, keep it missing. */
%let FEB29 = 0229; 
%let FEB28 = 0228;
data one;
  drop temp;
  input temp $char8. @1 date ?? yymmdd8.;
  if missing(date) then link fix;
  format date b8601da.;
  put (_all_) (=);
  return;
fix:
  if length(strip(temp))^=8 then return;
  if substr(temp,5) ^= "&FEB29" then return;
  date = input(cat(substr(temp,1,4), "&FEB28"), ?? yymmdd8.);
return;
cards;
20080229  ok
20090229  should be changed to 28th
201XX229  this should be missing
20110229  -> 28
20120229  ok 
20130229  -> 28
20270229  -> 28
;
run;

/* on log
temp=20080229 date=20080229
temp=20090229 date=20090228
temp=201XX229 date=.
temp=20110229 date=20110228
temp=20120229 date=20120229
temp=20130229 date=20130228
temp=20270229 date=20270228
NOTE: The data set WORK.ONE has 7 observations and 1 variables.
*/
3 голосов
/ 18 февраля 2009

Вот отличный совет от SCONSIG. ссылка

/******************************************************************/
 /***TIP00039.SAS                                                ***/
 /***   Leap Year Problem                                        ***/
 /***                                                            ***/
 /***   Most of us know that if the year is divisible by 4 then  ***/
 /***   that year is a Leap Year.  However, if the year is a     ***/
 /***   century year and is NOT divisible by 400 then that       ***/
 /***   century year is NOT A LEAP YEAR.                         ***/
 /***   (ie, 1700, 1800, 1900, 2100, 2200, 2300 are not LEAP     ***/
 /***        YEARS)                                              ***/
 /***                                                            ***/
 /******************************************************************/

 data leapyear;
   do year = 1600 to 2400 by 100;
    date = mdy(02,29,year);        /*** Leap Date                       ***/
    if date = . then do;           /*** If FEB 29th but not a Leap Year ***/
       date = mdy(03,01,year) - 1; /*** Make date March 1st and then    ***/
    end;                           /***   subtract 1 day                ***/
    output;
   end;
   format date mmddyy10.;
 run;

 proc print; run;

 /*** end of sas program - TIP00039 ***/

Возможно включить это в ваш груз тем или иным способом.

1 голос
/ 20 февраля 2009

Слегка измененная версия (мне кажется) ответа выше. Это избегает сообщений об ошибках, хотя с "??" в функции ввода.

data testit;
   format indate yymmdd10.;
   input x $8.;

   indate = input(x, ?? yymmdd8.);
   if indate=. then indate= input(put(x - 1, 8.), ?? yymmdd8.);


    put indate=;

cards;
20080229
20090229
20100229
20110229
20120229
20130229
20270229
run;
0 голосов
/ 20 февраля 2009

Это не красиво, и есть заметки о переходах, но это работает и не дает ошибок.

data testit;
   format test2 yymmdd10.;
   input x $8.;
   mod4 = mod(mod((substr(x,1,4)/4),4) * 10,10);   
   if mod4 NE 0 then x = x - 1;
   test2=input(x,yymmdd8.);
   put x= test2=;

cards;
20080229
20090229
20100229
20110229
20120229
20130229
20270229
run; 

Выход:

x=20080229 test2=2008-02-29
x=20090228 test2=2009-02-28
x=20100228 test2=2010-02-28
x=20110228 test2=2011-02-28
x=20120229 test2=2012-02-29
x=20130228 test2=2013-02-28
x=20270228 test2=2027-02-28
...