Sunday, February 26, 2017

Using Joda time to handle date+time+timezone

I have been working on a client-server system where the client and server are in different timezones. The client is on London time, the server is in Los Angeles, a difference of 8 hours. This means that at the end of the business day in LA it already the next day in London. The API that I have to use contains functions with parameters of type Calendar. As we know, Calendar is a date+time+timezone triple, and the timezone defaults. This means that if the timezone is not explicitly specified then it will change its meaning as it goes over the wire.

I have been using the Joda datetime package to help me and after a bit of struggling eventually came up with the example program below which shows the construction of Joda DateTime objects for a specific date+time+timezone which is displayed correctly in both timezones. The program also shows how to construct Calendar objects from them for the correct timezone.

package jodaexample;

import java.text.SimpleDateFormat;
import java.util.Calendar;

import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

 * @author marlowa
 * This example shows a time of 18:30 PST which is 8 hours behind UTC.
 * This means the date+time+timezone is 01:30 the previous day in UTC,
 * or 02:30 in BST.
public class example {

    public static void main(String[] args) {
        System.out.println("Joda timezone example program.");
        DateTimeZone mytimezone = DateTimeZone.forID("America/Los_Angeles");
        DateTime mydatetime = new DateTime(2017, 3, 31, 18, 30, 0, mytimezone);
        String formatString = "yyyy-MM-dd HH:mm:ss z '('Z')'";
        DateTimeFormatter dtf = DateTimeFormat.forPattern(formatString);
        System.out.println("DateTime (local, i.e. behind UTC) = "+dtf.print(mydatetime));
        Calendar datetimeInAmerica = mydatetime.toGregorianCalendar();
        SimpleDateFormat sdfInAmerica = new SimpleDateFormat(formatString);
        sdfInAmerica.setCalendar(datetimeInAmerica); // to set the timezone.
        System.out.println("Calendar inAmerica                = "+sdfInAmerica.format(datetimeInAmerica.getTime()));
        long dateTimeMilliseconds = mydatetime.getMillis(); 
        int millisecondsOffset = mytimezone.getOffset(dateTimeMilliseconds);
        System.out.println(String.format("Milliseconds = %d, offset = %d", dateTimeMilliseconds, millisecondsOffset));
        long millisecondsInTimezone = dateTimeMilliseconds+millisecondsOffset;
        System.out.println("millisecondsInTimezone            = "+millisecondsInTimezone);
        long millisecondsInUTC = mytimezone.convertLocalToUTC(millisecondsInTimezone, false);
        DateTime dateTimeUTC = new DateTime(millisecondsInUTC, DateTimeZone.UTC);
        System.out.println("DateTime (UTC)                    = "+dtf.print(dateTimeUTC));
        Calendar datetimeInLondon = dateTimeUTC.toGregorianCalendar();
  SimpleDateFormat sdfInLondon = new SimpleDateFormat(formatString);
  sdfInAmerica.setCalendar(datetimeInLondon); // to set the timezone.
  System.out.println("Calendar inLondon                 = "+sdfInLondon.format(datetimeInAmerica.getTime()));

Wednesday, May 25, 2016

The cause of MIDL error MIDL2398

Whilst working on a Windows Visual Studio (VS) project that uses MIDL (Microsoft IDL) I suddenly started getting the error MIDL2398 during the build. This was for no apparent reason. I tried the usual things, logging off, rebooting, cleaning the VS project, blowing my SVN checkout away and doing a fresh build. Sometimes this worked and sometimes it didn't. This was driving me nuts. Googling didn't yield much. Other people were also seeing this problem but no-one explained it and several people said that when they re-installed VS it went away. Yeah, right.

After a few hours of these failures I noticed something. The problem seemed to happen roughly on the hour. Then I remembered. I had recently set up a jenkins job to run on the hour. The jenkins job was building something else in an unrelated area but the coincidence seemd too great to ignore. I disabled the job. It turns out that the jenkins job was failing and during the failure logging it tried to log to a logfile without using double quotes around the filename. Since it was a jenkins job with the default jenkins install directory, the pathname started with "C:\Program Files (x86)\Jenkins". This was causing the logfile "C:\Program" to be created. The jenkins job, being run by jenkins, had administrator privileges so it was allowed to write this file to the root directory. When my VS got to the COM bit where it runs MIDL I got the error.

The fact is that the presence of the rogue file "C:\Program" kills MIDL with this weird error. Well I never. And it turns out to be easier to accidently create this rogue file than you might think.

Saturday, September 26, 2015

The pesky capslock and inserts keys on Windows computers

It is a complete mystery to me why computer keyboards even have a capslock key. Old timers like me have a theory that in the old fashioned days of typewriters there was a practical reason, but surely there is no reason for it now. See capsoff for a history lesson. Nowadays it is just a key that you hit by accident. At home I use the Happy Hacking keyboard. That's right, I spent extra money to get a keyboard that doesn't have the capslock key!

For several years I have using registry hacks to disable the capslock key. It is one of the first things I do when setting myself up on a new machine. But until recently I didn't know what to do about another pesky key: the insert key. That's the key that makes typing either insert or overwrite according to the current setting. The current setting is not displayed so you only find out if you have hit it by accident when you notice that the last few characters you typed overwrote instead of inserting. Unlike the numlock key, the insert key has no feedback to tell you its current state. So this is another key you might want to disable. I couldn't find a registry hack for that but recently I found a great program for Windows called SharpKeys. This does allow you to turn off the insert key and, of course, the capslock key. So I now resolve to use SharpKeys whereever I go from now on. I hope you find it useful too.

Saturday, August 01, 2015

The death of Purify

Purify is a memory debugger program used by software developers to detect memory access errors in programs, especially those written in C or C++. It was originally written by Pure Software.

My first experience of purify was way back in the days Motif programming around 1992. I used it to track down memory corruption and leakage bugs in my code for a complex oil and gas graphics program. After I had fixed my bugs I found that purify complained about loads of bugs in Motif. Over the next few years Motif got cleaned up dramatically, thanks in no small part to purify. I have been a keen user ever since and as time went on it was ported from Solaris to other flavours of UNIX and to Windows. A GUI was added, better support for multi-threading, it just got better and better.

Why was purify so good? Because at the time there was little else you could use that would do the same job in a completely comprehensive way. The other tools typically required access to the entire source of your product as recompilation was necessary. Other approaches included interposing special versions of new/delete and malloc/free which required special linking as sometimes special compilation as well. I saw one attempt at using a virtual machine, from IBM, but IMO it was a failure. I broke it with a simple 3 line program almost immediately. So I was very skeptical in the early days that emulation would ever work. Boy, was I wrong when it comes to valgrind. But valgrind wasn't around then. Remember, we are talking about how to debug legacy C++ that was written before valgrind was invented or linux was popular.

Pure Software acquired by Atria but the product continued to be good at that point and spread mainly by word of mouth. There were fully functional but time-limited trial versions. I used to say it was the next tool you should get right after the C++ compiler. But then it was acquired by Rational where it stayed for many years. It languished under the ownership of Rational who didn't seem particularly keen to sell it. One had to jump through hoops when one had finally won the argument to purchase licenses. These were not cheap but purify was so vastly superior to the other tools that the case could be made. Then the Rational purchase obstacles kicked in. One had to be determined. Then IBM acquired the product. If it was hard to buy from Rational it was almost impossible with IBM. And they neutered the demo/trail version, effectively making it so that it only spread by word of mouth. One could no longer use the trail version to evaluate it.

Fast forward to January 2015. IBM sold Purify to UNICOM. This sale has been disastrous for all users of purify. UNICOM no longer sell it. Instead they sell a product called PurifyPlus, which is a bundle of other tools developed by Pure Software and extended by subsequent owners. These tools are Quantify and PureCoverage, for performance and code coverage analysis respectively. These are and have always been good powerful tools. For some users it made sense to bundle them because if all three were desired the overall license fee was cheaper. Now there is no choice and buying all three is most definitely not for everyone. But there's more. You used to be able to purchase as many licenses as you wanted, from a single license to site-wide. Now UNICOM have made it so that the minimum number of licenses is FOUR. This makes it very expensive. Also a years support fees is compulsory. I recently got a sales quote for a client of mine and the quote was for over TEN THOUSAND dollars. Needless to say at that sort of price it was game over.

After discussion with some of my colleagues I have come to conclusion that UNICOM want to kill the entire product suite off. Why else would they only sell it to large enterprise outfits to whom tens of thousands of dollars for software purchases are as nothing? Effectively purify is dead. This is a serious problem for the development and maintenance of legacy C++ programs.

It's not a problem for any new C++ software development. Just start developing it on LINUX where valgrind is available. But valgrind will never be available for Windows. The problem is trying to purify a large Windows C++ program that cannot be ported to Linux (and where there may not be any need or desire to do so).

So I no longer recommend purify. It is consigned to the dustbin of history. What a pity, it was a fantastic tools right to the end.

Thursday, July 02, 2015

The wonders of semantic versioning

Many years ago, in the dim and distant past, I used to work for Prime Computer Inc. They don't exist any more. They had a very good policy when it came to versions of their operating system. They used the familar major.minor.fix convention for denoting the version but were very strict about what this meant. The version numbers were always numbers, never strings, and you could and were supposed to infer things from the numbers. These inferences told you what versions were compatible with what other versions. They also told you about scale and kind of changes between versions. Sadly the industry as a whole doesn't do any of this in general. In fact, until recently, Prime was the only case I knew of that ever did this properly. Then I came across something called Semantic Versioning. See the web site at This describes exactly what was done at Prime. How jolly sensible. Let's hope this catches on.

Tuesday, June 10, 2014

C++ code to dump memory in hex and ASCII

Every now and then I have the need to dump a block of memory as hex and ASCII in some C++ code I am working on. Each time I google for some code I can snaffle to do the trick. Each time I find something of very mediocre quality which will just about do for the occasion. Well, I finally got sick and tired of this and now I am publishing my own solution. I hope that people find it useful.

Many thanks to ECI training for this YouTube video on how to do file attachments in blogger.

Sunday, June 01, 2014

TrueCrypt has gone! OMG!!!

My hard drive failed so this weekend I started to migrate my stuff over to a new machine which didn't have much stuff set up on it. One of the missing components was truecrypt so I thought I would just download and build from source. What a shock awaited me - truecrypt has gone! See the wikipedia page that describes how it went on 29th May 2014. There was also an article in the Guardian. I am writing this on Sunday 1st June 2014. This was not how I wanted to spend my Sunday!

Conspiracy theories to one side, the practical question remains, what does one do if one wishes to continue using truecrypt as it was? The answer seems to be to build from the source of the 7.1a. Download it from the final release repository. However, there is more to it than that. It doesn't build cleanly. I found someone else who was trying to do what I wanted to do, Reinhard Seiler. He blogged about his build experience. However, this was on a raspberry Pi and I had some different problems. Here's what I found:

  • The build requires nasm, yasm won't do. No problem, I installed it via synaptic package manager.
  • SecurityToken.cpp failed to compile due to missing PKCS11 header files. I followed Reinhard Seiler's instructions, placing the headers from into a sub-directory of my truecrypt source. This is so I could copy the entire directory if this ever happens to me again (i.e complete install on new machine needed).
  • I got compilation errors due to missing macros such as CKR_NEW_PIN_MODE. Luckily, I found a blogger who had hit the same problem and posted a solution. Basically you ifdef out the offending lines. It is safe to do this since it is only error message handling.
  • Once it got past the PKCS11 errors I found that it needs fuse. I installed libfuse-dev from synaptic package manager.
  • The final compilation errors came from the GUI bits where it depends on wxWidgets. Synaptic to the rescue!
  • Finally it built. But then I got an error at runtime along the lines of "Failed to communicate with kernel device mapped drive". I had done a rather large synaptic upgrade without bothering to reboot. Apparantly this kernel mode was affecting truecrypt so I was forced to reboot. Then it worked! Hurrah!

Once I had a working version of truecrypt I copied the entire build directory to my external USB backups directory, ready for the next time I need to install truecrypt on a new machine.

Now I will just put on my tinfoil hat briefly. I reckon that it is a conspiracy that truecrypt has gone. The developers say that the tool is not necessary now that Microsoft have BitLocker but this just doesn't wash. For a start I am on linux! And second, BitLocker is closed, secret, proprietary, so there is bound to be an NSA backdoor. Now I will remove my tinfoil hat and go and get a nice cup of coffee!