Instead of directly working with SimpleDateFormat
(as this old API has lots of problems and design issues), you can use the ThreeTen Backport, a great backport for Java 8's new date/time classes. To use it in Android, you'll also need the ThreeTenABP (more on how to use it here).
The main classes to be used are org.threeten.bp.ZonedDateTime
(which can parse the date/time input) and org.threeten.bp.format.DateTimeFormatter
(to control the output format).
If you are reading this field (2017-06-22T16:18:04Z
) as a String
, you can create a ZonedDateTime
like this:
ZonedDateTime z = ZonedDateTime.parse("2017-06-22T16:18:04Z");
If you already have a java.util.Date
object, you can convert it using org.threeten.bp.DateTimeUtils
with a org.threeten.bp.ZoneOffset
:
Date date = // get java.util.Date
ZonedDateTime z = DateTimeUtils.toInstant(date).atZone(ZoneOffset.UTC);
In the end, the ZonedDateTime
object will have the webPublicationDate
value.
To get the different output formats, just create one DateTimeFormatter
for each format. In the examples below, I also use java.util.Locale
class to make sure the month names are in English:
// for Mar 3, 1984
DateTimeFormatter f1 = DateTimeFormatter.ofPattern("MMM d, yyyy", Locale.ENGLISH);
// for 4:40 PM
DateTimeFormatter f2 = DateTimeFormatter.ofPattern("h:mm a", Locale.ENGLISH);
// for 16:18
DateTimeFormatter f3 = DateTimeFormatter.ofPattern("HH:mm", Locale.ENGLISH);
System.out.println(f1.format(z)); // Jun 22, 2017
System.out.println(f2.format(z)); // 4:18 PM
System.out.println(f3.format(z)); // 16:18
The output is:
Jun 22, 2017
4:18 PM
16:18
Note that it uses the UTC timezone (the Z
in 2017-06-22T16:18:04Z
). If you want to display the date and time in another timezone, just use the org.threeten.bp.ZoneId
class:
System.out.println(f3.format(z.withZoneSameInstant(ZoneId.of("Europe/London")))); // 17:18
The output is 17:18
(becase London is in summer time now).
Note that the API uses IANA timezones names (always in the format Continent/City
, like America/Sao_Paulo
or Europe/Berlin
).
Avoid using the 3-letter abbreviations (like CST
or PST
) because they are ambiguous and not standard. To find the timezone that better suits each region, use the ZoneId.getAvailableZoneIds()
method and check which one fits best for your use cases.
If you don't want to add another dependency to your project and use SimpleDateFormat
, you do something similar (create one parser and 3 output formatters, and use English locale). Also don't forget to set the timezone - I'm using UTC below, but you can change it to whatever timezone you want.
// parse date
String dateInString = "2017-06-22T16:18:04Z";
SimpleDateFormat parser = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX");
Date date = parser.parse(dateInString);
// create output formatters (set timezone to UTC)
TimeZone utc = TimeZone.getTimeZone("UTC");
SimpleDateFormat s1 = new SimpleDateFormat("MMM d, yyyy", Locale.ENGLISH);
s1.setTimeZone(utc);
SimpleDateFormat s2 = new SimpleDateFormat("h:mm a", Locale.ENGLISH);
s2.setTimeZone(utc);
SimpleDateFormat s3 = new SimpleDateFormat("HH:mm", Locale.ENGLISH);
s3.setTimeZone(utc);
System.out.println(s1.format(date));
System.out.println(s2.format(date));
System.out.println(s3.format(date));
The output will be the same:
Jun 22, 2017
4:18 PM
16:18