-2

I am coding with Java a function that checks if a date it's ok or not and want to jump up of the method if some condition is executed. I've read a similar question but hasn't the same trouble as it occurs in general and that's not what I want to ask.

public static void validar(String data) {

        System.out.println (data);

        if (data.indexOf(" ") == -1) {
            System.out.println ("No hi ha separació entre data i temps");
            System.out.println ("Data incorrecta" + "\n");
            return;
        }
        else if (data.indexOf("-") == -1) {
            System.out.println ("La data no conté un guions");
            System.out.println ("Data incorrecta" + "\n");
            return;
        }
        else if (data.indexOf(":") == -1) {
            System.out.println ("El temps de la data no conté :'s");
            System.out.println ("Data incorrecta" + "\n");
            return;
        }

        ...

It all works when done like this it:

2023-01-17 17:05:26
Data correcta

2023-01-1717:05:26
No hi ha separació entre data i temps
Data incorrecta

2023/01-17 17.05.26
El temps de la data no conté :'s
Data incorrecta

2023-01-17 17.05.26
El temps de la data no conté :'s
Data incorrecta

Have other conditions to check related to the date (if the date's length is 3 and the same for the time and much more) so I've created some array.

If I create them in the middle of the conditions like:

if (data.indexOf(" ") == -1) {
            System.out.println ("No hi ha separació entre data i temps");
            System.out.println ("Data incorrecta" + "\n");
            return;
        }
        else if (data.indexOf("-") == -1) {
            System.out.println ("La data no conté un guions");
            System.out.println ("Data incorrecta" + "\n");
            return;
        }
        else if (data.indexOf(":") == -1) {
            System.out.println ("El temps de la data no conté :'s");
            System.out.println ("Data incorrecta" + "\n");
            return;
        }

        String[] arrDiaHora = data.split(" ");
        String diamesany = arrDiaHora[0];
        String horaminutsegon = arrDiaHora[1];

        String[] arrDiaMesAny = diamesany.split("-");
        String strany = arrDiaMesAny[0];
        String strmes = arrDiaMesAny[1];
        String strdia = arrDiaMesAny[2];

        String[] arrHoraMinutSegon = horaminutsegon.split(":");
        String strhora = arrHoraMinutSegon[0];
        String strminut = arrHoraMinutSegon[1];
        String strsegon = arrHoraMinutSegon[2];

        if (arrDiaHora.length != 2) {
            System.out.println ("No hi ha dos blocs formats per data i temps");
            System.out.println ("Data incorrecta" + "\n");
            return;
        }
        
        ...

Return values after the arrays don't work and get 'return' is unnecessary as the last statement in a 'void' method.

If I create the arrays before checking the conditions, I got an ArrayIndexOutOfBoundsException

Any help ?

Thanks in advance !!

16
  • 5
    return; will always end the method. But it must be reached first. and, indeed, there is no need to have return; as last statement. The only use case for which to add return statements in a void method, is to prevent the following statements to be executed Commented May 11, 2023 at 10:54
  • 2
    When you say: "Return values after the arrays don't work" - this does not make sense. This is a void method. It cannot return a value. Your question is unclear; it is likely that you are confused about a few concepts, which naturally means a bunch of things you state in your own terms in this question aren't understandable. I suggest you edit this question: Show some code (preferably, that compiles on its own), then show the error (exception, or compiler error - whatever the problem is). If no error, show what it outputs and show what you wanted it to output. Commented May 11, 2023 at 11:06
  • 1
    Please use text instead of images. See meta.stackoverflow.com/questions/285551/… for more details on the reason. Commented May 11, 2023 at 11:50
  • 1
    Unless this is an exercise to learn to program data validation, you should use Java library classes from package java.time docs.oracle.com/javase/8/docs/api/java/time/… to work with dates and time. Commented May 11, 2023 at 11:52
  • 2
    You do not need to repeat the same comment 3 times. return; is how you do it. Which you are - that's not the problem. You're not going to get more useful answers unless you do what we ask you to do. Help us help you. Commented May 11, 2023 at 16:11

2 Answers 2

2

The other answer nicely describes better ways to validate dates.

IMHO it fails to address your concern: why does IntelliJ IDEA report "'return' is unnecessary as the last statement in a 'void' method." on some of your return statements?

To explain that, I simplified your example to this:

public static void validar(int n) {
    System.out.println(n);

    if (n == 3) {
        System.out.println("a");
        return;  // Note 1
    } else if (n == 5) {
        System.out.println("b");
        return;  // Note 1
    }

    int x = n * n;

    if (x == 4) {
        System.out.println("c");
        return;  // Note 2
    } else if (x == 16) {
        System.out.println("c");
        return;  // Note 2
    }

}

I've added two notices to the return statements:

Note 1: the return; statements at these places is needed to exit early from the method. Without these return; statements the rest of the method would also execute. Accordingly there is no report from IntelliJ IDEA at these

Note 2: there are no more statements that could possibly be executed after these return; statements. They are therefore unnecessary. They are the last statements in the branches of an if - else if chain and there are no more statements after that chain. That means that execution of the method ends after executing the preceding statement anyway. For these return; statements IntelliJ IDEA reports "'return' is unnecessary as the last statement in a 'void' method.".

Please note that this is an informational message: its intention is to help you write better (cleaner) code. It doesn't mean that your code is faulty (i.e. it doesn't mean your code will not compile or will have bugs in it.)

You can change that simplified code (without changing its observable behaviour) to

public static void validar(int n) {
    System.out.println(n);

    if (n == 3) {
        System.out.println("a");
        return;  // Note 1
    } else if (n == 5) {
        System.out.println("b");
        return;  // Note 1
    }

    int x = n * n;

    if (x == 4) {
        System.out.println("c");
    } else if (x == 16) {
        System.out.println("c");
    }

}

Sign up to request clarification or add additional context in comments.

Comments

0

It looks like you are trying to split a string that contains a date. Possibly something like this. 2023-05-11 12:25:32.

Rather than trying to reinvent the wheel, check out some of these other options.

Option 1: SimpleDateFormat

Why not use SimpleDateFormat to do the job for you? This method has been around since the beginning and does the job pretty well. SimpleDateFormat will attempt to parse the date based on a pattern you define. If it fails to parse, it will throw a checked exception.

public static void validar(String data)
{
  DateFormat format = new SimpleDateFormat("yyyy-MM-dd h:mm:ss");
  try 
  {
    format.parse(data);
  } 
  catch (ParseException e) 
  {
    System.out.println(e.getMessage());
    System.out.println("El format de la data és incorrecte. Comproveu que la data coincideixi amb el format correcte " +
      "de \"AAAA-MM-DD hh:mm:ss\"");
  }
}

This way you don't need to worry about all of the complicated logic. Instead, you try to parse the date, and if your parse fails, then the date fails validation.

Option 2: Simple Regex

If you aren't concerned with the numbers actually corresponding to a valid date, and just that they match the format you expect, than you can accomplish this via simple pattern matching.

  public static void validarRegex(String data)
  {
    Pattern pattern = Pattern.compile("^\\d{4}\\-\\d{2}\\-\\d{2} \\d{2}:\\d{2}:\\d{2}$");
    if (!data.matches(pattern.pattern())) {
      System.out.println(data);
      System.out.println("El format de la data és incorrecte. Comproveu que la data coincideixi amb el format " +
        "correcte " + "de \"AAAA-MM-DD hh:mm:ss\"");
    }
  }

Option 3: DateTimeFormatter

As user Ole V.V. pointed out, you can also use the updated DateTimeFormatter to parse the string as well. A word of warning here. The DateTimeFormatter throws an unchecked exception, so you should be prepared for this behavior. My example below does not catch the exception. You can catch it here, or higher up the chain if you choose.

  public static void validar(String data)
  {
    System.out.println(data);
    LocalDateTime.parse(data, DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss"));
  }

Option 4: Complex Regex

I don't recommend this, because it's nearly impossible to get a good check due to things like leap years. However, if you want to give it a go, there are plenty of examples floating around.

Option 5: String parsing

This is essentially what you are already doing, but a bit more concise.

public static void validate(String data)
{
  System.out.println(data);

  if (isValidDate(data)) {
    String[] arrDiaHora = data.split(" ");
    String diamesany = arrDiaHora[0];
    String horaminutsegon = arrDiaHora[1];

    String[] arrDiaMesAny = diamesany.split("-");
    String strany = arrDiaMesAny[0];
    String strmes = arrDiaMesAny[1];
    String strdia = arrDiaMesAny[2];

    String[] arrHoraMinutSegon = horaminutsegon.split(":");
    String strhora = arrHoraMinutSegon[0];
    String strminut = arrHoraMinutSegon[1];
    String strsegon = arrHoraMinutSegon[2];

    if (arrDiaHora.length != 2) {
      System.out.println("No hi ha dos blocs formats per data i temps");
      System.out.println("Data incorrecta" + "\n");
    }
  }
}

public static boolean isValidDate(String data)
{
  boolean valid = true;
  if (!data.contains(" ")) {
    invalidData("No hi ha separació entre data i temps");
    valid = false;
  }
  else if (!data.contains("-")) {
    invalidData("La data no conté un guions");
    valid = false;
  }
  else if (!data.contains(":")) {
    invalidData("El temps de la data no conté :'s");
    valid = false;
  }
  return valid;
}

public static void invalidData(String message)
{
  System.out.println(message);
  System.out.println("Data incorrecta" + "\n");
}

6 Comments

Please, please don’t teach the young ones to use the long outdated and notoriously troublesome SimpleDateFormat class. At least not as the first option. And not without any reservation. We have so much better in java.time, the modern Java date and time API, and its DateTimeFormatter. I agree not to reinvent the wheel (except if as an exercise). Also your code will not give the validation that the OP’s code will, so is missing the point.
The correct way to validate the string in a real-world program would be like LocalDateTime.parse(data, DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss")).
While I agree that DateTimeFormatter is better in some cases, it throws runtime exceptions when it fails to parse and introduces extra dependencies that may or may not be needed. Since I don't know the purpose of the date he's handing over, I opted to use the formatter that forces the checked exception. I'll update my answer in a bit to address these concerns and provide alternative solutions.
Sorry, I can’t make sense of your objections -- or maybe they were not meant as objections? You must handle the DateTimeParseException from LocalDateTime.parse()in exactly the same way as you handle ParseException in your code. What difference does it make that it’s a subclass of RuntimeException? And since Java 8 java.time is built in and carries no extra dependencies with it.
I was not making objections. Your points were valid. I simply stated that we don't know the use case for this. I had provided one alternative, and now I've provided several. Hopefully this is enough to get @DBG moving in the right direction.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.