0

I have the following input String "30-JUL-21" for my date, and I want to convert to an Instant. But I cannot find the correct solution... do you have an idea?
I already tried with

SimpleDateFormat sdfmt2 = new SimpleDateFormat("dd-MMM-yy");
result = sdfmt2.parse(source).toInstant();

but it doesn't work properly.

my code:

String src = "30-JUL-21";
Instant result = null;

if (!StringUtils.isEmpty(src)) {
    try {
        SimpleDateFormat sdfmt2= new SimpleDateFormat("dd-MMM-yy");
        result = sdfmt2.parse(src).toInstant();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

return result;
deHaar
  • 17,687
  • 10
  • 38
  • 51
Adrien Ruffie
  • 195
  • 4
  • 16
  • What's not working? I quickly ran a test, and it seems your code works as expected. – Deltharis Jul 10 '20 at 09:23
  • What's your desired / expected output here? Do you need the epoch millis of that `Instant`? Why do you use the outdated `SimpleDateFormat` when there is a `DateTimeFormatter`? – deHaar Jul 10 '20 at 09:23
  • Please give the expected and the original output so that we can help you much better – Sumit Singh Jul 10 '20 at 09:27
  • No sorry @deHaar not working for me ... (JDK11) I got this : java.text.ParseException: Unparseable date: "30-JUL-21" (I edit the post for display to you my code) – Adrien Ruffie Jul 10 '20 at 09:46
  • @SumitSingh already said input String = "30-JUL-21" and expected output -> a Instant in java – Adrien Ruffie Jul 10 '20 at 09:48
  • 3
    Your code works as is for me. If it doesn't for you, than it probably means your Locale requires month name to be different? Try `new SimpleDateFormat("dd-MMM-yy", Locale.US);` – Deltharis Jul 10 '20 at 10:02
  • @Deltharis That's a good point... The `Locale` may be one of the reasons for *not working* here. But I think using plain `java.time` is recommended anyway. – deHaar Jul 10 '20 at 10:05
  • thank @Deltharis it work properly :-) ! I take your solution – Adrien Ruffie Jul 10 '20 at 10:17
  • I recommend you don’t use `SimpleDateFormat` and `Date`. Those classes are poorly designed and long outdated, the former in particular notoriously troublesome. Instead use `DateTimeFormatter` and other classes from [java.time, the modern Java date and time API](https://docs.oracle.com/javase/tutorial/datetime/). The answer by deHaar shows the direct way. – Ole V.V. Jul 10 '20 at 14:38

1 Answers1

3

You could build a DateTimeFormatter that parses case insensitively and uses an English Locale along with a matching pattern, because your representation of the month is not parseable by a pattern only.

See the following example where every step is done explicitly and where UTC is used as time zone. Alternatively, you can use the time zone of the system by replacing ZoneId.of("UTC") with ZoneId.systemDefault(), which will affect the output, of course, if the system's time zone is not UTC. I chose UTC here to have comparable output since I don't know your time zone (do you?):

public static void main(String[] args) {
    // example input
    String source = "30-JUL-21";
    // create a formatter that parses case-insensitively using a matching pattern
    DateTimeFormatter caseInsensitiveDtf = new DateTimeFormatterBuilder()
                                                .parseCaseInsensitive()
                                                .appendPattern("dd-MMM-uu")
                                                .toFormatter(Locale.ENGLISH);
    // parse the String using the previously defined formatter
    LocalDate localDate = LocalDate.parse(source, caseInsensitiveDtf);
    // print this intermediate result
    System.out.println(localDate);
    // build up a datetime by taking the start of the day and adding a time zone
    ZonedDateTime zdt = localDate.atStartOfDay(ZoneId.of("UTC"));
    // print that intermediate result, too
    System.out.println(zdt);
    // then simply convert it to an Instant
    Instant instant = zdt.toInstant();
    // and print the epoch millis of it
    System.out.println(instant.toEpochMilli());
}

The output of it is this (last print uses the resulting Instant):

2021-07-30
2021-07-30T00:00Z[UTC]
1627603200000
deHaar
  • 17,687
  • 10
  • 38
  • 51
  • deHaar No sorry I tried your code, add nothing ... your code generate too "java.time.format.DateTimeParseException: Text '30-JUL-21' could not be parsed at index 3" on line LocalDate localDate = LocalDate.parse(source, caseInsensitiveDtf); – Adrien Ruffie Jul 10 '20 at 10:10
  • 1
    @AdrienRuffie Try again with the updated code, I forgot to specify the `Locale` in the first version. – deHaar Jul 10 '20 at 10:11
  • @OleV.V. Thanks! I optimized the code of my answer according to your suggestions, added a hint to `ZoneId.systemDefault()` and explained why I use UTC here. – deHaar Jul 11 '20 at 08:27
  • 1
    @OleV.V. Don't know ;-) SO could introduce a different bounty for optimizing answers ^^ Like *Refinery points* or some badges users can get if they *follow suggestions given by moderators / site veterans and improve answers by including those suggestions* or similar ;-). – deHaar Jul 11 '20 at 08:36