I get a timestamp in the format "20210908094049.884Z". This is the last modify timestamp from an LDAP object. I use Spring Boot Ldap. I have no clue how to parse this String in a Datetime like dd.MM.yyyy HH:mm.
Can anyone help me please?
Here is an example:
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Main {
public static void main(String[] args) {
// Creating new simple date formatter with the format you've given
SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss.SSS");
// Defining the input date
String inputDate = "20210908094049.884Z";
// Parsing the date, catching the parse exception if date is malformatted
Date date = null;
try {
// Date ends on a Z, we remove this Z (Z is for timezone UTC +0:00)
date = format.parse(inputDate.replace("Z", ""));
System.out.println(date);
} catch (ParseException e) {
e.printStackTrace();
}
}
}
Giving following output:
Wed Sep 08 09:40:49 CEST 2021
Edit:
Here another even better solution from Ole V.V.
import java.time.Instant;
import java.time.format.DateTimeFormatter;
public class Main {
public static void main(String[] args) {
Instant instant = DateTimeFormatter
// Defining pattern to parse
.ofPattern("yyyyMMddHHmmss.SSSXX")
// Defining input to parse with pattern
.parse("20210908094049.884Z", Instant::from);
System.out.println(instant);
}
}
Output is an instant with value:
2021-09-08T09:40:49.884Z
java.time
I recommend that you use java.time, the modern Java date and time API, for your work with timestamps.
The LDAP timestamp format has a number of allowed variations (see the link at the bottom). The following formatter takes many of them into account, not all of them.
private static final DateTimeFormatter LDAP_PARSER = new DateTimeFormatterBuilder()
.appendPattern("uuuuMMddHHmmss")
.optionalStart()
.appendPattern("[.][,]")
.appendFraction(ChronoField.NANO_OF_SECOND, 1, 9, false)
.optionalEnd()
.appendPattern("[XX][X]")
.toFormatter(Locale.ROOT);
With this formatter we may for example parse your string into an OffsetDateTime:
String ldapTimestampString = "20210908094049.884Z";
OffsetDateTime timestamp = OffsetDateTime.parse(ldapTimestampString, LDAP_PARSER);
System.out.println(timestamp);
Output is:
2021-09-08T09:40:49.884Z
Formatting
To convert the timestamp to a string containing date and time you need to decide on a time zone for that since it is never the same date nor the same time in all time zones.
Use this formatter:
private static final DateTimeFormatter FORMATTER
= DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm");
Then do:
ZoneId zone = ZoneId.of("Pacific/Tarawa");
ZonedDateTime dateTime = timestamp.atZoneSameInstant(zone);
String formattedDateTime = dateTime.format(FORMATTER);
System.out.println(formattedDateTime);
08.09.2021 21:40
Links
Oracle tutorial: Date Time explaining how to use java.time.
GeneralizedTime on ldapwiki defining the LDAP timestamp format.
Related
The function shown below returns the date, e.g. "Sat Sep 8 00:00 PDT 2010". But I expected to get the date in the following format "yyyy-MM-dd HH:mm". What's wrong in this code?
String date = "2010-08-25";
String time = "00:00";
Also in one laptop the output for,e.g. 23:45 is 11:45. How can I define exactly the 24 format?
private static Date date(final String date,final String time) {
final Calendar calendar = Calendar.getInstance();
String[] ymd = date.split("-");
int year = Integer.parseInt(ymd[0]);
int month = Integer.parseInt(ymd[1]);
int day = Integer.parseInt(ymd[2]);
String[] hm = time.split(":");
int hour = Integer.parseInt(hm[0]);
int minute = Integer.parseInt(hm[1]);
calendar.set(Calendar.YEAR,year);
calendar.set(Calendar.MONTH,month);
calendar.set(Calendar.DAY_OF_MONTH,day);
calendar.set(Calendar.HOUR,hour);
calendar.set(Calendar.MINUTE,minute);
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
Date d = calendar.getTime();
String dateString= dateFormat.format(d);
Date result = null;
try {
result = (Date)dateFormat.parse(dateString);
} catch (ParseException e) {
e.printStackTrace();
}
return result;
}
What's wrong in this code?
You seem to be expecting the returned Date object to know about the format you've parsed it from - it doesn't. It's just an instant in time. When you want a date in a particular format, you use SimpleDateFormat.format, it's as simple as that. (Well, or you use a better library such as Joda Time.)
Think of the Date value as being like an int - an int is just a number; you don't have "an int in hex" or "an int in decimal"... you make that decision when you want to format it. The same is true with Date.
(Likewise a Date isn't associated with a specific calendar, time zone or locale. It's just an instant in time.)
How did you print out the return result? If you simply use System.out.println(date("2010-08-25", "00:00") then you might get Sat Sep 8 00:00 PDT 2010 depending on your current date time format setting in your running machine. But well what you can do is:
Date d = date("2010-08-25", "00:00");
System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm").format(d));
Just curious why do you bother with this whole process as you can simple get the result by concatenate your initial date and time string.
just use SimpleDateFormat class
See
date formatting java simpledateformat
The standard library does not support a formatted Date-Time object.
The function shown below returns the date, e.g. "Sat Sep 8 00:00 PDT
2010". But I expected to get the date in the following format
"yyyy-MM-dd HH:mm".
The standard Date-Time classes do not have any attribute to hold the formatting information. Even if some library or custom class promises to do so, it is breaking the Single Responsibility Principle. A Date-Time object is supposed to store the information about Date, Time, Timezone etc., not about the formatting. The only way to represent a Date-Time object in the desired format is by formatting it into a String using a Date-Time parsing/formatting type:
For the modern Date-Time API: java.time.format.DateTimeFormatter
For the legacy Date-Time API: java.text.SimpleDateFormat
About java.util.Date:
A java.util.Date object simply represents the number of milliseconds since the standard base time known as "the epoch", namely January 1, 1970, 00:00:00 GMT (or UTC). Since it does not hold any timezone information, its toString function applies the JVM's timezone to return a String in the format, EEE MMM dd HH:mm:ss zzz yyyy, derived from this milliseconds value. To get the String representation of the java.util.Date object in a different format and timezone, you need to use SimpleDateFormat with the desired format and the applicable timezone e.g.
Date date = new Date(); // In your case, it will be Date date = date("2010-08-25", "00:00");
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.ENGLISH);
// sdf.setTimeZone(TimeZone.getTimeZone("America/New_York")); // For a timezone-specific value
String strDate = sdf.format(date);
System.out.println(strDate);
Your function, Date date(String, String) is error-prone.
You can simply combine the date and time string with a separator and then use SimpleDateFormat to parse the combined string e.g. you can combine them with a whitespace character as the separator to use the same SimpleDateFormat shown above.
private static Date date(final String date, final String time) throws ParseException {
return sdf.parse(date + " " + time);
}
Note that using a separator is not a mandatory requirement e.g. you can do it as sdf.parse(date + time) but for this, you need to change the format of sdf to yyyy-MM-ddHH:mm which, although correct, may look confusing.
Demo:
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
public class Main {
static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.ENGLISH);
public static void main(String[] args) throws ParseException {
Date date = date("2010-08-25", "00:00");
String strDate = sdf.format(date);
System.out.println(strDate);
}
private static Date date(final String date, final String time) throws ParseException {
return sdf.parse(date + " " + time);
}
}
Output:
2010-08-25 00:00
ONLINE DEMO
Switch to java.time API.
The java.util Date-Time API and their formatting API, SimpleDateFormat are outdated and error-prone. It is recommended to stop using them completely and switch to the modern Date-Time API*.
Solution using java.time, the modern Date-Time API:
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
LocalDateTime ldt = localDateTime("2010-08-25", "00:00");
// Default format i.e. the value of ldt.toString()
System.out.println(ldt);
// Custom format
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm", Locale.ENGLISH);
String strDate = dtf.format(ldt);
System.out.println(strDate);
}
private static LocalDateTime localDateTime(final String date, final String time) {
return LocalDateTime.of(LocalDate.parse(date), LocalTime.parse(time));
}
}
Output:
2010-08-25T00:00
2010-08-25 00:00
ONLINE DEMO
You must have noticed that I have not used DateTimeFormatter for parsing the String date and String time. It is because your date and time strings conform to the ISO 8601 standards. The modern Date-Time API is based on ISO 8601 and does not require using a DateTimeFormatter object explicitly as long as the Date-Time string conforms to the ISO 8601 standards.
Learn more about the modern Date-Time API from Trail: Date Time.
* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.
I'm surprise you are getting different date outputs on the different computers. In theory, SimpleDateFormat pattern "H" is supposed to output the date in a 24h format. Do you get 11:45pm or 11:45am?
Although it should not affect the result, SimpleDateFormat and Calendar are Locale dependent, so you can try to specify the exact locale that you want to use (Locale.US) and see if that makes any difference.
As a final suggestion, if you want, you can also try to use the Joda-Time library (DateTime) to do the date manipulation instead. It makes it significantly easier working with date objects.
DateTime date = new DateTime( 1991, 10, 13, 23, 39, 0);
String dateString = new SimpleDateFormat("yyyy-MM-dd HH:mm").format( date.toDate());
DateTime newDate = DateTime.parse( dateString, DateTimeFormat.forPattern("yyyy-MM-dd HH:mm"));
I am trying to convert java String date into java.sql.Timestamp. I am able to convert this by using SimpleDateFormat with String date value as "2021-01-07 02:02:16.172", but when trying with the value as "2021-08-04T00:00:00.000" with seperator 'T', it gives me error. Below is the java code:
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class DateTest {
public static void main(String[] args) throws ParseException {
//String date = "2021-08-04T00:00:00.000Z";// How to convert this?
String date = "2021-01-07 02:02:16.172";// conversion successful
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss.SSS");
Date parsedDate = dateFormat.parse(date);
Timestamp timestamp = new java.sql.Timestamp(parsedDate.getTime());
System.out.println(timestamp);
}
}
You could use the modern API for dates, times and related information (like offsets from UTC): java.time
Strings in different formats need to be handled differently:
your first example String is formatted in ISO standard, so it can be parsed without defining a custom format. The parsing implicitly uses a DateTimeFormatter.ISO_OFFSET_DATE_TIME, which will result in an OffsetDateTime
your seconds String lacks the 'T' between date and time as well as an offset, that means you can just directly parse it to a LocalDateTime
java.sql.Timestamp got methods for conversion to java.time classes, at least to/from an Instant and a LocalDateTime. Since an Instant is a well defined moment in time, you can derive it from an OffsetDateTime:
public static void main(String[] args) throws Exception {
// your two example datetimes
String isoDateTime = "2021-08-04T00:00:00.000Z";
String customDateTime = "2021-01-07 02:02:16.172";
// you will need a custom formatter for the second one
DateTimeFormatter customDtf = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss.SSS");
// parse the Strings to java.time objects
// ISO standard, no extra formatter needed for the first one
OffsetDateTime odt = OffsetDateTime.parse(isoDateTime);
// the second one requires the formatter defined above
LocalDateTime ldt = LocalDateTime.parse(customDateTime, customDtf);
// convert them into Timestamps
Timestamp tsOne = Timestamp.from(odt.toInstant());
Timestamp tsTwo = Timestamp.valueOf(ldt);
// and print them
System.out.println("First Timestamp: " + tsOne);
System.out.println("Second Timestamp: " + tsTwo);
}
The output of this is
First Timestamp: 2021-08-04 02:00:00.0
Second Timestamp: 2021-01-07 02:02:16.172
This would be the new style...
new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss.SSS");
would be the old style
Given:
public static void main(String[] args) {
String dateString = "2018-07-30T13:36:17.820";
DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter
.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS");
LocalDate date = LocalDate.parse(dateString, DATE_TIME_FORMATTER);
ZonedDateTime zonedDateTime = date.atStartOfDay((ZoneOffset.UTC));
System.out.println(zonedDateTime);
}
And output:
2018-07-30T00:00Z
...what is the pattern to print seconds? Stupid question no doubt but driving me a little nuts
I need:
2018-07-30T00:00:00Z
I changed java.time.LocalDate to java.time.LocalDateTime, you need it if you want to show also the seconds.
package com.test;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
public class DateFormatter {
public static void main(String[] args) {
String dateString = "2018-07-30T13:36:17.820";
DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter
.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS");
LocalDateTime date = LocalDateTime.parse(dateString, DATE_TIME_FORMATTER);
ZonedDateTime zonedDateTime = date.atZone(ZoneOffset.UTC);
System.out.println(zonedDateTime);
}
}
Output is:
2018-07-30T13:36:17.820Z
LocalDate will keep just date. You need to parse LocalDateTime and convert to ZonedDateTime and you will have seconds as you expect.
var dateString = "2018-07-30T13:36:17.820";
var format = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS");
var localDate = LocalDateTime.parse(dateString, format);
var zone = ZoneId.of( "America/Montreal" );
var zonedDateTime = localDate.atZone(zone);
System.out.println(zonedDateTime);
You will have to go a few steps:
parse the String to a LocalDateTime because it contains date and time of day
extract the date only
create a ZonedDateTime out of that by adding the start of day (LocalTime.MIN = 00:00:00) and a ZoneOffset.UTC
This code may do:
public static void main(String[] args) {
String dateString = "2018-07-30T13:36:17.820";
// parse a LocalDateTime
LocalDateTime localDateTime = LocalDateTime.parse(dateString);
// extract the date part
LocalDate localDate = localDateTime.toLocalDate();
// make it a ZonedDateTime by applying a ZoneId
ZonedDateTime zonedDateTime = ZonedDateTime.of(localDate, LocalTime.MIN, ZoneOffset.UTC);
// print the result
System.out.println(zonedDateTime.format(DateTimeFormatter.ISO_ZONED_DATE_TIME));
}
Output is
2018-07-30T00:00:00Z
There are several ways to do it, this is just one of them and it just slightly differs from most of the other answers (and comments :-) ).
tl;dr
You have used the wrong things in the wrong places.
You do not need a DateTimeFormatter explicitly in order to parse 2018-07-30T13:36:17.820 because it's already in ISO 8601 format which is also the default format used by LocalDateTime#parse. Moreover, this string has date and time instead of just date; therefore, it makes more sense to parse it into LocalDateTime instead of LocalDate. You can always get LocalDate from LocalDateTime using LocalDateTime#toLocalDate.
The ZonedDateTime#toString uses the LocalDateTime#toString which in turn uses LocalTime#toString for the time part which omits second and fraction-of-second if they are zero. If you need a string with zero second and fraction-of-second, you will need to use a DateTimeFormatter.
Demo:
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
public class Main {
public static void main(String args[]) {
String dateString = "2018-07-30T13:36:17.820";
LocalDateTime localDateTime = LocalDateTime.parse(dateString);// You do not need a DateTimeFormatter here
ZonedDateTime zonedDateTime = localDateTime.toLocalDate().atStartOfDay(ZoneOffset.UTC);
// Print zonedDateTime.toString()
System.out.println(zonedDateTime);
// Custom format
final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS");
System.out.println(DATE_TIME_FORMATTER.format(zonedDateTime));
}
}
Output:
2018-07-30T00:00Z
2018-07-30T00:00:00.000
Learn more about the modern date-time API from Trail: Date Time.
I currently have a Date e.g. "2015-10-10T14:34:22Z". I need the year from the Date object for my new LocalDateTime object as this object will be set to that Date object year and have a specific month, day and time set (yyyy-06-15T17:00:00Z).
Taking the getYear() from Date has the 1900 issue.
I get the date via LocalDate date = input.toInstant().atZone(ZoneId.systemDefault()).toLocalDate()
Create another object to set the desired month and day
Create LocalDateTime object to set the time
I feel I am doing it a very long convuluted way and would like to ask if there are any other shorter and better alternatives.
EDIT:
Are there are any other shorter and better alternatives?
Since your date-time string has timezone offset information. So, you can parse it to an OffsetDateTime object and then get the year from it.
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
public class Main {
public static void main(String[] args) {
String strDateTime = "2015-10-10T14:34:22Z";
OffsetDateTime odt = OffsetDateTime.parse(strDateTime);
System.out.println(odt);
System.out.println(odt.getYear());
// If you want to get LocalDateTime from OffsetDateTime
LocalDateTime ldt = odt.toLocalDateTime();
System.out.println(ldt);
}
}
Output:
2015-10-10T14:34:22Z
2015
2015-10-10T14:34:22
Note that Z in the date-time string stands for Zulu date-time and specifies a timezone offset of +00:00 hours or date-time at UTC.
Taking the getYear() from Date has the 1900 issue.
The date-time API of java.util and their formatting API, SimpleDateFormat are outdated and error-prone. I suggest you should stop using them completely and switch to the modern date-time API. Learn more about the modern date-time API at Trail: Date Time.
If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.
Converting from legacy API to the modern API:
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.util.Date;
public class Main {
public static void main(String[] args) throws ParseException {
String strDateTime = "2015-10-10T14:34:22Z";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX");
Date date = sdf.parse(strDateTime);
Instant instant = date.toInstant();
OffsetDateTime odt = instant.atOffset(ZoneOffset.UTC);
System.out.println(odt);
System.out.println(odt.getYear());
// If you want to get LocalDateTime from OffsetDateTime
LocalDateTime ldt = odt.toLocalDateTime();
System.out.println(ldt);
}
}
Output:
2015-10-10T14:34:22Z
2015
2015-10-10T14:34:22
Note: If you want to convert the Instant into ZonedDateTime at UTC, you can do it as follows:
ZonedDateTime zdt = instant.atZone(ZoneOffset.UTC);
or the following:
ZonedDateTime zdt = instant.atZone(ZoneId.of("Etc/UTC"));
Note that the three-letter name for a ZoneId is error-prone i.e. avoid using something like ZoneId.of("UTC").
What is wrong with your code:
You are using .atZone(ZoneId.systemDefault()) which is converting the object of Instant to an object of ZonedDateTime with your JVM's timezone. You have to use .atOffset(ZoneOffset.UTC) as shown above to keep the date-time with the same timezone offset (i.e. +00:00 hours or date-time at UTC) which is there in the date-time string.
try this :
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ssX");
try {
String s = "2015-10-10T14:34:22+02";
s = s.replaceAll("T", " ");
Date d = df.parse(s);
Calendar cl = Calendar.getInstance();
cl.setTime(d);
System.out.println(cl.getTime());
System.out.println("year : " + cl.get(Calendar.YEAR));
} catch (ParseException e) {
System.err.println(e);
}
output
Sat Oct 10 13:34:22 GMT+01:00 2015
year : 2015
Maybe this approach could help:
import java.text.ParseException;
import java.time.*;
import java.util.Date;
public class ConvertDate {
public static void main(String[] args) throws ParseException {
Date date = new Date();
LocalDateTime localDateTime = date.toInstant().atOffset(ZoneOffset.UTC).toLocalDateTime();
System.out.println(localDateTime);
System.out.println(localDateTime.getYear());
}
}
Time zone is crucial
You need to decide in which time zone you want the year. New Year doesn’t happen at one point in time across the globe, but over a span of about 26 hours. So if your date string is within a day or so of New Year, your result could be off by a year if you don’t pick the correct time zone. For example:
ZoneId zone = ZoneId.of("America/Louisville");
// The year in the following object does not matter
ZonedDateTime fixedTimeOfYear = ZonedDateTime.of(2020, 6, 15, 17, 0, 0, 0, zone);
String inputString = "2015-01-01T01:02:03Z";
OffsetDateTime input = OffsetDateTime.parse(inputString);
int year = input.atZoneSameInstant(zone).getYear();
System.out.format("Year in %s is %d%n", zone, year);
ZonedDateTime desiredTime = fixedTimeOfYear.withYear(year);
System.out.println("Result: " + desiredTime);
Output from this snippet is:
Year in America/Louisville is 2014
Result: 2014-06-15T17:00-04:00[America/Louisville]
You notice that even though the year in the string is 2015, it is still only 2014 in the time zone that I chose for the demonstration, so the resulting date and time are in 2014. The example was picked to demonstrate my point.
Don’t use LocalDateTime
The frequent use of LocalDateTime that you mention in a comment is a misunderstanding. For a date and time in a known time zone in 2015, for example, LocalDateTime is the wrong class to use. Use ZonedDateTime or at least OffsetDateTime so we know what we are talking about. These classes have the advantages that they keep track of time zone or offset themselves, and that they define an unambiguous point in time. LocalDateTime does nothing of this.
I have a string - 20180915 in format yyyyMMdd
I need to get epoch milli seconds for this date, answer for 20180915 should be 1537012800000
I was able to do this using following function -
import java.text.ParseException;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
public static void main(String args[]) throws ParseException {
String myDate = "2018-09-15 12:00:00";
LocalDateTime localDateTime = LocalDateTime.parse(myDate,
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss") );
System.out.println(localDateTime);
long millis = localDateTime
.atZone(ZoneOffset.UTC)
.toInstant().toEpochMilli();
System.out.println(millis);
}
The problem I am facing is -
I am passing String as "2018-09-15 12:00:00" but my input is "20180915".
I am unable to find good way to convert "20180915" to "2018-09-15 12:00:00"
How can i achieve this ?
Answer -
private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
public static Long getMillisForDate(String date) {
return LocalDateTime
.of(LocalDate.parse(date, formatter), LocalTime.NOON)
.atZone(ZoneOffset.UTC)
.toInstant().toEpochMilli();
}
You can make the DateTimeFormatter do all the work, which is especially useful if you need to parse multiple dates, as it reduces the number of intermediate parsing steps (and objects created):
DateTimeFormatter fmt = new DateTimeFormatterBuilder()
.appendPattern("uuuuMMdd")
.parseDefaulting(ChronoField.HOUR_OF_DAY, 12)
.toFormatter()
.withZone(ZoneOffset.UTC);
String input = "20180915";
long epochMilli = OffsetDateTime.parse(input, fmt).toInstant().toEpochMilli();
System.out.println(epochMilli); // prints: 1537012800000
You can replace OffsetDateTime with ZonedDateTime. Makes no difference to the result.
Parse the date with proper mask "yyyyMMdd"
SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
Date date = format.parse("20180915");
long epochs = date.getTime();