DayAddDay leap year bug << Back



Read this previous post on leap year bug first. Fortunately DateTime doesn't suffer this problem, or does it?

Use UI
DateTime feb march // Changed this from "DATE" data type
Move 02/28/1700 to feb
Move 03/01/1700 to march
showln (SpanTotalDays(march - feb)) // it shows 1
InKey FieldIndex

So far so good. What if I use the global function DateAddDay?

Use GlobalDateTimeFunctions.pkg
DateTime feb 
Move 02/28/1700 to feb
showln (DateAddDay(feb, 1)) // it shows 02/29/1700
InKey FieldIndex

Hmm, what gives? I thought DateTime was immune from the leap year bug. Let's take a look at the implementation of DateAddDay inside GlobalDateTimeFunctions.pkg.

Function DateAddDay Global DateTime dtVar Integer iAdd Returns DateTime
    DateTime dtVar2
    Date dDate
    Integer iCrnt iOverflow
    If (IsNullDateTime(dtVar) or not(IsDateValid(dtVar))) Begin
        Error DFERR_INVALID_DATETIME
        Function_Return dtVar2
    End
    Move dtVar to dtVar2
    Move dtVar to dDate
    Move (dDate + iAdd) to dDate
    Move (DateGetDay(dDate))  to iCrnt
    Move (DateSetDay(dtVar2,iCrnt)) to dtVar2
    Move (DateGetMonth(dDate)) to iCrnt
    Move (DateSetMonth(dtVar2,iCrnt)) to dtVar2
    Move (DateGetYear(dDate)) to iCrnt
    Move (DateSetYear(dtVar2,iCrnt)) to dtVar2
    Function_Return dtVar2
End_Function

Line 4 shows some sloppy copy-and-paste job with an extra variable "iOverflow", but that's not the problem (Maybe compiler should warn you about unused local variables, like in C# or C++). Line 11 is the culprit. Moving a "DateTime" to "Date", then do addition. As I have shown before, "Date" data type can contain invalid date, like 02/29/1700. You might ask - why didn't DAW use "TimeSpan" to do addition instead? Let's have a look.

Use UI
DateTime feb 
TimeSpan ts
Move 02/28/1700 to feb
showln (feb + DateSetDay(ts, 1)) // it shows 03/01/1700
InKey FieldIndex

That seems to work just fine. Maybe we can simplify DateAddDay to something like this?

Function DateAddDay Global DateTime dtVar Integer iAdd Returns DateTime
    TimeSpan ts
    DateTime dtVar2
    If (IsNullDateTime(dtVar) or not(IsDateValid(dtVar))) Begin
        Error DFERR_INVALID_DATETIME
        Function_Return dtVar2
    End
    Function_Return (dtVar + DateSetDay(ts, iAdd))
End_Function





Free Web Hosting