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