Search code examples
javacalendartimezonecodenameonesimpledateformat

Java code for managing X, XX, XXX (ISO timezone) format cases for CodenameOne implementation of SimpleDateFormat


I created an app with CodenameOne cross-platform tool. It uses its own version of Java classes. In many cases there are edge cases that those CN1 classes do not address. It is unclear how much it is. This is due to API version problems or other developing problems.

Now I have to use the CN1 SimpleDateFormat class. I checked it and I had to manage some cases myself.

I managed the literals with single quotes, the u parameter, and now I have to deal with the time zone

X, XX, XXX

parameters.

I do not know if other cases should be addressed. My app is compatible with the Android or Oracle examples so it is enough for me, because I can reproduce the example cases at least.

The X, XX, XXX formats should correspond to -08; -0800; -08:00

so

I created this code, that rely on the Z timezone parameter, that corresponds to -0800

String format=completeFormatString;

Date date= new Date();
Calendar calendar = Calendar.getInstance(); //CN1 Calendar implementation
calendar.setTime(date);

String timeZoneFormat="Z";
SimpleDateFormat timeZoneDateFormat = new SimpleDateFormat(timeZoneFormat);
String timeZone=timeZoneDateFormat.format(calendar);

String timeZoneLastPart=timeZone.substring(timeZone.length()-2);
String timeZoneFirstPart=timeZone.substring(0,timeZone.length()-2);

format=StringUtil.replaceAll((format,"XXX",timeZoneFirstPart+":"+timeZoneLastPart);
format=StringUtil.replaceAll(format,"XX",timeZoneFirstPart+timeZoneLastPart);
format=StringUtil.replaceAll(format,"X",timeZoneFirstPart);

Is it correct, is it safe to put it in my app?


Solution

  • What a pity that you’re stuck with the notoriously troublesome and long outdated SimpleDateFormat class. Below are examples of how it behaves with Oracle Java 11.

        for (String zid : new String[] { "Etc/UTC", "America/Inuvik", "Asia/Katmandu" }) {
            System.out.format("%-14s", zid);
            for (String formatPattern : new String[] { "Z", "X", "XX", "XXX" }) {
                SimpleDateFormat sdf = new SimpleDateFormat(formatPattern);
                sdf.setTimeZone(TimeZone.getTimeZone(ZoneId.of(zid)));
                System.out.format(" %-6s", sdf.format(0L));
            }
            System.out.println();
        }
    

    Output is:

    Etc/UTC        +0000  Z      Z      Z     
    America/Inuvik -0800  -08    -0800  -08:00
    Asia/Katmandu  +0530  +05    +0530  +05:30
    

    It seems that for a non-zero offset it works the way you expected when writing your code. It also seems to me that you will need to build in a special case for offset zero, +0000 from pattern letter Z since in this case the pattern letter upper case X produces Z (for zero or Zulu time zone) no matter if you use X, XX or XXX.