if you make a decision that "early years" are just the year number, you might want a user format that uses ranges. Here's a demo demonstrating why you might want to avoid using integer years [PRE]
proc format ;
picture older_ds /* handling older dates than SAS */
"1jan1582"d - <0 = [date9.]
0 - 1581 = '1234'( prefix='old~' )
1582 - "31dec9999"d = [date9.]
;
%put >>%sysfunc( putn( 1234, older_ds ))<<;
data demo;
do date = 1581,
"1jan1582"d to "1jan1960"d by 35000,
"1jan1870"d to "1jan1960"d by 7000,
"1jan1950"d to "1jan1960"d by 700,
-5 to 10,
1066, 1284, 1413,
1580 to 1590;
put date date= older_ds. ;
output ;
end;
run; [/PRE]
treating date values zero to 1581 as a year number loses regular SAS dates 1jan60 - 30Apr64 as old~years.
Using a suitable picture modifier multiplier would allow old~years to be placed above or below the valid SAS date number range .
Here's the picture for placing early~years above the valid sas date range with multiplier 1e-7. 10660000000 ( or 1066e7) is displayed as o:yr1066. Old~year date arithmetic is supported by doing the same as the picture "multiplier=" modifier, that is: dividing by 1e7 [PRE]
proc format ;
picture older_ds /* handling older dates than SAS */
1e7 - 1581e7 = '1234'( prefix='o:yr' mult= 1e-7 )
1582e7 -high = '1234'( prefix='2high' mult= 1e-7 )
other = [date9.]
;
run;
data demo;
do date = 1581,
"1jan1582"d to "1jan1960"d by 35000,
"1jan1950"d to "1jan1960"d by 700,
1066e7, 1284e7, 1413e7,
1580e7 to 1584e7 by 1e7,
1e7 to 10000010,
19999996 to 20000004,
2e7 to 1582e7 by (1e7*33)
;
put date date= older_ds. ;
output ;
end;
run; [/PRE]
as you can see, an old~year constant would appear as
1066e7
Given that SAS integers in standard 8byte numerics are precise to 16 or 17 digits, a 4 digit year and 7-zeros suffix are supported "precisely" .
What's the application that wants to use such history ?
Peter