parsing date/time to localtimezone

    String timeToConvert = "2018-06-25T08:06:52Z";
    Instant inst = Instant.parse(timeToConvert);
    LocalTime time = inst.atZone(ZoneId.of("Africa/Nairobi"))
            .toLocalTime()
            .truncatedTo(ChronoUnit.MINUTES);
    System.out.println("Time in Nairobi: " + time);

This prints:

Time in Nairobi: 11:06

I am using java.time, in this case the backport to Java 6 and 7. This backport is available in an Android edition too, which you may use for low Android API levels. My imports are:

import org.threeten.bp.Instant;
import org.threeten.bp.LocalTime;
import org.threeten.bp.ZoneId;
import org.threeten.bp.temporal.ChronoUnit;

If you need the time string for an API that requires this format, you’re fine. If you are after a time string for presentation to a user, consider using Java’s built-in format instead:

    DateTimeFormatter timeFormatter = DateTimeFormatter.ofLocalizedTime(FormatStyle.SHORT);
    ZonedDateTime dateTime = inst.atZone(ZoneId.of("Africa/Nairobi"));
    System.out.println("Formatted: " + dateTime.format(timeFormatter));

I tried running this in Swahili (sw_KE) locale and got:

Formatted: 11:06 AM

Apparently this locale uses the English AM/PM way of notating times (I got the same result in Kikuyu and Kalenjin locales). In UK locale I get the same format as before:

Formatted: 11:06

I am using and suggesting java.time, the modern Java date and time API. For anyone reading along and using Java 8 or later or programming for Android API level 26 or higher, you don’t need the backport mentioned. Just import the built-in date-time classes from java.time with subpackages instead of the above mentioned ones.

What went wrong in your code?

Your error comes from hardcoding the Z in the date-time string as a literal. It’s a UTC offset of zero, and when you don’t parse it as such, the date-time string will be parsed in the time zone of your SimpleDateFormat, Africa/Nairobi, which is incorrect for your string.

IMHO you shouldn’t want to use SimpleDateFormat, TimeZone and Date at all, though. Those classes are long outdated and the first in particular has proven troublesome. I always use java.time instead.

Another tip: Don’t swallow exceptions. Don’t leave your catch block empty. Report the exception in some noticeable way. This is your chance to discover when something goes wrong in your code.

Links

Leave a Comment