Reputation: 23
Consider below string are UTC time and I want equivalent time in milliseconds using java.
String flcDate = "2018-09-07 05:45:00.0";
String geofenceDate = "2018-07-27 08:42:20";
I was trying the below code but it's changing the milliseconds on the basis of in which time zone I am.
public static long stringToMilliSeconds(String string) throws ParseException {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
TimeZone fromTimeZone = calendar.getTimeZone();
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
calendar.setTimeZone(fromTimeZone);
calendar.setTime(sdf.parse(string));
System.out.println(calendar.getTime().toString());
return calendar.getTime().getTime();
}
Upvotes: 1
Views: 2264
Reputation: 86379
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.
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
.
Upvotes: 0
Reputation: 3496
Of course you should use the new java.time* Classes. But if its not possible, try this:
public static long stringToMilliSeconds(String string) throws ParseException {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
Date date = sdf.parse(string);
System.out.println(date.getTime());
return date.getTime();
}
Upvotes: 1
Reputation: 45339
This uses local date-time and instant to convert the string.
return LocalDateTime.parse("2018-09-07 05:45:00.0",
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.S"))
.toInstant(ZoneOffset.UTC)
.toEpochMilli(); //1536299100000
The resulting long
represents Epoch milliseconds for the input date/time (UTC time):
Instant.ofEpochMilli(1536299100000L) ==> 2018-09-07T05:45:00Z
And for the second string, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
can be used as formatter.
Upvotes: 3