turn on suggestions

Auto-suggest helps you quickly narrow down your search results by suggesting possible matches as you type.

Showing results for

Find a Community

- Home
- /
- SAS Programming
- /
- Base SAS Programming
- /
- how sas can read these dates?

Topic Options

- RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

07-24-2008 04:04 AM

data san;

input @ 1 from_dt date9. @ 11 to_date date10. ;

cards ;

01jan1382 01jan20001

01jan1082 01dec20001

01jan1882 01jan20000

01jan1582 01jan2001

;

run ;

input @ 1 from_dt date9. @ 11 to_date date10. ;

cards ;

01jan1382 01jan20001

01jan1082 01dec20001

01jan1882 01jan20000

01jan1582 01jan2001

;

run ;

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to Pavan_SAS

07-24-2008 08:33 AM

I think that you are SOL. From the SAS Base documentation:

SAS date value

is a value that represents the number of days between January 1, 1960, and a

specified date. SAS can perform calculations on dates ranging from A.D. 1582 to

A.D. 19,900.

The reason for this is that, when the dates are stored as durations, that range is the widest that can be precisely expressed in real number format in 8 bytes.

Doc Muhlbaier

Duke

SAS date value

is a value that represents the number of days between January 1, 1960, and a

specified date. SAS can perform calculations on dates ranging from A.D. 1582 to

A.D. 19,900.

The reason for this is that, when the dates are stored as durations, that range is the widest that can be precisely expressed in real number format in 8 bytes.

Doc Muhlbaier

Duke

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to Doc_Duke

07-25-2008 01:37 AM

i know this !

but for my one of the project i have to play with such type of dates.

now how can i handle this?

no solution in sas?

but for my one of the project i have to play with such type of dates.

now how can i handle this?

no solution in sas?

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to Pavan_SAS

07-25-2008 07:55 AM

I believe there is no solution period. Here is why, the calendar used today is the Gregorian Calendar which came into effect in 1582 AD (hmm where have we seen that before?), which most likly why SAS uses that as the date floor. Before the Gregorian Calendar the western world used the Julian Calendar which among other things treats leap days, number of days in a month different than the calendar used today. Hence a monday could be a tuesday if you compare a Julian date with a Gregorian date and the year could have a different number of days.

Gregorian dates before 1582 use something called the proleptic Gregorian calendar. Unfortunately, I don't SAS can use that calendar (there may be a custom calendar functionality but I don't know about it) Since SAS dates will not go before 1582, you will have to find a custom solution.

My first suggestion would be to find Julian day number to Gregorian mapping table (GOOGLE it and see what you find) and treat the days as integers and not dates. A Julian day number is not the same thing as the Julian Calendar it is the number days since 1/14713 BC, not sure why that day was picked . You will have to construct your own "date" format to display it. Just a guess, I haven't tried to go that far back in time with SAS.

I wish I could be more helpful.

-Darryl

Gregorian dates before 1582 use something called the proleptic Gregorian calendar. Unfortunately, I don't SAS can use that calendar (there may be a custom calendar functionality but I don't know about it) Since SAS dates will not go before 1582, you will have to find a custom solution.

My first suggestion would be to find Julian day number to Gregorian mapping table (GOOGLE it and see what you find) and treat the days as integers and not dates. A Julian day number is not the same thing as the Julian Calendar it is the number days since 1/14713 BC, not sure why that day was picked . You will have to construct your own "date" format to display it. Just a guess, I haven't tried to go that far back in time with SAS.

I wish I could be more helpful.

-Darryl

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to darrylovia

07-25-2008 04:35 PM

Hi:

Oh, my, I had NO idea there was this much possibility of variation in dates. These make for interesting reading and the last link has a formula and some lookup tables.

http://quasar.as.utexas.edu/BillInfo/JulianDatesG.html

http://charon.nmsu.edu/~lhuber/leaphist.html

http://www.decimaltime.hynes.net/dates.html

http://www.decimaltime.hynes.net/convert.html (has a Gregorian to Julian conversion formula)

cynthia

Oh, my, I had NO idea there was this much possibility of variation in dates. These make for interesting reading and the last link has a formula and some lookup tables.

http://quasar.as.utexas.edu/BillInfo/JulianDatesG.html

http://charon.nmsu.edu/~lhuber/leaphist.html

http://www.decimaltime.hynes.net/dates.html

http://www.decimaltime.hynes.net/convert.html (has a Gregorian to Julian conversion formula)

cynthia

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to Pavan_SAS

07-27-2008 05:16 AM

Hi Pavan.

I would try something quite different : store separately day, month & year instead of trying to build a real date. You can compute durations (though it will be a little more complicated that using built-in SAS function) but usually this is enough to get trhough common needs.

[pre]

proc format ;

invalue months

"jan" = 1

"feb" = 2

"mar" = 3

"apr" = 4 /* and so on */

"dec" = 12

;

run ;

data san;

input @1 from_dd 2. from_mm months. from_yy 4. @11 to_dd 2. to_mm months. to_yy :5. ;

cards ;

01jan1382 01jan20001

01jan1082 01dec20001

01jan1882 01jan20000

01jan1582 01jan2001

;

run ;

[/pre]

Regards.

Olivier

I would try something quite different : store separately day, month & year instead of trying to build a real date. You can compute durations (though it will be a little more complicated that using built-in SAS function) but usually this is enough to get trhough common needs.

[pre]

proc format ;

invalue months

"jan" = 1

"feb" = 2

"mar" = 3

"apr" = 4 /* and so on */

"dec" = 12

;

run ;

data san;

input @1 from_dd 2. from_mm months. from_yy 4. @11 to_dd 2. to_mm months. to_yy :5. ;

cards ;

01jan1382 01jan20001

01jan1082 01dec20001

01jan1882 01jan20000

01jan1582 01jan2001

;

run ;

[/pre]

Regards.

Olivier

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to Olivier

07-28-2008 01:00 AM

by using this, i can read this dates into sas.

but to do some analysis like date difference and something, how i can do?

if these dates will enter into sas dataset, like numer of dates from 1jan1960,

then it is good to do some analysis!

i want to take these dates as no. of days from 1jan1960.

but to do some analysis like date difference and something, how i can do?

if these dates will enter into sas dataset, like numer of dates from 1jan1960,

then it is good to do some analysis!

i want to take these dates as no. of days from 1jan1960.

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to Pavan_SAS

07-28-2008 05:21 AM

i got the solution !

data san;

length from_dt to_date $10;

input from_dt $ : to_date $ : ;

if input(substr(from_dt,6),best.) lt 1582 then do;

days_in_loop=0;

days_till_1582='01jan1582'd;

do i=input(substr(from_dt,6),best.) to 1581;

if mod(i,4)=0 then days_in_year=366;

else days_in_year=365;

days_in_loop=days_in_loop-days_in_year;

end;

from_dt1=days_till_1582+days_in_loop;

end;

else from_dt1=input(from_dt,date9.);

to_date1=input(tranwrd(to_date,'000','00'),date9.);

keep to: from: ;

cards ;

01jan1382 01jan20001

01jan1082 01dec20001

01jan1882 01jan20000

01jan1582 01jan2001

01jan1581 01jan20003

;

run ;

data san;

length from_dt to_date $10;

input from_dt $ : to_date $ : ;

if input(substr(from_dt,6),best.) lt 1582 then do;

days_in_loop=0;

days_till_1582='01jan1582'd;

do i=input(substr(from_dt,6),best.) to 1581;

if mod(i,4)=0 then days_in_year=366;

else days_in_year=365;

days_in_loop=days_in_loop-days_in_year;

end;

from_dt1=days_till_1582+days_in_loop;

end;

else from_dt1=input(from_dt,date9.);

to_date1=input(tranwrd(to_date,'000','00'),date9.);

keep to: from: ;

cards ;

01jan1382 01jan20001

01jan1082 01dec20001

01jan1882 01jan20000

01jan1582 01jan2001

01jan1581 01jan20003

;

run ;

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to Pavan_SAS

10-15-2008 07:24 AM

Your leepyear algorithm is too crude - it is not simply every 4 years. Can't recall the exact rules, but did code it up once. A quick google should help you out

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to jbhan

08-04-2011 11:52 AM

Leapyears are every four years EXCEPT for century years which are only leapyears if they are divisible by 400. So, 2012 is a leap year (divisible by 4), 1900 was not a leapyear (it was a century year but was not divisible by 400), 2000 was a leapyear (century year divisible by 400).

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to DouglasMartin

08-05-2011 12:04 PM

Although --- this is a bit off topic by now, since I'm fairly certain that darrylovia's answer means that treating the days before 1582 as if they came from current-day calendar practices is essentially wrong ... I thought I'd share my leap year code logic (operates on the year in four digits ... so you'd need to get the year from the SAS date value first):

/* The following is the beginning snippet of code that defines a year as a leap year */

IF (MOD(YEAR,100) NE 0 AND MOD(YEAR,4) EQ 0) OR (MOD(YEAR,400) EQ 0) THEN

... I think this handles when leap years occur in the modern calendar.