I have following code
dateTimeFormat = ISODateTimeFormat.dateTimeNoMillis()
and i use dateTimeFormat below
public static String print(Date value) {
return dateTimeFormat.print(value.getTime());
}
And now i get problem, in my print method i put many date instances with + 4 hours time, and after dateTimeFormat.print(value.getTime()); i get time with +3 hour, but one of all date instances become with +4 hours, this error for me.
In all date instances has the same time zone Europe/Moscow
What may be wrong in my case?
In all date instances has the same time zone Europe/Moscow
A Date instance doesn't have a time zone - it's just an instant in time. But you should probably specify the time zone for your formatter, e.g.
dateTimeFormat = ISODateTimeFormat
.dateTimeNoMillis()
.withZoneUTC();
If you want a value which does know about a time zone, you should use DateTime instead of Date.
java.time
The java.util Date-Time API 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*.
Also, quoted below is a notice from the home page of Joda-Time:
Note that from Java SE 8 onwards, users are asked to migrate to java.time (JSR-310) - a core part of the JDK which replaces this project.
Solution using java.time, the modern Date-Time API:
import java.time.ZoneId;
import java.time.temporal.ChronoUnit;
import java.util.Date;
public class Main {
public static void main(String[] args) {
System.out.println(print(new Date()));
}
public static String print(Date value) {
return value.toInstant()
.atZone(ZoneId.of("Europe/Moscow"))
.truncatedTo(ChronoUnit.SECONDS)
.toOffsetDateTime()
.toString();
}
}
Output:
2021-06-20T16:18:56+03:00
ONLINE DEMO
Learn more about the modern Date-Time API from Trail: Date Time.
* 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.
Is there a way to check if a java Date object is Monday? I see you can with a Calendar object, but date? I'm also using US-eastern date and time if that changes indexing of monday
Something like this will work:
Calendar cal = Calendar.getInstance();
cal.setTime(theDate);
boolean monday = cal.get(Calendar.DAY_OF_WEEK) == Calendar.MONDAY;
You can use Calendar object.
Set your date to calendar object using setTime(date)
Example:
calObj.get(Calendar.DAY_OF_WEEK) == Calendar.MONDAY
EDIT: As Jon Skeet suggested, you need to set TimeZone to Calendar object to make sure it works perfect for the timezone.
The question doesn't make sense without two extra pieces of information: a time zone and a calendar system.
A Date object just represents an instant in time. It happens to be Wednesday in the Gregorian calendar in my time zone - but for some folks to the east of me, it's already Thursday. In other calendar systems, there may not even be such a concept of "Monday" etc.
The calendar system part is probably not a problem, but you will need to work out which time zone you're interested in.
You can then create a Calendar object and set both the time zone and the instant represented - or, better, you could use Joda Time which is a much better date/time API. You'll still need to think about the same questions, but your code will be clearer.
You should use Calendar object for these checks. Date has weak timezones support. In one timezone this Date can be Monday, and in another timezone it is still Sunday.
java.time
The java.util Date-Time API 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*.
Also, quoted below is a notice from the home page of Joda-Time:
Note that from Java SE 8 onwards, users are asked to migrate to java.time (JSR-310) - a core part of the JDK which replaces this project.
Solution using java.time, the modern Date-Time API:
Use Instant to represent a moment:
Instant instant = Instant.now();
System.out.println(instant); // A sample output: 2021-07-03T09:07:37.984Z
An Instant represents an instantaneous point on the timeline in UTC. The Z in the output is the timezone designator for a zero-timezone offset. It stands for Zulu and specifies the Etc/UTC timezone (which has the timezone offset of +00:00 hours).
However, if you have got an object of java.util.Date, convert it to Instant e.g.
Date date = new Date(); // A sample date
Instant instant = date.toInstant();
Convert Instant to ZonedDateTime representing Date-Time in your timezone e.g.
ZonedDateTime zdt = instant.atZone(ZoneId.of("America/New_York"));
Check if the Date-Time falls on Monday e.g.
System.out.println(zdt.getDayOfWeek() == DayOfWeek.SUNDAY);
Demo:
import static java.time.DayOfWeek.SUNDAY;
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
public class Main {
public static void main(String[] args) {
Instant instant = Instant.now();
ZonedDateTime zdt = instant.atZone(ZoneId.of("America/New_York"));
System.out.println(zdt.getDayOfWeek() == SUNDAY);
}
}
Output:
false
ONLINE DEMO
Learn more about the modern Date-Time API from Trail: Date Time.
* 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.
I'm trying to simply add TimeZone information back into a LocalDate before performing some more calculations. The LocalDate came from using the ObjectLab LocalDateCalculator to add days to an existing DateTime but the method needs to return a modified ReadableInstant to form an Interval which I can then inspect.
The code I'm trying amounts to a conversion of Joda LocalDate to Joda DateTime:
LocalDate contextLocalBusinessDate = calculator.getCurrentBusinessDate();
DateTime businessDateAsInContextLocation = new DateTime(contextLocalBusinessDate, contextTimeZone);
The error I get is from Joda's conversion system:
java.lang.IllegalArgumentException: No instant converter found for type: org.joda.time.LocalDate
at org.joda.time.convert.ConverterManager.getInstantConverter(ConverterManager.java:165)
at org.joda.time.base.BaseDateTime.<init>(BaseDateTime.java:147)
at org.joda.time.DateTime.<init>(DateTime.java:192)
I'm looking for a fix to this problem, or a workaround that results in an accurate Interval with full timezone information.
There are various methods on LocalDate for this, including:
LocalDate::toDateTimeAtCurrentTime()
LocalDate::toDateTimeAtStartOfDay()
LocalDate::toDateTime( LocalTime )
LocalDate::toDateTime( LocalTime , DateTimeZone )
You have to be explicit about what you want the time component to be in the resulting DateTime object, which is why DateTime's general-conversion constructor can't do it.
java.time
Quoted below is a notice from the home page of Joda-Time:
Note that from Java SE 8 onwards, users are asked to migrate to java.time (JSR-310) - a core part of the JDK which replaces this project.
Solution using java.time, the modern Date-Time API:
A common way to convert a LocalDate to ZonedDateTime is to first convert it to LocalDateTime with 00:00 hours using LocalDate#atStartOfDay and then combine with a ZoneId. An alternative to LocalDate#atStartOfDay is LocalDate#atTime(LocalTime.MIN).
Note that LocalDate#atStartOfDay(ZoneId) is another variant of atStartOfDay. However, it may not return a ZonedDateTime with 00:00 hours on the day of DST transition.
You can convert from ZonedDateTime to OffsetDateTime using ZonedDateTime#toOffsetDateTime.
Demo:
import java.time.LocalDate;
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
public class Main {
public static void main(String[] args) {
LocalDate today = LocalDate.now();
// Note: Change the ZoneId as applicable e.g. ZoneId.of("Europe/London")
ZonedDateTime zdt = today.atStartOfDay().atZone(ZoneId.systemDefault());
System.out.println(zdt);
OffsetDateTime odt = zdt.toOffsetDateTime();
System.out.println(odt);
}
}
Output:
2021-07-11T00:00+01:00[Europe/London]
2021-07-11T00:00+01:00
ONLINE DEMO
Learn more about the modern Date-Time API from Trail: Date Time.
* 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.
What is the most elegant way to get ISO 8601 formatted presentation of the current moment, UTC? It should look like: 2010-10-12T08:50Z.
Example:
String d = DateFormat.getDateTimeInstance(DateFormat.ISO_8601).format(date);
Use SimpleDateFormat to format any Date object you want:
TimeZone tz = TimeZone.getTimeZone("UTC");
DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm'Z'"); // Quoted "Z" to indicate UTC, no timezone offset
df.setTimeZone(tz);
String nowAsISO = df.format(new Date());
Using a new Date() as shown above will format the current time.
Java 8 Native
java.time makes it simple since Java 8. And thread safe.
ZonedDateTime.now( ZoneOffset.UTC ).format( DateTimeFormatter.ISO_INSTANT )
Result: 2015-04-14T11:07:36.639Z
You may be tempted to use lighter Temporal such as Instant or LocalDateTime,
but they lacks formatter support or time zone data.
Only ZonedDateTime works out of the box.
By tuning or chaining the options / operations of ZonedDateTime and DateTimeFormatter, you can easily control the timezone and precision, to a certain degree:
ZonedDateTime.now( ZoneId.of( "Europe/Paris" ) )
.truncatedTo( ChronoUnit.MINUTES )
.format( DateTimeFormatter.ISO_DATE_TIME )
Result: 2015-04-14T11:07:00+01:00[Europe/Paris]
Refined requirements, such as removing the seconds part, must still be served by custom formats or custom post process.
.format( DateTimeFormatter.ISO_LOCAL_DATE_TIME ) // 2015-04-14T11:07:00
.format( DateTimeFormatter.ISO_LOCAL_DATE ) // 2015-04-14
.format( DateTimeFormatter.ISO_LOCAL_TIME ) // 11:07:00
.format( DateTimeFormatter.ofPattern( "yyyy-MM-dd HH:mm" ) ) // 2015-04-14 11:07
For Java 6 & 7, you may consider back-ports of java.time such as ThreeTen-Backport, which also has an Android port.
Both are lighter than Joda, and has learned from Joda's experience - esp. considering that java.time is designed by Joda's author.
For systems where the default Time Zone is not UTC:
TimeZone tz = TimeZone.getTimeZone("UTC");
DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm'Z'");
df.setTimeZone(tz);
String nowAsISO = df.format(new Date());
The SimpleDateFormat instance may be declared as a global constant if needed frequently, but beware that this class is not thread-safe. It must be synchronized if accessed concurrently by multiple threads.
EDIT: I would prefer Joda Time if doing many different Times/Date manipulations...
EDIT2: corrected: setTimeZone does not accept a String (corrected by Paul)
As of Java 8 you can simply do:
Instant.now().toString();
From the java.time.Instant docs:
now
public static Instant now()
Obtains the current instant from the system clock.
This will query the system UTC clock to obtain the current instant.
toString
public String toString()
A string representation of this instant using ISO-8601 representation.
The format used is the same as DateTimeFormatter.ISO_INSTANT.
Java 8:
thisMoment = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mmX")
.withZone(ZoneOffset.UTC)
.format(Instant.now());
Pre Java 8:
thisMoment = String.format("%tFT%<tRZ",
Calendar.getInstance(TimeZone.getTimeZone("Z")));
From the docs:
'R' Time formatted for the 24-hour clock as "%tH:%tM"
'F' ISO 8601 complete date formatted as "%tY-%tm-%td".
use JodaTime
The ISO 8601 calendar system is the default implementation within Joda-Time
Here is the doc for JodaTime Formatter
Edit:
If you don't want to add or if you don't see value of adding above library you could just use in built SimpleDateFormat class to format the Date to required ISO format
as suggested by #Joachim Sauer
DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mmZ");
String nowAsString = df.format(new Date());
DateFormatUtils from Apache commons-lang3 have useful constants, for example: DateFormatUtils.ISO_DATETIME_FORMAT
If you don't want to include Jodatime (as nice as it is)
javax.xml.bind.DatatypeConverter.printDateTime(
Calendar.getInstance(TimeZone.getTimeZone("UTC"))
);
which returns a string of:
2012-07-10T16:02:48.440Z
which is slightly different to the original request but is still ISO-8601.
ISO 8601 may contains seconds
see http://en.wikipedia.org/wiki/ISO_8601#Times
so the code should be
DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
tl;dr
Some of the other Answers are correct in recommending java.time classes but go about using unnecessary lengths for your specific needs.
Instant.now() // Capture the current moment in UTC with a resolution as fines nanoseconds but usually in microseconds or milliseconds.
.truncatedTo( ChronoUnit.MINUTES ) // Lop off any seconds or fractional second, to get a value in whole minutes.
.toString() // Generate a String in standard ISO 8601 format where a `T` separates the year-month-day from the hour-minute-second, and the `Z` on the end for “Zulu” means UTC.
2018-01-23T12:34Z
Instant::toString
The jav.time.Instant class represents a moment in UTC, always in UTC.
Instant instant = Instant.now() ;
instant.toString(): 2018-01-23T12:34:56.123456Z
The Z on the end of your example string 2010-10-12T08:50Z is pronounced “Zulu” and means UTC.
Your desired format happens to comply with the ISO 8601 standard. The java.time classes use these standard formats by default when parsing/generating strings. So no need to specify a formatting pattern. Just call Instant::toString as seen above.
If you specifically want whole minutes without second or fractional second, then truncate. Specify a unit of time via ChronoUnit class.
Instant instant = Instant.now().truncatedTo( ChronoUnit.MINUTES ) ;
String output = instant.toString(); // Generate a `String` object in standard ISO 8601 format.
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
Joda-Time
Update: The Joda-Time project is now in maintenance mode, with the team advising migration to the java.time classes. For Java 6 & 7, see the ThreeTen-Backport project, further adapted for Android in the ThreeTenABP project.
Using the Joda-Time library…
String output = new DateTime( DateTimeZone.UTC ).toString() ;
This is thread-safe. Joda-Time creates new immutable objects rather than changing existing objects.
If you truly intended to ask for a format without seconds, resolving to minutes, then use one of the many other built-in formatters in Joda-Time.
DateTime now = new DateTime( DateTimeZone.UTC ) ;
String output = ISODateTimeFormat.dateHourMinute.print( now ) ;
java.time
For Java 8 and later, Joda-Time continues to work. But the built-in java.time framework supplants Joda-Time. So migrate your code from Joda-Time to java.time as soon as is convenient.
See my other Answer for a modern solution.
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
For Java version 7
You can follow Oracle documentation:
http://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html
X - is used for ISO 8601 time zone
TimeZone tz = TimeZone.getTimeZone("UTC");
DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX");
df.setTimeZone(tz);
String nowAsISO = df.format(new Date());
System.out.println(nowAsISO);
DateFormat df1 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX");
//nowAsISO = "2013-05-31T00:00:00Z";
Date finalResult = df1.parse(nowAsISO);
System.out.println(finalResult);
I do believe the easiest way is to first go to instant and then to string like:
String d = new Date().toInstant().toString();
Which will result in:
2017-09-08T12:56:45.331Z
You could use Java's SimpleDateFormat with the following pattern yyyy-MM-dd'T'HH:mm:ssXXX for ISO 8601.
Sample Code: (lists out for all the available time zones)
for (String timeZone : TimeZone.getAvailableIDs())
{
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX");
dateFormat.setTimeZone(TimeZone.getTimeZone(timeZone));
String formatted = dateFormat.format(new Date());
System.out.print(formatted);
if (formatted.endsWith("Z"))
{
// These time zone's have offset of '0' from GMT.
System.out.print("\t(" + timeZone + ")");
}
System.out.println();
}
You could use:
TimeZone.getDefault()
for the default vm timezone. More here
You might notice the date time for few time zones that end with 'Z'. These time zones have offset of '0' from GMT.
More info can be found here.
private static String getCurrentDateIso()
{
// Returns the current date with the same format as Javascript's new Date().toJSON(), ISO 8601
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.US);
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
return dateFormat.format(new Date());
}
Here's a whole class optimized so that invoking "now()" doesn't do anything more that it has to do.
public class Iso8601Util
{
private static TimeZone tz = TimeZone.getTimeZone("UTC");
private static DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm'Z'");
static
{
df.setTimeZone(tz);
}
public static String now()
{
return df.format(new Date());
}
}
DateTimeFormatter.ISO_DATE_TIME
.withZone(ZoneOffset.UTC)
.format(yourDateObject.toInstant())
Still, joda-time does only support the extended format:
"2015-12-09T00:22:42.930Z"
not the basic:
"20151209T002242.930Z"
...we might be better off testing a list of formats with java SimpleDateFormat.
I did it in Android using Calendar and SimpleDateFormat. The following method returns a Calendar with the "GMT" TimeZone (This is the universal time zone). Then you can use the Calendar class to set the hour between differents time zones, using the method setTimeZone() of the Calendar class.
private static final String GMT = "GMT";
private static final String DATE_FORMAT_ISO = "yyyyMMdd'T'HHmmss";
public static Calendar isoToCalendar(final String inputDate) {
Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone(GMT));
try {
SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT_ISO, Locale.US);
dateFormat.setTimeZone(TimeZone.getTimeZone(GMT));
Date date = dateFormat.parse(inputDate);
calendar.setTime(date);
} catch (ParseException e) {
Log.e("TAG",e.getMessage());
}
return calendar;
}
REMEMBER:
The Date class doesn't know about the TimeZone existence. By this reason, if you debug one date,you always see the date for your current timezone.
If you care about performance, I created a library which outperforms standard Java parser and formatter in manipulating with ISO8601-formatted dates. DatetimeProcessor implementations are thread-safe and can be cached in a concurrent map or static fields.
<dependency>
<groupId>com.axibase</groupId>
<artifactId>date-processor</artifactId>
<version>1.0.3</version>
</dependency>
import com.axibase.date.DatetimeProcessor;
import com.axibase.date.PatternResolver;
import org.junit.Before;
import org.junit.Test;
import java.time.Clock;
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZoneOffset;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.Is.is;
public class DateFormatTest {
private Clock clock;
#Before
public void prepare() {
clock = Clock.fixed(Instant.ofEpochMilli(1571285405300L), ZoneId.of("Europe/Berlin"));
}
#Test
public void testIsoMillis(){
final DatetimeProcessor formatter = PatternResolver.createNewFormatter("iso");
assertThat(formatter.print(clock.millis(), ZoneOffset.UTC), is("2019-10-17T04:10:05.300Z"));
}
#Test
public void testIsoMillisLocalZone(){
final DatetimeProcessor formatter = PatternResolver.createNewFormatter("iso");
assertThat(formatter.print(clock.millis(), clock.getZone()), is("2019-10-17T06:10:05.300+02:00"));
}
#Test
public void testIsoMinutes(){
final DatetimeProcessor formatter = PatternResolver.createNewFormatter("yyyy-MM-ddTHH:mmXXX");
assertThat(formatter.print(clock.millis(), ZoneOffset.UTC), is("2019-10-17T04:10Z"));
}
}
They should have added some kind of simple way to go from Date to Instant and also a method called toISO8601, which is what a lot of people are looking for.
As a complement to other answers, from a java.util.Date to ISO 8601 format:
Instant.ofEpochMilli(date.getTime()).toString();
It is not really visible when using auto-completion but:
java.time.Instant.toString():
A string representation of this instant using ISO-8601
For those using Joda Time, here's a one-liner in the format yyyy-MM-dd'T'HH:mm:ss'Z'
DateTime(timeInMillis, DateTimeZone.UTC).toString(ISODateTimeFormat.dateTimeNoMillis())
Try This,
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSSSSSZ");
String date=sdf.format (new Date() );
Its For ISO 8601 format
I want to create a calendar object that is the epoch date. What's the 'correct' (if any) way to do it?
Date epochDate = new java.text.SimpleDateFormat ("dd/MM/yyyy HH:mm:ss z").parse("01/01/1970 01:00:00 GMT");
Calendar epochCal;
epochCal.setTime(epochDate);
// or maybe
Calendar epochCal;
epochCal.setTimeInMillis(1);
The 'setTimeInMillis()' method would work fine and be easily understood by others. It might also be clearer if you passed it 0 instead of 1. The first method has more line noise and just adds more chances that something can get screwed up in maintenance.
java.time
The legacy date-time API (java.util date-time types and their formatting type, SimpleDateFormat) is outdated and error-prone. It is recommended to stop using it completely and switch to java.time, the modern date-time API*.
Solution using the modern API:
import java.time.Instant;
public class Main {
public static void main(String[] args) {
Instant instant = Instant.EPOCH;
System.out.println(instant);
}
}
Output:
1970-01-01T00:00:00Z
If at all you need an object referenced by java.util.Calendar, you can get the same using this object of Instant:
// If at all you need a Calendar object, derive it from instant
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(instant.toEpochMilli());
// Verification
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX");
sdf.setTimeZone(TimeZone.getTimeZone("Etc/UTC"));
System.out.println(sdf.format(calendar.getTime()));
Learn more about the modern date-time API* from Trail: Date Time.
* 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.