LISTSERV at the University of Georgia
Menubar Imagemap
Home Browse Manage Request Manuals Register
Previous messageNext messagePrevious in topicNext in topicPrevious by same authorNext by same authorPrevious page (August 2003)Back to main SPSSX-L pageJoin or leave SPSSX-L (or change settings)ReplyPost a new messageSearchProportional fontNon-proportional font
Date:         Fri, 1 Aug 2003 17:42:25 -0400
Reply-To:     Richard Ristow <wrristow@mindspring.com>
Sender:       "SPSSX(r) Discussion" <SPSSX-L@LISTSERV.UGA.EDU>
From:         Richard Ristow <wrristow@mindspring.com>
Subject:      Re: working with dates
Comments: To: amtmannd@comcast.net
In-Reply-To:  <200308011630.h71GUIE03955@listserv.cc.uga.edu>
Content-Type: text/plain; charset="iso-8859-1"; format=flowed

At 04:29 PM 8/1/2003 +0000, Dagmar Amtmann wrote:

>This is a really basic question. [...] I need to figure out how many >years, months, and days elapsed between two dates. When I use the >compute command the output provides numbers, but I can't figure out >how to make them into something interpretable, such as months or >years. Thanks for your help. Dagmar

It's a basic question, but it comes up often, and there are some subtleties to the answer. The problem is that a 'day' is a defined unit of time(*), but 'year' and 'month' are not. (Months vary much more than years, of course: from 28 to 31 days, rather than from 365 to 366 days.)

Here, I assume 1. The beginning and ending date are variables STRT_DT and END_DT respectively 2. Both are SPSS date variables, created with the SPSS functions provided for the purpose (*not* including YRMODA, which creates an older, now-obsolete form).

A. DAYS between two dates is unambiguous: . COMPUTE DYS_BTWN = CTIME.DAYS(END_DT-STRT_DT).

B. For many purposes, approximate, uniform-length years or months will do: . COMPUTE YRS_BTWN = DYS_BTWN/365.25. . COMPUTE MTH_BTWN = DYS_BTWN/30.5. /* 30.44 is closer */

(Of course, you can substitute the CTIME.DAYS expression from A. for "DYS_BTWN", and save using an extra variable.)

C. For CALENDAR years, months, and days in an interval, you have to use calendar-date functions. Logic has been posted a number of times on this list; see, for example, "Small off-topic (or not?): What strategy is better?", by Marta Garcia-Granero (Asesoría Bioestadística <bioestadistica@ERESMAS.NET>), Wed, 30 Jul 2003 12:58:28 +0200.

Here's another style. (I'm modifying my own code, from posting "Re: Calculating age to given calendar date", Wed, 25 Jun 2003 14:21:55 -0400.)

CAREFUL: Calculation of years and months in the interval is pretty straightforward. Calculation of days is obscure, and a little arbitrary. It is + the difference between the starting and ending day-of-month, IF that is zero or positive; + otherwise, the days between the ending date, and the starting day-of-month in the month preceding the ending date. (I.e., add 28, 29, 30, or 31 to the negative number of days calculated above, depending on what month the ending date falls in.)

WARNING: I don't think this code will work if the ending date is actually earlier than the starting date. Make sure that's impossible, or check it.

/* First, calculate RAW years, months, and days, ignoring */ /* whether the ending date is earlier in the year, or the */ /* month, than the starting date */

. COMPUTE YRS_BTWN = XDATE.YEAR(END_DT) - XDATE.YEAR(STRT_DT). . COMPUTE MTH_BTWN = XDATE.MONTH(END_DT) - XDATE.MONTH(STRT_DT). . COMPUTE DYS_BTWN = XDATE.MDAY(END_DT) - XDATE.MDAY(STRT_DT).

/* Second, correct "months" and "days" in interval, if */ /* starting day-of-month is less than ending day-of-month. */ /* (See earlier note on "days" calculation.) */

. DO IF (DYS_BTWN < 0). . COMPUTE MTH_BTWN = MTH_BTWN - 1. /* Here's the "days" code -- the most obscure part */ . COMPUTE #END_YR = XDATE.YEAR(END_DT). . COMPUTE #END_MO = XDATE.MONTH(END_DT). . COMPUTE #STRT_MD = XDATE.MDAY(STRT_DT). . DO IF (#END_MO > 1). . COMPUTE #BACK1MO = DATE.DMY(#STRT_MD,#END_MO-1, #END_YR). . ELSE. . COMPUTE #BACK1MO = DATE.DMY(#STRT_MD,#END_MO+11,#END_YR-1). . END IF. . COMPUTE DYS_BTWN = CDATE.DAYS(END_DT - #BACK1MO). . END IF.

/* Third, correct "months" and "years" in interval, if */ /* ending day is earlier in year than starting day. */ /* Because of the previous correction, the "months" */ /* in interval will be negative if */ /* . The ending month is earlier in the year than than the */ /* starting month, OR */ /* . The two months are the same, and the ending day is */ /* earlier in the month than the starting day. */

. DO IF (MTH_BTWN < 0). . COMPUTE YRS_BTWN = YRS_BTWN - 1. . COMPUTE MTH_BTWN = MTH_BTWN + 12. . END IF.

................ (*) For social-science purposes, one can ignore that an astronomical day is now a little longer than 86,400 standard seconds. <:,)


Back to: Top of message | Previous page | Main SPSSX-L page