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