java.time
This one should be flexible enough to accept both of your strings:
private static DateTimeFormatter FORMATTER = new DateTimeFormatterBuilder()
.append(DateTimeFormatter.ISO_LOCAL_DATE)
.appendLiteral(' ')
.append(DateTimeFormatter.ISO_LOCAL_TIME)
.toFormatter();
public static long stringToMilliseconds(String string) {
return LocalDateTime.parse(string, FORMATTER)
.toInstant(ZoneOffset.UTC)
.toEpochMilli();
}
Demonstration:
String flcDate = "2018-09-07 05:45:00.0";
System.out.println(stringToMilliseconds(flcDate)); // 1536299100000
String geofenceDate = "2018-07-27 08:42:20";
System.out.println(stringToMilliseconds(geofenceDate)); // 1532680940000
Output is in the comments.
The built-in DateTimeFormatter.ISO_LOCAL_DATE
accepts a date string like 2018-09-10. DateTimeFormatter.ISO_LOCAL_TIME
accepts a time string like 10:15 or 05:45:00.0. The seconds and fraction of second are optional, and the fraction may be up to 9 decimals. I use a DateTimeFormatterBuilder
for building the two formatters into one with a space between the date and the time.
The ‘local’ in LocalDateTime
(and other java.time class names) means “without time zone information”, so the use of this class makes sure that no unintended time zone, like your default one, interferes. And the use of ZoneOffset.UTC
in the conversion to Instant
makes sure we get the time in UTC.
What went wrong in your code?
Despite your time zone operations, your SimpleDateFormat
uses your local time zone and therefore produces a point in time of 2018-09-07 05:45:00.0 in your local time zone, not in UTC. After that error is introduced, it propagates through your Calendar
object and back out into your return value.
I recommend you don’t use SimpleDateFormat
, Calendar
and TimeZone
at all. Those classes are long outdated, and SimpleDateFormat
in particular is notoriously troublesome. Today we have so much better in java.time, the modern Java date and time API.
Link: Oracle tutorial: Date Time explaining how to use java.time
.