zzxdw
zzxdw

Reputation: 65

How to convert date time input string with optional time into UNIX time using java.time

I'm using java.time to convert date time to unix time but the result is not always correct when I have different input formats. In the code below the output is not correct. It converts "2016-06-21-10-19-22" to 2016-06-21T00:00:00+00:00.

If the input is "04/28/2016", "MM/dd/yyyy", the result is correct.

I want to know how to write a function that can convert both date with time and date without time to the correct timeInSeconds?

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(
                "yyyy-MM-dd-HH-mm-ss");
        String dateTimeString = "2016-06-21-10-19-22";
        LocalDate date = LocalDate.parse(dateTimeString, formatter);

        ZonedDateTime resultado = date.atStartOfDay(ZoneId.of("UTC"));

        Instant i = resultado.toInstant();
        long timeInSeconds = i.getEpochSecond();
        int nanoAdjustment = i.getNano();

        System.out.println("" + timeInSeconds + " seconds " + nanoAdjustment + " nanoseconds");//1466467200 seconds 0 nanoseconds

enter image description here

Upvotes: 1

Views: 311

Answers (1)

Ryuzaki L
Ryuzaki L

Reputation: 40008

There are multiple problems in your code, let me try listing one by one

  1. You are always parsing the input string into LocalDate, even it is representing with time
LocalDate date = LocalDate.parse("2016-06-21-10-19-22", formatter);  //2016-06-21 

LocalDate date = LocalDate.parse("2016-06-21", formatter);  //2016-06-21
  1. After parsing the input string into LocalDate, you are always converting it into ZoneDateTime with starting time of the day which is 00:00:00
 ZonedDateTime resultado = date.atStartOfDay(ZoneId.of("UTC"));   //2016-06-21T00:00Z[UTC]
  1. And finally you are converting same ZonedDateTime into Instant irrespective of time from input, which is why you are getting same result always
Instant i = resultado.toInstant().getEpochSecond();  //1466467200

The best to achieve this problem will be using DateTimeFormatter with optional time representation in formatter, and using parseBest

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd[-HH-mm-ss]");

TemporalAccessor dt = parser.parseBest(dateTimeString, LocalDateTime::from, LocalDate::from);

if (dt instanceof LocalDateTime) {
       (LocalDateTime) dt).atOffset(ZoneOffset.UTC).toInstant();
  } else {
       (LocalDate) dt).atStartOfDay(ZoneOffset.UTC).toInstant();
 }

Upvotes: 1

Related Questions