Posting time bug fix proposal (simplified)

Charles Day cedayiv at
Sat Aug 16 15:49:09 EDT 2008

On Fri, Aug 15, 2008 at 4:08 PM, Stuart D. Gathman <stuart at>wrote:

> Charles Day wrote:
>  <a proposal to flag dates with a time of day of 00:00:00>
> The problem is that this is an obfuscated flag.  If you're going to flag
> dates, flag them with a new XML field.  However unlikely, the 00:00:00
> flag will fail, and you have the worst of all possible situations - code
> that fails *rarely*.

We can't add new fields without breaking two of the four goals stated at the
beginning of this thread.

> If you want to keep the existing file format unchanged, keep it
> unchanged.  New programs are free to use the included timezone to
> extract the original date - or equivalently, ignore everything except
> the date.  When the timestamps are loaded into a struct tm or equivalent
> - lo and behold, the month,day,year fields have the correct date.

Using the date and dropping the time and time zone only works reliably for
transactions that are not already bug-affected. And this is what the patch
does. But the rest of the challenge is to detect transactions that have
already been thrown off by the bug, then derive the original date entered.
The patch is designed to do that too.

> Instead of doing the mktime() thing and dividing by seconds per day
> (which will fail sometimes - a Very Bad Thing), use a nice julian date
> routine to compute a day number.  Here is an example based on the
> Gregorian Calendar:

I'm not following... I don't think I used any division in the patch. Which
part of the code are you referring to?

JULDAY julian(const struct mmddyy *mdy) {
>  int dyyr,lpyrs,cyrs,clyrs;
>  JULDAY dayno;
>  if (mdy->mm == 99 && mdy->dd == 99)
>    return 0x7FFFFFFF;
>  dyyr=(mdy->mm*275)/9-32+mdy->dd;
>  lpyrs=mdy->yy+4712;
>  dayno=lpyrs*365L;
>  cyrs=clyrs=0;
>  if (mdy->yy>1582) { cyrs=mdy->yy-1500; clyrs=mdy->yy-1200; }
>  if (mdy->mm<3)    { cyrs--; clyrs--; lpyrs--; dyyr+=2; }
>  dayno += (dyyr+clyrs/400+lpyrs/4-cyrs/100);
>  if (dayno>2299170L) dayno-=10;        /* Oct 5 = Oct 15, 1582 */
>  return dayno;
> }
> Or just use the mdy information as is - but be sure to ignore the rest.
> When writing timestamps - do whatever tickles your fancy.  By using the
> included timezone (or equivalently ignoring everything except the date),
> you get the right date in new programs.  However, for old versions of
> gnucash to work as well as they used to, you probably want to do the
> same thing - or maybe change the time of day to 12:00 (although that
> makes failure on timezone change rarer - a Bad Thing).


More information about the gnucash-devel mailing list