Reputation: 23344
I am trying to convert the date in milliseconds to the following ISO 8601 format:
But I am getting the following using SimpleDateFormat:
/**
* It converts the time from long to the ISO format
*
* @param timestampMillis
* @return isoDate
*/
public String convertTimeMillisToISO8601(String timestampMillis)
{
long timeInLong= Long.parseLong(timestampMillis);
DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
df.setTimeZone(TimeZone.getTimeZone("UTC"));
String isoDate = df.format(new java.util.Date(timeInLong));
return isoDate;
}
OUTPUT:
"ts":"2015-06-18T09:56:21+0000"
I know I can use substring to append the extra colon but Is there any better way to do so ?
Upvotes: 4
Views: 4492
Reputation: 23840
For Java 7 and higher, you might use XXX
(ISO 8601 time zone) in the date format String. According to the documentation, the result of X
can be:
X => -08
XX => -0800
XXX => -08:00
but for all of those, it might as well return Z
!
For Java 6 and earlier, there is no X
(J6 doc), and since the result of X
may or may not do what you want, I strongly recommend you just insert that colon yourself.
Upvotes: 8
Reputation: 15879
For Java 8 if you use one of the standard ISO_DATE_*
format patterns then the output formatted String will be truncated when the offset is +00:00 (UTC typically just appends Z
).
OffsetDateTime utcWithFractionOfSecond = ZonedDateTime.parse("2018-01-10T12:00:00.000000+00:00", DateTimeFormatter.ISO_OFFSET_DATE_TIME);
utcWithFractionOfSecond.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME); // 2018-01-10T12:00:00Z ... not what you want!
The only solution I have found is using the outputPattern
(shown below) that uses lowercase `xxx' to ensure that a colon is included in the timezone offset.
I have included an example with factions-of-a-second for completeness (you can remove the SSSSSS
in your case)
DateTimeFormatter inputPattern = DateTimeFormatter.ISO_OFFSET_DATE_TIME;
DateTimeFormatter outputPattern = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSSSSxxx");
OffsetDateTime utcWithFractionOfSecond = OffsetDateTime.parse("2018-01-10T12:00:00.000000+00:00", inputPattern);
OffsetDateTime utcNoFractionOfSecond = OffsetDateTime.parse("2018-01-10T12:00:00+00:00", inputPattern);
OffsetDateTime utcWithZ = OffsetDateTime.parse("2018-01-10T12:00:00Z", inputPattern);
OffsetDateTime utcPlus3Hours = OffsetDateTime.parse("2018-01-10T12:00:00.000000+03:00", inputPattern);|
utcWithFractionOfSecond.format(outputPattern ); // 2018-01-10T12:00:00.000000+00:00
utcNoFractionOfSecond.format(outputPattern); // 2018-01-10T12:00:00.000000+00:00
utcWithZ.format(outputPattern); // 2018-01-10T12:00:00.000000+00:00
utcPlus3Hours.format(outputPattern); // 2018-01-10T12:00:00.000000+03:00
In these examples I have used ISO_OFFSET_DATE_TIME only to create the input values for the test cases. In all cases it is the outputPattern yyyy-MM-dd'T'HH:mm:ss.SSSSSSxxx
that controlling how to include a colon character in the timezone portion of your resulting formatted string.
Note that if your input data included the Zone ID like [Europe/London]
then you would create your input data using ZonedDateTime instead of OffsetDateTime
Upvotes: 1
Reputation: 338376
OffsetDateTime.parse( "2014-06-18T09:56:21+00:00" )
2014-06-18T09:56:21Z
Some other answers are close, correct in using the modern java.time classes that supplanted the terrible old legacy classes (Date
, Calendar
, SimpleDateFormat
). But they are either working too hard or chose the wrong class.
Your format is in standard ISO 8601 format. The java.time classes use these standard formats by default when parsing/generating text representing their date-time values. So you need not specify any formatting pattern at all. Works by default.
OffsetDateTime
Your input indicates an offset-from-UTC of zero hours and zero minutes. So we should use the OffsetDateTime
class.
String input = "2014-06-18T09:56:21+00:00";
OffsetDateTime odt = OffsetDateTime.parse( input );
We can generate a string in standard ISO 8601 format by merely calling toString
. The Z
on the end means UTC, and is pronounced “Zulu”.
odt.toString(): 2014-06-18T09:56:21Z
ZonedDateTime
If your input indicated a time zone, rather than merely an offset, we would have used ZonedDateTime
class. An offset is simply a number of hours, minutes, and seconds – nothing more. A time zone is much more. A time zone is a history of past, present, and future changes to the offset used by the people of a particular region.
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?
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.
Upvotes: 0
Reputation: 65813
You can always use a StringBuilder:
new StringBuilder(
new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ")
.format(date))
.insert(22,':')
.toString();
Upvotes: 1
Reputation: 11113
Can you use Java 8?
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("YYYY-MM-dd'T'HH:mm:ssXXX");
System.out.println(formatter.format(ZonedDateTime.now()));
2015-04-15T17:24:19+09:00
Upvotes: 0