Android Format date with time zone

You can use Joda Time instead. Its DateTimeFormat has a ZZ format attribute which does what you want.

Link

Big advantage: unlike SimpleDateFormat, DateTimeFormatter is thread safe. Usage:

DateTimeFormatter fmt = DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ssZZ")
    .withLocale(Locale.ENGLISH);

You can also use "ZZZZZ" instead of "Z" in your pattern (according to documentation). Something like this

    Calendar c = Calendar.getInstance();
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZZZZZ", Locale.ENGLISH);      
    Log.e(C.TAG, "formatted string: "+sdf.format(c.getTime()));

tl;dr

You can use the pattern, yyyy-MM-dd'T'HH:mm:ssXXX for your desired output.

java.time

The date-time API of java.util and their formatting API, SimpleDateFormat are outdated and error-prone. It is recommended to stop using them completely and switch to the modern date-time API.

  • For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7.
  • If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.

Using the modern date-time API:

Building an object that holds date, time and timezone offset information and formatting the same:

import java.time.LocalDate;
import java.time.LocalTime;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        OffsetDateTime odt = OffsetDateTime.of(LocalDate.of(2013, 1, 4), LocalTime.of(15, 51, 45),
                ZoneOffset.ofHoursMinutes(5, 30));

        // Print the default format i.e. the string returned by OffsetDateTime#toString
        System.out.println(odt);

        // Custom format
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ssXXX", Locale.ENGLISH);
        System.out.println(dtf.format(odt));
    }
}

Output:

2013-01-04T15:51:45+05:30
2013-01-04T15:51:45+05:30

As you can notice, the outputs for the default format and for that using a DateTimeFormatter are same. However, there is a catch here: the implementation of OffsetDateTime#toString omits the second and the fraction of second if they are 0 i.e. if the time in the above code is LocalTime.of(15, 0, 0), the output for the default format will be 2013-01-04T15:00+05:30. If you need a string like 2013-01-04T15:00:00+05:30 for this time, you will have to use a DateTimeFormatter with the desired pattern.

Parsing and formatting:

import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        DateTimeFormatter dtfForInputString = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ssZ", Locale.ENGLISH);
        OffsetDateTime odt = OffsetDateTime.parse("2013-01-04T15:51:45+0530", dtfForInputString);

        // Print the default format i.e. the string returned by OffsetDateTime#toString
        System.out.println(odt);

        // Custom format
        DateTimeFormatter dtfCustomOutput = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ssXXX", Locale.ENGLISH);
        System.out.println(dtfCustomOutput.format(odt));
    }
}

Output:

2013-01-04T15:51:45+05:30
2013-01-04T15:51:45+05:30

Using the legacy API:

Building a date-time object for the given timezone offset and formatting the same:

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;

public class Main {
    public static void main(String[] args) {
        Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("GMT+05:30"));
        calendar.set(2013, 0, 4, 15, 51, 45);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX", Locale.ENGLISH);
        sdf.setTimeZone(TimeZone.getTimeZone("GMT+05:30"));
        Date date = calendar.getTime();
        System.out.println(sdf.format(date));
    }
}

Output:

2013-01-04T15:51:45+05:30

The Calendar class uses UTC (or GMT) as its default timezone and therefore, unless you specify the timezone with it, it will return the java.util.Date object for UTC.

Similarly, the SimpleDateFormat class also uses UTC as its default timezone and therefore, unless you specify the timezone with it, it will return the formatted String for the corresponding date-time in UTC.

Parsing and formatting:

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;

public class Main {
    public static void main(String[] args) throws ParseException {
        SimpleDateFormat sdfForInputString = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ", Locale.ENGLISH);
        Date date = sdfForInputString.parse("2013-01-04T15:51:45+0530");

        SimpleDateFormat sdfCustomOutput = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX", Locale.ENGLISH);
        sdfCustomOutput.setTimeZone(TimeZone.getTimeZone("GMT+05:30"));
        System.out.println(sdfCustomOutput.format(date));
    }
}

Output:

2013-01-04T15:51:45+05:30