Modify the input
As far as I know, none of the three common date-time frameworks for Java (the old bundled java.util.Date/.Calendar/java.text.SimpleDateFormat classes, the Joda-Time framework, or the java.time framework built into Java 8 and later) allow for an offset-from-UTC as a total number of minutes.
As suggested by Sotirios Delimanolis, you must modify the offset-from-UTC to convert from a number of total minutes to the standard number of hours and minutes (and seconds – a possibility ignored by that odd Microsoft format). So -420
should become -07:00
or -07:00:00
.
java.time
You are using the troublesome old date-time classes bundled with the earliest versions of Java. The old classes are now legacy, and have been supplanted by the java.time framework built into Java 8 and later, and largely back-ported to Java 6 & 7 by the ThreeTen-Backport project and further adapted to Android.
The java.time classes have a resolution of nanoseconds, for up to nine digits of a decimal fraction of second. So no problem handling your inputs 4-6 digits of fractional second.
Our strategy has two parts: (a) Modify the input to convert that offset-from-UTC, and (b) Parse the modified input string as a date-time object.
Modify input
First we change the input from 20160513072950.782000-420
to 20160513072950.782000-07:00:00
. We do this by extracting the characters trailing after the +
or -
, the 420
in this case.
// Modify the input to replace offset as a number of minutes to the standard format, a number of hours, minutes, and seconds.
String input = "20160513072950.782000-420";
String offsetInMinutesAsString = input.substring ( 22 );
Convert that to a long
, and create a LocalTime
object so that we can generate a string in the format of HH:mm:ss
.
long offsetInMinutes = Long.parseLong ( offsetInMinutesAsString );
LocalTime offsetAsLocalTime = LocalTime.MIN.plusMinutes ( offsetInMinutes );
String offsetAsString = offsetAsLocalTime.format ( DateTimeFormatter.ISO_LOCAL_TIME );
Replace those trailing characters with our generated string.
String inputModified = ( input.substring ( 0 , 22 ) + offsetAsString );
Parse string to date-time object
Define a custom formatting pattern by which to parse that string into a OffsetDateTime
object.
// Parse the modified input as an OffsetDateTime.
DateTimeFormatter formatter = DateTimeFormatter.ofPattern ( "yyyyMMddHHmmss.SSSSSSZZZZZ" , Locale.US );
OffsetDateTime odt = OffsetDateTime.parse ( inputModified , formatter );
Dump to console.
System.out.println ( "input: " + input + " | inputModified: " + inputModified + " | odt: " + odt );
input: 20160513072950.782000-420 | inputModified: 20160513072950.782000-07:00:00 | odt: 2016-05-13T07:29:50.782-07:00
Convert
I strongly suggest avoiding the old date-time classes. But if you must use a java.util.Date
object to interoperate with old date-time code, you can convert.
Look for new methods added to the old classes for conversion. For this conversion we use java.util.Date.from
. We need to feed that conversion method a Instant
object, a moment on the timeline in UTC with a resolution of nanoseconds. We can extract one from our OffsetDateTime
.
Instant instant = odt.toInstant();
java.util.Date utilDate = java.util.Date.from( instant );
For more info about converting, including a nifty diagram, see my Answer to another Question. Keep in mind that we are working with only a mere offset-from-UTC in our input strings and our OffsetDateTime
, not a full time zone. A time zone is an offset plus rules for handling anomalies such as Daylight Saving Time (DST). Both the Instant
and the java.util.Date
are in UTC (an offset of zero).