BookmarkSubscribeRSS Feed

I would like the year,month and day to work on datetime variable as well as date variables.

18 Comments
Kurt_Bremser
Super User

As a workaround, create a macro wrapper:

%macro dtday(dt);
day(datepart(&dt.))
%mend;

data test;
day = %dtday(datetime());
run;
PaigeMiller
Diamond | Level 26

How would the function know if it was supposed to work on a date or datetime? Are you suggesting that there be an additional argument to the function that indicates that it is supposed to work in datetime mode?

Patrick
Opal | Level 21

@PaigeMiller Can't recall where it applies but I'm certain there is "somewhere" functionality which switches treating a numerical value as SAS date to treating it as a SAS datetime based on some threshold. Given that there is no data type providing this information I always felt this to be a bit "doggy". Does anyone know where this applies? I'm rather certain that such functionality exists "somewhere" (eventually just some informat).

@rudfaden What @Kurt_Bremser proposes will work. Just use the datepart() function on SAS Datatime values. This will convert your SAS datetime values to SAS date values.

PaigeMiller
Diamond | Level 26

I agree with you @Patrick , integer values such as 20000 could be either valid SAS dates or valid SAS datetimes, and I wouldn't want SAS guessing whether this is a date or a datetime. Furthermore this change could wreak havoc on existing programs, unless it was done via adding an optional parameter to the function call.

Kurt_Bremser
Super User

The simplest thing to do (if one needs this at all) would be to set up new functions DTDAY, DTMON and DTYEAR that do what I did in the macro. This is easier to handle (at least for me) than an optional parameter in the existing functions. Furthermore, there is already an example for this, the DT... formats that are equivalent to their date-related counterparts.

rudfaden
Lapis Lazuli | Level 10

Dear All.

 

I am well aware of all the soutions to the problem. I just think it is a wird and unexpected that the functions does not work with datetime values. I work i a very large company where a part of my job is to offer support for SAS users. I regulary get the question why does year/month/day not work for datetime.

Kurt_Bremser
Super User

The question can only arise from people who do not understand/know the difference between date and datetime values. As soon as someone has internalized that dates are counts of days and datetimes are counts of seconds, the question is moot. As already stated, simply making the function accept datetime values is impossible, as there are ranges where plausible date values are also plausible datetimes:

x1 = '31dec9999'd;
put x1=;
put x1= datetime19.;
run;

So, I repeat: only someone who does not know the difference between SAS dates and SAS datetimes can be surprised by the fact that DAY() does not work with a datetime value. It seems that your SAS users have not been trained adequately.

yabwon
Onyx | Level 15

One more approach would be to use the FCMP procedure (with @Kurt_Bremser warning about the date and the datetime overlap in mind, date has priority. For dates above February 3rd, 1960 there should be no conflict)

data _null_;
x1 = '31dec9999'd;
put x1=;
put x1= datetime19.;
run;


proc fcmp outlib = work.f.p;
  function dtday(dt);
    if dt <= '31dec9999'd 
      then return (day(dt));
      else return (day(datepart(dt)));
  endsub;
  function dtmonth(dt);
    if dt <= '31dec9999'd 
      then return (month(dt));
      else return (month(datepart(dt)));
  endsub;
  function dtyear(dt);
    if dt <= '31dec9999'd 
      then return (year(dt));
      else return (year(datepart(dt)));
  endsub;
run;


options cmplib = work.f;
data test;
  d = datetime();
  put d= datetime21.;
  day = dtday(d);
  month = dtmonth(d);
  year = dtyear(d);
  put (_all_) (=);
run;

I also agree with Kurt's "only someone who does not know the difference between SAS dates and SAS datetimes can be surprised by the fact that DAY() does not work with a datetime value" statement.

 

Bart

rudfaden
Lapis Lazuli | Level 10
Why could a function not account for this difference?
PaigeMiller
Diamond | Level 26

Of course a function could account for this difference, if SAS chooses to make it so, which so far they have not.

 

I personally would rather explain to the programmers in my company how dates and datetimes work, and have SAS spend their time on more important and more valuable things.