Sunday, February 22, 2015

Gnucash Timezone Problem Workaround

GnuCash is accounting software. It is usable, which is the most important compliment software can get, but it has one annoying bug, first reported in 2002. Let’s assume it will never be fixed, and just work around it.

The bug is that dates are stored in the xml file as timestamps. E.g. if you say a transaction happened on 2014-06-21, then it gets stored as “2014-06-21 00:00:00”. That is the bug. The problem is that it also stores the users current timezone. So, if I type that in when in the Asia/Tokyo timezone it will actually store it as “2014-06-21 00:00:00 +0900”. If I then open the gnucash file on a server in the Europe/London timezone, and re-save, the file now stores this: “2014-06-20 16:00:00 +0100”. It has moved it to BST timezone, but in the UI all you now see is that the transaction is on the wrong day! (That was a real problem, but if you think that is exotic the original bug report was done by someone who merely moved from one state in the U.S. to another state!)

Anyway, my proposed workaround is to always run gnucash in the UTC timezone. On Linux you do this from commandline by starting it like this:

TZ=UTC gnucash

In windows environments, you might have associated your *.gnucash files, so double-clicking them opens them in gnucash. The following instructions work for xfce (thunar file manager), but I suspect gnome is exactly the same.

  1. Right click any gnucash file, and choose properties
  2. Choose open with, and at the bottom it says “Other application…”
  3. Give bash -c "TZ=UTC gnucash %f"
  4. Close it, and test it by double-clicking any gnucash file.

(I confirmed it had worked by looking at the raw XML.)

What to do if you have someone else working on your files who does not want to do this? Or is on Windows (where I don’t know a similar workaround)? Well, the only solution I know is that they temporarily move their whole machine to UTC, open, edit and save your gnucash files, then restore their machine back to their real timezone. (Remember that UTC is different from Europe/London.)

Thursday, February 5, 2015

PHP Sending mails twice?? (doing stuff twice)

Just had a mammoth troubleshooting session, because a very simple PHP script to send an email kept sending them twice. I’d only just configured postfix to send email, so I kept looking for problems there. I kept staring at the PHP code, and could see no problem, but it looked more and more like PHP was calling postfix twice. Commenting php.ini settings in and out made no difference. This was commandline PHP, so nothing to do with browser reloads, or anything like that.

Then I had the brainwave to append a random number to the bottom of the body text. Different numbers; in fact, not just that, but the 2nd email got both numbers! So it is definitely my PHP script. But I still couldn’t see it.

Stripped down, so the problem is more obvious, it looked like this:

$bodyText = "Whatever";

class Test{

function test(){
$bodyText.="RANDOM=".mt_rand(1,1000);
mail("me@example.com", "Test", $bodyText);
}
}

$R = new Test;
$R->test();

I’ve been spending too much time jumping between languages. And I’d also got used to PHP constructors being called __construct() and forget it still offered backwards compatibility for using the class name. Yep, that’s right, PHP functions (and classes) are case-insensitive, and so test() was being treated as the constructor of class Test. So one mail was being sent from the constructor, the second from my explicit function call. Grrrr….

(The above is also a possible explanation for problems like “PHP calls web service twice”, or “PHP has double log entries” or “PHP does something twice”!)

Written with StackEdit.