You can change this answer to return epoch millis like
static long dateTimeStringToEpoch(String s, String pattern) {
return DateTimeFormatter.ofPattern(pattern).withZone(ZoneOffset.UTC)
.parse(s, Instant::from).toEpochMilli();
}
Or, if you even want to avoid the construction of a temporary Instant:
static long dateTimeStringToEpoch(String s, String pattern) {
return DateTimeFormatter.ofPattern(pattern).withZone(ZoneOffset.UTC)
.parse(s, ta -> ta.getLong(ChronoField.INSTANT_SECONDS)*1000
+ta.get(ChronoField.MILLI_OF_SECOND));
}
Note that both, DateTimeFormatter.ofPattern(pattern).withZone(ZoneOffset.UTC) and ta -> ta.getLong(ChronoField.INSTANT_SECONDS)*1000+ta.get(ChronoField.MILLI_OF_SECOND) are reusable components here, e.g. you could do
static final DateTimeFormatter MY_PATTERN
= DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm").withZone(ZoneOffset.UTC);
static final TemporalQuery EPOCH_MILLIS
= ta -> ta.getLong(ChronoField.INSTANT_SECONDS)*1000+ta.get(ChronoField.MILLI_OF_SECOND);
and
long millis = MY_PATTERN.parse("2018-07-21 18:30", EPOCH_MILLIS);
The question is, how many different format strings do you expect to occur within you application. Usually, it’s not something that changes as often as the formatted dates you have to parse. It might be beneficial to create a cache mapping from format string to prepared DateTimeFormatter. The lambda expression is a singleton anyway.