BookmarkSubscribeRSS Feed
Vassy
Calcite | Level 5

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?

5 REPLIES 5
Tom
Super User Tom
Super User

Please read the documentation on the option.  It has a pretty complete explanation of how it works.

https://documentation.sas.com/?docsetId=lesysoptsref&docsetTarget=n0yt2tjgsd5dpzn16wk1m3thcd3c.htm&d...

 

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.

 

Vassy
Calcite | Level 5

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;

Tom
Super User Tom
Super User
YEARCUTOFF=2000 means you want dates from 2000 to 2099. Is that what you want?
Usually you want to set YEARCUTOFF to something like the current year minus 100 plus some small number for the number of years into the future your dates might have.
options yearcutoff=%eval(%sysfunc(today(),year4.)-95);
ballardw
Super User

@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;

ballardw
Super User

@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.

Ready to join fellow brilliant minds for the SAS Hackathon?

Build your skills. Make connections. Enjoy creative freedom. Maybe change the world. Registration is now open through August 30th. Visit the SAS Hackathon homepage.

Register today!
How to Concatenate Values

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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 5 replies
  • 871 views
  • 2 likes
  • 3 in conversation