1

I am given a txt with some specific format. The format is supposed to be starting with dd/MM/uuuu. However i would like to check if it is indeed this specific format or else my code will break.

Now my thoughts were to check if the specific 10 first chars(with the delimeters) can define a LocalDate object. So i came up with this:

public boolean isDate(String date) {

    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/uuuu");
    LocalDate ld = null;
    try {
        ld = LocalDate.parse(date, formatter);
        System.out.println(ld);
    } catch (DateTimeParseException e) {
        System.out.println("Date " + date + " is not a date.");
        return false;

    }

    return true;
}

However this is not the best practice because i am controling the programm flow with exceptions. Plus i have to check another 8 fields to be representing time etc.. so my code will be full of try catches. Is there a more effecient way to go around this?

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
Kostas Thanasis
  • 368
  • 4
  • 11
  • 5
    I don't think it's bad practice in this example. At least I've personally never heard of try/catch blocks worsening the programm flow. This entire method of testing is based on the idea of parsing a String to a different data type and catching a potential Exception that the String can't be transformed. May I ask how you came to the conclusion that catching Exceptions in situations like this is not good practice? – yur Nov 07 '19 at 13:24
  • "However this is not the best practice because i am controling the programm flow with exceptions.". Bad practice? And why? – Roberto Manfreda Nov 07 '19 at 13:24
  • 1
    I don’t think there is an alternative unless you use a less restrictive check like regex. – AndyMan Nov 07 '19 at 13:29
  • 1
    When I read only the title of this question, before clicking it to see the actual question, the solution that popped up in my mind was like the one you have already done. – Roger Gustavsson Nov 07 '19 at 13:33
  • @RogerGustavsson Same, I was thinking another poor soul was trying to come up with some RegEx but no he already has the efficient solution and is asking us based on the still unsupported claim that this solution is somehow bad practice. – yur Nov 07 '19 at 13:36
  • Item 57: Use exceptions only for exceptional conditions. The fact that the format is wrong or the specified string do not represent a date is not something exceptional. I will simply do not process the date from that specific row. There is no reason to throw an exception for that. I,however, use the exception instead of many if then conditions. That's my understanding of the item.Note that i am an undergraduate student with no experience,so i do not now if my opinions are valid. – Kostas Thanasis Nov 07 '19 at 13:38
  • 2
    Opininions are always valid and I'm not much more experienced! Item 57? What is this Item you're talking about? I think you're thinking a bit too far on this one. This is just how data type testing is done in java, it is the most efficient way, it reads cleanly and it doesn't impact performance, what more could you want? As @Kayaman said, if there was a native ```isDate(String string)``` method, this would be how the code for it would look like. – yur Nov 07 '19 at 13:41
  • I think "Item 57" may refer to the case when you allow exceptions to bubble up in the call hierarchy. Only do that for exceptional conditions. It's perfectly ok to use exceptions as done in this case. – Roger Gustavsson Nov 07 '19 at 13:42
  • 3
    @Kostas Thanasis - you are not throwing an exception here, you are catching the one that is thrown by parsing method. So you are not violating Item 57. If you were to throw a new exception or re-throw the one, you caught then you'd be in violation of the said principle – Michael Gantman Nov 07 '19 at 13:43
  • 1
    Yes, [exceptions for control flow is an anti-pattern](https://softwareengineering.stackexchange.com/questions/189222/are-exceptions-as-control-flow-considered-a-serious-antipattern-if-so-why). However I certainly consider this the exception (sorry) where it’s OK. It’s the way that the library offers, and for good reasons since we often need a message about why some format is invalid, an exception message is fine for that. And your `try` statement is short and easy to read. I too would do it that way. – Ole V.V. Nov 07 '19 at 15:30

2 Answers2

4

There's nothing wrong with the code in question. It's clear and readable, and there's no obvious performance problems (sure you can cache the DateTimeFormatter if you want, but that won't make a difference). Exceptions don't cause a significant performance hit either, as yur mentioned.

This is not a case of control flow by exceptions. The only way you can know if it's a date is by parsing it. The parser will throw an exception if it's not. There is no LocalDate.tryParse(), but if there were, it would look like the code in the question.

This is a case of "I heard/I was under the assumption" and while some things have been a real issue in the past (e.g. slow synchronization), usually they're based on outdated Java versions from over 10 years ago or an issue is understood in the wrong way (e.g. exceptions / control flow).

Kayaman
  • 72,141
  • 5
  • 83
  • 121
0

I had a very interesting task once - to check if any string represents a date in any format. I came up with an interesting idea. in the nutshell, it is to hold the list of all Date formats that you wish to support as an external property and then check your string against each format one by one. But there is more to it. For instance order of the formats matter. I wrote an article on this issue. Here is the link to it: Java 8 Java. Time Package: Parsing Any String to Date

Michael Gantman
  • 7,315
  • 2
  • 19
  • 36
  • 2
    The format is known here so why go through all that trouble? – Joakim Danielson Nov 07 '19 at 13:30
  • 1
    I provided a very general solution. It may be an overkill – Michael Gantman Nov 07 '19 at 13:32
  • If you're in the exceptional situation where you need to support unknown number of different formats, you really need a custom tailored solution that's heavily data dependent. – Kayaman Nov 07 '19 at 13:33
  • @JoakimDanielson Eh, it kind of is. The question "Is there an efficient way to check if a String represents A date?" may very well be understood as "if a String represents any date". Might've been better as a comment though but it's not entirely off-topic. – yur Nov 07 '19 at 13:37
  • 1
    @Joakim Danielson, while I understand why you think that this is not an answer, I disagree. Since you can implement this solution with a single format in the format list and if OP requirements change to support more then one format it will be easily etandable without changing the code. So I stand by my answer. Also, as for the use of Exception in OP code, in this case it is valid and acceptable – Michael Gantman Nov 07 '19 at 13:39
  • 1
    I agree, I read the text which was more focused on the use of try/catch and didn't read the title carefully enough. So the issue is more with inconsistency in OP's question than this answer. I remove my comment. – Joakim Danielson Nov 07 '19 at 13:41