0

I'm using a Java DateTimeFormatter in order to parse dates and datetimes. I construct it with a DateTimeFormatterBuilder dtfb, and then try to get epoch seconds from it as follows:

dtfb.toFormatter().withZone(ZoneId.of("America/New_York"))
      .parse(timeStr)
      .getLong(ChronoField.INSTANT_SECONDS)

However, this only works if timeStr is specific enough to identify one particular second. For example, this works: "1997.10.10 23:45:23", but this does not "1997.10.10", as there's no hour minute second information. I'm wondering if there's a way in Java to systematically "round down" and return the first timestamp that fits the constraints. For example, in this failing case I'd want the answer to be the timestamp at "1997.10.10 00:00:00". Basically just keep filling in zeros in smaller and smaller time units until it's specific enough to give me a second. Is this possible?

John
  • 2,575
  • 1
  • 17
  • 29
  • May help: [Java 8 DateTimeFormatter with optional part](https://stackoverflow.com/a/48281350/6395627). – Slaw Jan 13 '20 at 20:25
  • 3
    Does this answer your question? [Parse date-only as LocalDateTime in Java 8](https://stackoverflow.com/questions/49323017/parse-date-only-as-localdatetime-in-java-8) – jrook Jan 13 '20 at 20:44
  • @Slaw With `parseBest`, one needs to be careful to retrieve an *Instant* not a *LocalDateTime* or the like, since the OP wants to obtain `INSTANT_SECONDS` which is not available in a `LocalDateTime`. It seems to me that at least with the constraints of this question, `parseDefaulting` is the way to go. – jrook Jan 13 '20 at 20:49

1 Answers1

2

I think this might be what you want to do. I tried with ChronoField.SECOND_OF_DAY, but that results in a java.time.DateTimeException: Conflict found: HourOfDay 23 differs from HourOfDay 0 while resolving when using your example with a timestamp.

Note that you must start the building with the formatting string. If you use .parseDefaulting prior to .appendPattern, you get a java.time.format.DateTimeParseException.

import java.time.format.DateTimeFormatterBuilder;
import java.time.temporal.ChronoField;
import java.time.ZoneId;

class Testing {
  public static void main(String[] args) {
    DateTimeFormatterBuilder dtfb =
      new DateTimeFormatterBuilder()
        .appendPattern("yyyy.dd.MM[ HH:mm:ss]")
        .parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
        .parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0)
        .parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0);

    String timeStr = "1997.10.10";
//    String timeStr = "1997.10.10 00:00:01";
//    String timeStr = "1997.10.10 23:45:23";

    Long instant =
      dtfb.toFormatter().withZone(ZoneId.of("America/New_York"))
          .parse(timeStr)
          .getLong(ChronoField.INSTANT_SECONDS);

    System.out.println(instant);
  }
}
Scratte
  • 3,056
  • 6
  • 19
  • 26
  • 2
    This is an almost exact replication of the answer in [this question](https://stackoverflow.com/questions/49323017/parse-date-only-as-localdatetime-in-java-8). Please mark the question as duplicate in such cases. – jrook Jan 13 '20 at 22:16
  • Sorry. I hadn't seen that. Should I delete my answer? – Scratte Jan 13 '20 at 22:50
  • You don't need to delete it. If you agree that this question can be answered by the linked question please mark it as duplicate. If you feel your answer can add extra stuff not present in the linked question, edit your answer and clearly demonstrate why the question is not a duplicate. – jrook Jan 13 '20 at 23:01