Hi Fellas,
Sorry in advance if my question was already discussed here or it is not for this section.
System I am running my jobs: z/OS
I am new with SAS programming (more like a NOOB) but am trying to catch up, so thank you for your effort and thoughts in advance.
Issue:
Last two months I have data integrity issues. The data for JAN20 and FEB20 is treated as older them JAN2018 (data is stored only for the last two year).
==============
JAN20
FEB20
JAN18
FEB18
.
.
.
DEC19
==========
I was able to find that in SAS 9.3 and earlier, the default value of the YEARCUTOFF= option is 1920 and this is going to cause data integrity issues because any 2-digit years of "20" in dates will be assumed to be 1920 instead of 2020.
To check my SAS version I found that I need to code this in my JCL: PROC OPTIONS OPTION=YEARCUTOFF;
Actually I was really surprised to see the result: SAS 9.4 TS1M2 and the YEARCUTOFF=1960;
So my question is, if the YEARCUTOFF is 1960 not 1920, why my data from 2020 is treated as older then 2019 and 2018?
Usually I need the data only for the previous month so I use below:
IF MONTHYR GT '01JAN20'D;
but now I am collecting the data for the last 2 years. My workaround is to use LT '01JAN18'D, but this is collecting for JAN and FEB20 and I want only for February. If I try with EQ '01FEB20'D, I am not receiving the output data. I tried with:
IF MONTHYR LT '01JAN18'D;
IF MONTHYR NE '01JAN20;D; - but this is collecting the data for JAN20 and FEB20.
Last year I didn't face any issues during the transition from 2018 to 2019, so why now?
Please read the documentation on the option. It has a pretty complete explanation of how it works.
Find out where in your code or your system configuration the option is getting set to 1960. Note that your code does not need to use the option that your system administrator has set in the configuration files. You can change the option in your code using the OPTIONS statement.
A value of 1960 means that the range of years that SAS will use when it sees a year string value less than 100 will be from 1960 to 2059. That would be useful if the types of dates you are using are more likely to be for the future. Such as pay off dates for 30 year mortgages. Not very useful for reading birth dates.
Hi Tom,
I already tried with:
options yearcutoff=2000;
But I didn't receive the data.
Is there a way the issue to be related with the formatting? For example every 10 years the year with 0 to be moved on the top of the list.
Not sure if this will help you. The code is looking like this:
000013 OPTIONS SOURCE SOURCE2 NOMACROGEN NOSYMBOLGEN NOMLOGIC NOTES OVP
000014 NOERRORABEND NOCAPSOUT NOCAPS USER=WORK LABEL NODSNFERR S=72
000015 S2=72 LS=132 PS=60 ;
000016 OPTIONS YEARCUTOFF=2000;
000017
000018 * OPTIONS FMTSEARCH=(WORK.FORMATS P1OLIB.FORMATS
000019 OPTIONS FMTSEARCH=(WORK.FORMATS
000020 PMUOLIB.USERFMT1 PMUOLIB.MICSFMTS PMUOLIB.USERFMT2
000021 MCOLIB.USERFMT1 MCOLIB.MICSFMTS MCOLIB.USERFMT2
000022 LIBRARY.FORMATS);
000023 PROC FORMAT;
000024 PICTURE LARGE
000025 LOW -< 0 = 'NEGATIVE' (NOEDIT)
000026 0 - 9999 = '0,009.9 '
000027 10000 - 9999999 = '0,009.9K' (MULT=.01)
000028 10000000 - 9999999999 = '0,009.9M' (MULT=.00001)
000029 10000000000 - 9999999999999 = '0,009.9B' (MULT=.00000001);
000030 RUN;
@Vassy wrote:
Hi Tom,
I already tried with:
options yearcutoff=2000;
But I didn't receive the data.
Is there a way the issue to be related with the formatting? For example every 10 years the year with 0 to be moved on the top of the list.
Not sure if this will help you. The code is looking like this:
000013 OPTIONS SOURCE SOURCE2 NOMACROGEN NOSYMBOLGEN NOMLOGIC NOTES OVP
000014 NOERRORABEND NOCAPSOUT NOCAPS USER=WORK LABEL NODSNFERR S=72
000015 S2=72 LS=132 PS=60 ;
000016 OPTIONS YEARCUTOFF=2000;
000017
000018 * OPTIONS FMTSEARCH=(WORK.FORMATS P1OLIB.FORMATS
000019 OPTIONS FMTSEARCH=(WORK.FORMATS
000020 PMUOLIB.USERFMT1 PMUOLIB.MICSFMTS PMUOLIB.USERFMT2
000021 MCOLIB.USERFMT1 MCOLIB.MICSFMTS MCOLIB.USERFMT2
000022 LIBRARY.FORMATS);
000023 PROC FORMAT;
000024 PICTURE LARGE
000025 LOW -< 0 = 'NEGATIVE' (NOEDIT)
000026 0 - 9999 = '0,009.9 '
000027 10000 - 9999999 = '0,009.9K' (MULT=.01)
000028 10000000 - 9999999999 = '0,009.9M' (MULT=.00001)
000029 10000000000 - 9999999999999 = '0,009.9B' (MULT=.00000001);
000030 RUN;
The YEARCUTOFF really only comes into play when creating a value that uses a two digit year. Once the value has been set for a data set variable that value stays the same. You do not show any code creating values so it is kind of hard to say what is or isn't happening.
Likely you need to share some actual data.
Is there a way the issue to be related with the formatting? For example every 10 years the year with 0 to be moved on the top of the list.
This doesn't make any sense without some actual data and likely a lot of description.
You may want to use the word "layout" or "structure" relating the way a data set appears. "Format" in SAS is going to be interpreted as a format used to display values of a variable.
Perhaps this code may provide some help understanding the behavior. It shows what happens to the value of a variable created with a 2-digit year with different options for Yearcutoff. Then shows what displaying the value created with a different Yearcutoff looks like when you change the option value. Suggest that you reset the Yearcutoff after the example code.
options yearcutoff=2000; data junk; file print; put 'Example with yearcutoff=2000'; x='01JAN2018'd; y='01Jan40'd; put x= x=date9. y= y=date9.; run; options yearcutoff=1920; data _null_; file print; put 'Example with yearcutoff=1920'; x='01JAN2018'd; y='01Jan40'd; put x= x=date9. y= y=date9.; run; options yearcutoff=1960; data _null_; file print; put 'Example with yearcutoff=1960'; x='01JAN2018'd; y='01Jan40'd; put x= x=date9. y= y=date9.; run; options yearcutoff=1820; data _null_; file print; put 'Example with yearcutoff=1820'; x='01JAN2018'd; y='01Jan40'd; put x= x=date9. y= y=date9.; run; proc print data=junk; title "Values of the variables created with Yearcutoff=2000"; title2 "Displayed when Yearcutoff=1820"; format x y date9.; run; title;
@Vassy wrote:
Hi Fellas,
Sorry in advance if my question was already discussed here or it is not for this section.
System I am running my jobs: z/OS
I am new with SAS programming (more like a NOOB) but am trying to catch up, so thank you for your effort and thoughts in advance.
Issue:
Last two months I have data integrity issues. The data for JAN20 and FEB20 is treated as older them JAN2018 (data is stored only for the last two year).
==============
JAN20
FEB20
JAN18
FEB18
.
.
.
DEC19
==========
I was able to find that in SAS 9.3 and earlier, the default value of the YEARCUTOFF= option is 1920 and this is going to cause data integrity issues because any 2-digit years of "20" in dates will be assumed to be 1920 instead of 2020.
To check my SAS version I found that I need to code this in my JCL: PROC OPTIONS OPTION=YEARCUTOFF;
Actually I was really surprised to see the result: SAS 9.4 TS1M2 and the YEARCUTOFF=1960;
So my question is, if the YEARCUTOFF is 1960 not 1920, why my data from 2020 is treated as older then 2019 and 2018?
Usually I need the data only for the previous month so I use below:
IF MONTHYR GT '01JAN20'D;
but now I am collecting the data for the last 2 years. My workaround is to use LT '01JAN18'D, but this is collecting for JAN and FEB20 and I want only for February. If I try with EQ '01FEB20'D, I am not receiving the output data. I tried with:
IF MONTHYR LT '01JAN18'D;
IF MONTHYR NE '01JAN20;D; - but this is collecting the data for JAN20 and FEB20.
Last year I didn't face any issues during the transition from 2018 to 2019, so why now?
I would also suggest that any time you use a date literal that you use a 4 digit year for clarity. May not help with dates that have been created incorrectly when reading because of the two digit year but at least it is clearer for your intent.
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!
Learn how use the CAT functions in SAS to join values from multiple variables into a single value.
Find more tutorials on the SAS Users YouTube channel.