saber que porque hay fue cuatro como caracteristicas calculadora cada bisiestos bisiesto años año date sas

date - que - No válido de la fecha del ''año bisiesto'' de SAS yymmdd8



porque hay años bisiestos cada cuatro años (4)

Aquí hay un gran consejo de SCONSIG. enlazar

/******************************************************************/ /***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 ***/

Es posible incorporar esto en su carga de una forma u otra.

Estoy leyendo algunos datos sin procesar que tienen un par de fechas malas. Específicamente, alguien ha ingresado "29 de febrero" en un año NO bisiesto. Por ejemplo:

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

Al cliente le gustaría que esto vuelva al 28 de febrero. ¿Existe un método rápido / eficiente para hacer esto? por ejemplo, un equivalente de:

IF iserror (date) then date = date-1; ?

¡Cualquier sugerencia recibida con gratitud!


Esto no es bonito y hay notas de conversión, pero funciona y no falla.

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;

Salida:

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


Versión ligeramente modificada (creo) de la respuesta anterior. Sin embargo, evita los mensajes de error con el "??" en la función de entrada.

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;


Sería un poco más cuidadoso arreglando fechas. aquí hay una manera. hth.

%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. */