views:

435

answers:

4

How do I add 2 years to a date in powerbuilder and account for the leap year correctly?

We have a medical license application where the user would like the date to go expire two years. Current license date is 7/10/2010 and expire date should be 7/2/2012 I used relative date and added 729 if not a leap year and 730 if it was but that is messy.

I wish the relativedate function took another parameter to so you could pass in number years.

+1  A: 

How about:

// adjusted from suggestions
IF Month (ldt_OldDate) = 2 AND Day (ldt_OldDate) = 29 THEN
   ldt_NewDate = Date (Year(ldt_OldDate) + 2, 3, 1) 
   // or ... 2, 28) whichever you think is two years from Feb 29
ELSE
   ldt_NewDate = Date (Year(ldt_OldDate) + 2, Month (ldt_OldDate), Day (ldt_OldDate))
END IF

Good luck,

Terry

Terry
Thank to both for your answers! I used the one from Terry and it seems to work just as I needed. I am so glad I "stumbled" onto this site! I will share with other programmers for sure.
Judy
I am posting my final code under another answer
Judy
I don't think this is quite right. 2 years after 29-FEB-2000 will be 01-JAN-1900 i.e. it will not parse it.
Colin Pickard
A: 

This was the code I used:

//Get the license Issue Date
  ldt_calculate_date = this.GetItemDateTime(1, 'issue_date')

//Add two years to the date
  ld_calculate_date = date(ldt_calculate_date)
    ld_NewDate = Date ((Year(ld_calculate_date) + 2), Month (ld_calculate_date), Day 
        (ld_calculate_date))

//Subtract 1 from the date for correct expiration
  ld_calculate_date_to = date(RelativeDate(ld_NewDate, -1))

//Set expiration date on my datawindow
  setitem(1,"expiration_date", ld_calculate_date_to)
Judy
This code will fail on 29th February. It will give you an expiry date of 01-JAN-1900.
Colin Pickard
I will check this out
Judy
+1  A: 

If you use PFC, you could do:

n_cst_datetime     luo_dateTime   

ld_calculate_date_to = luo_dateTime.of_relativeYear(ldt_calculate_date, 2)
Zerofiz
You can get the source code for PowerBuilder Foundation Classes (PFC) free of charge from Sybase CodeXchange (http://codexchange.sybase.com). The function mentioned is actually implemented in pfc_n_cst_datetime in pfcapsrv.pbl, if you just want to look at source, but the way the function is implemented above is correct according to PFC philosophy (never directly using PFC level objects, but the extension layer objects).
Terry
A: 

Here's more reusable solution - and can do a lot more than you need - it's global function - or for you nvo lovers you can put it one of those :

>

/* WHAT IT DOES

pass a date & the days, months, years that you would like to add to it and it returns the new date

USAGE

you can send any number in ai_days ai_months ai_years including negative numbers and months greater than 12 (e.g. ai_months = -18 means 18 months in the past)

ARGUMENTS

date adt_change - pass in & return with changed date

intger ai_days

integer ai_months

integer ai_years

return integer

*/

try

integer li_add_years

integer li_new_day

integer li_new_month

integer li_new_year

integer li_total_months

add the days

if ai_days <> 0 then adt_change = relativedate(adt_change,ai_days)

if isnull(adt_change) then throw STOP end if

save changed day & month & year

li_new_day = day(adt_change)

  if isnull(li_new_day) then throw STOP

li_new_month = month(adt_change)

  if isnull(li_new_month) then throw STOP

li_new_year = year(adt_change)

  if isnull(li_new_year) then throw STOP

change the month

if ai_months <> 0 then

  li_total_months = li_new_month + ai_months

  li_new_month = mod(li_total_months,12)

      if isnull(li_new_month) then throw STOP

  li_add_years = int(li_total_months/12)  

      if isnull(li_add_years) then throw STOP

  if li_total_months <=0 then li_new_month += 12      

end if

change the year

li_new_year += li_add_years + ai_years

reset date

adt_change = date(li_new_year,li_new_month,li_new_day)

  if adt_change = 1900-01-01 or isnull(adt_change) then 

throw STOP

return SUCCESS

catch (runtimeerror lrteo_error)

return logerror(lrteo_error)

end try

Matt
You'll have to take the try catch stuff out if you dont use that for trapping errors - but otherwise you should be able to create a new function - I call mine changedate() . adt_change should be passed by reference, the rest can be passed by value.Those interested in how the try catch works - I have a SourceForge Powerbuilder project with sample code : it's called OBA or OBAFrame on SourceForge.
Matt