Friday, July 20, 2007

Java Dates, Calendars and TimeZones

We all know Java date handling is a pain. I'm sure most Java developers give as little thought as possible to dates, less to calendars, and none to time zones. We use new java.util.Date() as much as possible and avoid java.util.Calendar like the plague. This works out, more or less, until you need to account for time zones. Java dates don't include any time zone related methods so it's easy to ignore them, we forget that dates really have a time zone of Greenwich Mean Time (GMT).

The thing to remember is that a Java date is a very simple object . If you remove the deprecated constructors and methods there is not much left besides equals(), hashCode() and getTime(). A date is really just a wrapper around a Java long integer value and that long integer is the number of milliseconds since January 1, 1970, 00:00:00 GMT. We forget about the GMT business because whenever we print a date it looks like this -

Sun Jul 15 10:00:00 CDT 2007

It is easy to forget that the output of toString() is the value of the date in a localized format for display and not the real value. The same date printed in two different time zones would look different even though the actual long integer value is the same. Here is an example that may help -

import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.TimeZone;

public class CalendarTimeZoneTest {
private static String getCalendarDate(Calendar cal) {
return (cal.get(Calendar.MONTH) + 1) + "/" +
cal.get(Calendar.DAY_OF_MONTH) + "/" +
cal.get(Calendar.YEAR) + " " +
cal.get(Calendar.HOUR_OF_DAY) + ":" +
cal.get(Calendar.MINUTE) + ":" +
cal.get(Calendar.SECOND);
}

private static Calendar getCalendarForTimeZone(TimeZone tz) {
Calendar cal = new GregorianCalendar(tz);
cal.clear();
cal.set(Calendar.HOUR_OF_DAY, 10);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MONTH, 6);
cal.set(Calendar.YEAR, 2007);
cal.set(Calendar.DAY_OF_MONTH, 15);
return cal;
}

private static void showDate(Calendar Cal) {
System.out.println(" Time zone : " +
Cal.getTimeZone().getDisplayName());
System.out.println(" Milliseconds : " +
Cal.getTimeInMillis());
System.out.println(" Calendar Date: " +
getCalendarDate(Cal));
System.out.println(" Local Date : " +
new Date(Cal.getTimeInMillis()));
System.out.println();
}

public static void main(String[] args) {
Calendar localCal =
getCalendarForTimeZone(TimeZone.getTimeZone("America/Chicago"));
Calendar japanCal =
getCalendarForTimeZone(TimeZone.getTimeZone("Japan"));
System.out.println("Same date/time in different time zones");
showDate(localCal);
showDate(japanCal);
System.out.println();

japanCal = new GregorianCalendar(TimeZone.getTimeZone("Japan"));
japanCal.setTimeInMillis(localCal.getTimeInMillis());
System.out.println("Same milliseconds in different time zones");
showDate(localCal);
showDate(japanCal);
}

First the example creates two calendars with the same date and time for two different time zones. This results in two dates with different millisecond values. Next, the example creates two calendars with the same milliseconds in two different time zones. The output looks like -

Same date/time in different time zones
Time zone : Central Standard Time
Milliseconds : 1184511600000
Calendar Date: 7/15/2007 10:0:0
Local Date : Sun Jul 15 10:00:00 CDT 2007

Time zone : Japan Standard Time
Milliseconds : 1184461200000
Calendar Date: 7/15/2007 10:0:0
Local Date : Sat Jul 14 20:00:00 CDT 2007


Same milliseconds in different time zones
Time zone : Central Standard Time
Milliseconds : 1184511600000
Calendar Date: 7/15/2007 10:0:0
Local Date : Sun Jul 15 10:00:00 CDT 2007

Time zone : Japan Standard Time
Milliseconds : 1184511600000
Calendar Date: 7/16/2007 0:0:0
Local Date : Sun Jul 15 10:00:00 CDT 2007

What I hope the example demonstrates is that the same Java date, i.e. millisecond value, has different meanings in different time zones. If you want the same date and time in different time zones you must take the offset between time zones into account. The easiest way to do this using the standard Java libraries is to create a date from its parts, year, month, day, etc., using a Java calendar object.

Sunday, July 15, 2007

Lazy Initialization Using an On Demand Holder

I was reminded of the "On Demand Holder" idiom the other day. If you're not familiar with it, the idiom is a thread safe replacement for lazy initialization using double checked locking. As we all know double checked locking is broken. Here is an example implementation -
public class Something {
private Something() { }

private static class Holder {
private static final Something instance = new Something();
}

public static Something getInstance() {
return Holder.instance;
}
}

This works because of the way classes are loaded. The inner class Holder is not loaded and initialized until a thread references it, so the static instance of Something is not created until the first time that the getInstance() method is called. Here is more information and references for "On Demand Holder".

Saturday, July 14, 2007

Programmer Personality Test

Here's a link to an interesting "Programmer Personality Test". If you've ever taken a Meyers-Briggs test, then the test should be familiar. It's short, painless, and worth taking if just for the entertainment value. You might learn something and it could spark interesting discussions with your teammates. A test like this could be useful as part of the hiring process, but this one is short and I'm not sure how accurate it is.

Thursday, July 5, 2007

What's Your Build Process?

So what is your build process like? Is simple or complicated? Is it manual or automated? How many of the Five R's of Agile SCM Baselines does it satisfy? I've been doing a lot of work on software build process lately and here is a simple four step process that mostly satisfies those "Five R's" -

  1. Get the latest sources from the SCM repository (branch or mainline).
  2. Execute the build against the latest sources.
  3. Commit the results of the build back to the SCM repository.
  4. Label the results of the build in the SCM repository (branch or version as needed).
Four steps, looks pretty simple. I can't think anything simpler that would be very robust. So how about automating the process? What would be simplest way to get this fully automated and as mistake proof as possible. There are lot's of build server out there, both open source and commercial, it seems like on of them ought to be able to handle the job.

I've evaluated quite a few build servers recently (I'll post reviews later) and can't find one suitable product. They all easily handle continuous integration builds, but none can automate all four builds steps. Obviously, all the servers can mange step 2, and they all partially handle step 1, i.e. getting the sources from the main line. All the servers can check out source code, but if you want to do it from more than one branch you need a configuration for each branch. None of the servers can commit anything back to the repository without external scripting of some sort let alone branch your project. If I need to write scripts or maintain multiple configurations what have I gained over just doing the four step process manually?

This is for Java application development and Ant is used for the building. I've looked at enhancing the Ant builds and as much as I like Ant, it is just not well suited for this task by itself. It might be possible to write custom Ant tasks, but I really don't want to create a custom build system that needs to be maintained. It's enough work just maintaining the Ant builds as they are. Something seems wrong when it is so hard to automate such a simple process.

Sunday, July 1, 2007

A Java Builder Pattern

There's a Builder pattern that Joshua Bloch has briefly described in a couple of his "Effective Java Reloaded" sessions at Java One. This Builder is not necessarily a replacement for the original design pattern. The problems this Builder pattern can solve are too many constructors, too many constructor parameters, and over use of setters to create an object.


Here are some examples of the pattern in use. These examples create various Widgets with two required properties and several optional ones -




Widget x = new Widget.Builder("1", 1.0).
model("1").build();
Widget y = new Widget.Builder("2", 2.0).
model("2").manufacturer("222").
serialNumber("12345").build();
Widget z = new Widget.Builder("3", 4.0).
manufacturer("333").
serialNumber("54321").build();


The basic idea behind the pattern is to limit the number of constructor parameters and avoid the use of setter methods. Constructors with too many parameters, especially optional ones, are ugly and hard to use. Multiple constructors for different modes are confusing. Setter methods add clutter and force an object to be mutable. Here is an class skeleton of the pattern -



public class Widget {
public static class Builder {
public Builder(String name, double price) { ... }
public Widget build() { ... }
public Builder manufacturer(String value) { ... }
public Builder serialNumber(String value) { ... }
public Builder model(String value) { ... }
}

private Widget(Builder builder) { ... }
}


Notice that Widget has no public constructor and no setters and that the only way to create a Widget is using the static inner class Widget.Builder. Widget.Builder has a constructor that takes the required properties of Widget. Widget's optional properties can be set using optional property methods on the Widget.Builder. The property methods of Widget.Builder return a reference to the builder so method calls can be chained.


A really nice feature of this pattern is the ability to do pre-creation validation of an object state. When setters are used to set object state during creation it is virtually impossible to guarantee that object has been properly created.


Here is the full source for Widget and its Builder -



public class Widget {
public static class Builder {
private String name;
private String model;
private String serialNumber;
private double price;
private String manufacturer;

public Builder(String name, double price) {
this.name = name;
this.price = price;
}

public Widget build() {
// any pre-creation validation here
Widget result = new Widget(name, price);
result.model = model;
result.serialNumber = serialNumber;
result.manufacturer = manufacturer;
return result;
}

public Builder manufacturer(String value) {
this.manufacturer = value;
return this;
}

public Builder serialNumber(String value) {
this.serialNumber = value;
return this;
}

public Builder model(String value) {
this.model = value;
return this;
}
}

private String name;
private String model;
private String serialNumber;
private double price;
private String manufacturer;

/**
* Creates an immutable widget instance.
*/
private Widget(String name, double price) {
this.name = name;
this.price = price;
}

public String toString() {
return super.toString() + " {"
+ "name="
+ getName()
+ " model="
+ getModel()
+ " serialNumber="
+ getSerialNumber()
+ " price="
+ getPrice()
+ " manufacturer="
+ getManufacturer()
+ "}";
}

public String getManufacturer() {
return manufacturer;
}

public String getModel() {
return model;
}

public String getName() {
return name;
}

public double getPrice() {
return price;
}

public String getSerialNumber() {
return serialNumber;
}
}


Notice that Widget's private constructor takes the required properties and that the Builder sets the optional properties. Another thing to note is that widget is an immutable object as implemented.