Maturity of dates

Asked

Viewed 633 times

0

I have this code that validates the dates of a card and puts in the table:

@SuppressWarnings("nls")
public static ObservableList<String> getPagaVenci1(TableView<PersonC> jtc, String sq4, int l) throws Exception{
    Label le = new Label(sq4);
    String g = le.getText();
    ObservableList<String> data = FXCollections.observableArrayList();

    Date datavs = new Date();
    DateFormat f = DateFormat.getDateInstance();
    f = DateFormat.getDateInstance();
    System.out.println(f.format(datavs));
    String datat = f.format(datavs);
    String datav = datat;
    String dataFormat = g;

    int dasf;
    int dasv;
    String dataF = (String) dataFormat.subSequence(0,10);
    int len = sq4.length();
    int lo = l;

    while(lo != 0){
        switch(len){
            case 22:
                String dataF1 = (String) dataFormat.subSequence(12,22);
                if(len == 22){
                    System.out.println("22");
                    dasf = Integer.parseInt(dataF.replace("/", "").toString());
                    dasv = Integer.parseInt(datav.replace("/", "").toString());
                    String sd7 = "";
                    String sd8 = "";
                    if(dasf <= dasv){
                        sd7 = dataF;
                        System.out.println(sq4);
                        System.out.println("Encontrou o true.");
                    }
                    dasf = Integer.parseInt(dataF1.replace("/", "").toString());
                    if(dasf <= dasv){
                        sd8 = dataF1;
                        System.out.println(sq4);
                        System.out.println("Encontrou o true.");    
                    }
                    String[] sdarr3 = {sd7,sd8};
                    System.out.println(sdarr3);
                    data.addAll(sdarr3);
                }
            case 34:
                String dataF11 = (String) dataFormat.subSequence(12,22);
                String dataF2 = (String) dataFormat.subSequence(24,34);
                if(sq4.length() == 34){
                    System.out.println("34");
                    dasf = Integer.parseInt(dataF.replace("/", "").toString());
                    dasv = Integer.parseInt(datav.replace("/", "").toString());
                    String sd4 = "";
                    String sd5 = "";
                    String sd6 = "";
                    if(dasf <= dasv){
                        sd4 = dataF; 
                        System.out.println(sq4);
                        System.out.println("Encontrou o true.");
                    }
                    dasf = Integer.parseInt(dataF11.replace("/", "").toString());
                    if(dasf <= dasv){
                        sd5 = dataF11; 
                        System.out.println(sq4);
                        System.out.println("Encontrou o true.");    
                    }
                    dasf = Integer.parseInt(dataF2.replace("/", "").toString());
                    if(dasf <= dasv){
                        sd6 = dataF2; 
                        System.out.println(sq4);
                        System.out.println("Encontrou o true.");    
                    }
                    String[] sdarry2 = {sd4,sd5,sd6}; 
                    System.out.println(sdarry2);
                    data.addAll(sdarry2);
                }
            case 42:
                String dataF111 = (String) dataFormat.subSequence(12,22);
                String dataF22 = (String) dataFormat.subSequence(24,34);
                if(sq4.length() == 42){
                    System.out.println("42");
                    dasf = Integer.parseInt(dataF.replace("/", "").toString());
                    dasv = Integer.parseInt(datav.replace("/", "").toString());
                    String sd = "";
                    String sd1 = "";
                    String sd2 = "";
                    String sd3 = "";
                    if(dasf <= dasv){
                        sd = dataF;
                        System.out.println(sq4);
                        System.out.println("Encontrou o true.");
                    }
                    dasf = Integer.parseInt(dataF111.replace("/", "").toString());
                    if(dasf <= dasv){
                        sd1 = dataF111;
                        System.out.println(sq4);
                        System.out.println("Encontrou o true.");    
                    }
                    dasf = Integer.parseInt(dataF22.replace("/", "").toString());
                    if(dasf <= dasv){
                        sd2 = dataF22;
                        System.out.println(sq4);
                        System.out.println("Encontrou o true.");    
                    }
                    String dataF3 = (String) dataFormat.subSequence(34,42);
                    dasf = Integer.parseInt(dataF3.replace("/", "").toString());
                    if(dasf <= dasv){
                        sd3 = dataF3;
                        System.out.println(sq4);
                        System.out.println("Encontrou o true.");    
                    }
                    String[] sdarry = {sd,sd1,sd2,sd3};
                    System.out.println(sdarry);
                    data.addAll(sdarry);    
                }
            lo = 0;
        }
    }
    System.out.println(data);
    return data;
}

I’m trying to slow it down. And there’s nothing on the table either.

What I do?


Code of Table Rows:

    static ObservableList<Person> data = FXCollections.observableArrayList();

public static ObservableList<Person> SCs() {
    String sql = "SELECT NOME,DIVIDA,PAGAMENTO,DATADV FROM CLIENTES";
    String url = "Jdbc:oracle:thin:@localhost:1521:xe";
    try(Connection con = DriverManager.getConnection(url, "system", "AL0921069LUCASJL");
            PreparedStatement stm = con.prepareStatement(sql);
            ResultSet rs = stm.executeQuery()){
        int linha = 0;
        while(rs.next()){
            linha ++;
            int l = linha;
            System.out.println(l);
            String sq1 = rs.getString("NOME");
            String sq2 = rs.getString("DIVIDA");
            String sq3 = rs.getString("PAGAMENTO");
            String sq4 = rs.getString("DATADV");

            data.addAll(new Person(sq1,sq2,sq3,Person.getPagaVenci(jtc,sq4,l)));

        }
    }catch(Exception es){
        es.printStackTrace();
        System.out.println("OK!");
        SI.createExceptionDialog(es, "Erro Inesperado. \n"+ "Informe ao Fornecedor. \n"+ "Erro 5.");
    }
    return data;
}
  • Where and how do you call this function? What can come in the parameters sq4 and l?

  • I updated the question.

  • Okay, I’m already trying to work out an answer.

  • Which strings exactly exist within the column DATADV? I ask this because I’m thinking there’s something wrong with the sizes you pass to the subSequence.

1 answer

1


Your code has a lot of problems:

  1. You did not provide the class PersonC of the parameter jtc (I’m supposed to be a subclass of Person), but since you don’t seem to be using this parameter for anything, we can simply delete it.

  2. The throws Exception is unnecessary, and can be removed.

  3. The second line of this section is useless:

    DateFormat f = DateFormat.getDateInstance();
    f = DateFormat.getDateInstance();
    

    So that would be all:

    DateFormat f = DateFormat.getDateInstance();
    
  4. In this passage:

    String datat = f.format(datavs);
    String datav = datat;
    

    The variable datat is never used again, so can be eliminated:

    String datav = f.format(datavs);
    
  5. In these variables:

    public static ObservableList<String> getPagaVenci1(String sq4, int l) {
        Label le = new Label(sq4);
        String g = le.getText();
        // ...
        String dataFormat = g;
    

    It seems to me that the label is useless, and that both g how much dataFormat shall always be equal to sq4.

  6. The occurrences of subSequence may be replaced by substring eliminated the cast.

  7. In the parts dataF.replace("/", "").toString(), the toString() is totally unnecessary and can be eliminated.

  8. The use of DateFormat.getDateInstance(); makes the behavior of your program depend on the Locale default. This can interfere with how you compare dates.

  9. Variable names could be better!

But the worst part of the code is switch within the while:

    int len = sq4.length();
    int lo = l;

    while(lo != 0){
        switch(len){
            case 22:
                String dataF1 = (String) dataFormat.subSequence(12,22);
                if(len == 22){
                    // Bloco 1 com várias instruções.
                }
            case 34:
                String dataF11 = (String) dataFormat.subSequence(12,22);
                String dataF2 = (String) dataFormat.subSequence(24,34);
                if(sq4.length() == 34){
                    // Bloco 2 com várias instruções.
                }
            case 42:
                String dataF111 = (String) dataFormat.subSequence(12,22);
                String dataF22 = (String) dataFormat.subSequence(24,34);
                if(sq4.length() == 42){
                    // Bloco 3 com várias instruções.
                }
            lo = 0;
        }
    }

In this part:

  1. The noose while is completely useless. The lo = 0; at the end makes it perform at most once. The fact of the parameter l be the line number and start with 1, make the loop always run at least once. And if it runs at least once and at most once, then it runs exactly once always, and therefore is totally unnecessary.

  2. When deleting the loop, the variable lo also becomes unnecessary and can be eliminated.

  3. When deleting the variable lo, the parameter l also becomes unnecessary.

  4. The variables dataF1, dataF11 and dataF111 are the same things, but declared in different places. The same occurs for dataF2 and dataF22.

  5. The ifare unnecessary if instead of fallthrough, one break; used in an appropriate manner.

  6. If the size of sq4 is neither 22, nor 34, nor 42, the code goes into loop infinite!

  7. If the String sq4 has as content things that are not dates in the correct format, the result can be either a nonsense list being shown as a result, or a NumberFormatException being released.

  8. The while and the switch are constructions of language very inadequate for this circumstance and the fact that they have been very badly employed and on top of that in a circumstance where they should not even be employed, demonstrates that whoever did this simply did not know what he was doing, which is reinforced by the use of variables that should not be related to the logic used (the line number) and by the redundant and repetitive use of multiple distinct variables with equal meanings. Apparently the reason this lame gambit was made this way is to try to avoid a StringIndexOutOfBoundsException when executing the subSequence when the String is too small.

With all of this, I come to the conclusion that it is best to redo the entire method from scratch. So let’s analyze the code try to actually do:

  1. Initially it stings the String sq4 in 4 parts: 0 to 9, 12 to 21, 24 to 33 and 34 to 41. The characters in headings 10, 11, 22 and 23 are ignored. The first three Stringresulting s each have 10 characters, if any. The latter has 8.

  2. If the String sq4 is too short, the surplus parts simply do not exist.

  3. Each piece that exists represents a date that is compared to the current date. The comparison is made by removing the bars, converting to number and checking which one is the largest. If the String representing the date is in the past or present, it is added to the list. If you’re in the future, a String empty is added to the list. If not, nothing is added to the list.

To redo your code I’ll assume the following:

  1. I will consider that the fact of a String empty can be added to the list is a bug and this should never happen.

  2. I will consider the positions and size of the pieces in String are correct, but if they are not, you will have no difficulty changing.

  3. I will consider that the procedure of removing the bars and converting to numbers has the purpose of knowing which date precedes or succeeds another.

  4. I’ll assume that case to String does not have a valid size and format, it is best to throw an exception.

  5. I’m going to assume that the date format should always be yyyy/MM/dd. But if it is not, you can change it easily. It should always be the same format that is used in the database.

  6. I think the fact that the last part of String size 8 is a serious bug in your code, 'cause it’s not gonna work out this size unless for some reason, this part of String don’t have the bars or the year has only two digits. But I’ll keep it that way because this is something that so far only you can fix because only you know, so far, how information is stored in your database. If her size was 10, String It would have to be a size four. It may also be that the positions chosen - 0, 12, 24 and 34 - are wrong, and perhaps the correct ones would be 0, 11, 22 and 33, which would make more sense, but the String would have to be size 43 in this case. Anyway, this is easy to change in the following code.

Here is the resulting code:

    private static void adicionarData(SimpleDateFormat f, String dataDvStr, int comeco, int tamanho, Date agora, List<String> destino) {
        if (dataDvStr.length() < comeco + tamanho) return;
        String data = dataDvStr.substring(comeco, comeco + tamanho);
        try {
            if (!f.parse(data).after(agora)) destino.add(data);
        } catch (ParseException ex) {
            throw new IllegalArgumentException("Data inválida.", ex);
        }
    }

    public static ObservableList<String> getPagaVenci1(String dataDvStr) {
        ObservableList<String> resultado = FXCollections.observableArrayList();

        Date agora = new Date();
        SimpleDateFormat f = new SimpleDateFormat("yyyy/MM/dd");

        int len = dataDvStr.length();
        if (len != 22 && len != 34 && len != 42) throw new IllegalArgumentException("Tamanho inválido.");

        adicionarData(f, dataDvStr,  0, 10, agora, resultado);
        adicionarData(f, dataDvStr, 12, 10, agora, resultado);
        adicionarData(f, dataDvStr, 24, 10, agora, resultado);
        adicionarData(f, dataDvStr, 34,  8, agora, resultado); // 8!? WTF? Isso daqui só pode estar errado!
        return resultado;
    }

If the last String in fact has size 8, unlike the other three, but use a different date format, then you should instantiate one more SimpleDateFormat with the appropriate format and pass it to this last call. Assuming the format of the last date is yyyyMMdd, would look like this:

    public static ObservableList<String> getPagaVenci1(String dataDvStr) {
        ObservableList<String> resultado = FXCollections.observableArrayList();

        Date agora = new Date();
        SimpleDateFormat f = new SimpleDateFormat("yyyy/MM/dd");
        SimpleDateFormat f2 = new SimpleDateFormat("yyyyMMdd");

        int len = dataDvStr.length();
        if (len != 22 && len != 34 && len != 42) throw new IllegalArgumentException("Tamanho inválido.");

        adicionarData(f, dataDvStr,  0, 10, agora, resultado);
        adicionarData(f, dataDvStr, 12, 10, agora, resultado);
        adicionarData(f, dataDvStr, 24, 10, agora, resultado);
        adicionarData(f2, dataDvStr, 34,  8, agora, resultado); // Usa um SimpleDateFormat especial aqui!
        return resultado;
    }

Again, if the dates have different formats, you should use a SimpleDateFormat for each distinct format.


Finally, we still have your method SCs. In it I have few changes to make:

  1. The method getPagaVenci (or getPagaVenci1) had the parameters changed.

  2. It is not good practice to keep a changeable list in a global variable. Let’s make the method return a new list instead of returning the global variable.

  3. No sense having two variables l and linha that represent exactly the same thing.

  4. The name of some variables could be better.

So your method SCs gets like this:

    public static ObservableList<Person> SCs() {
        ObservableList<Person> data = FXCollections.observableArrayList();

        String sql = "SELECT NOME,DIVIDA,PAGAMENTO,DATADV FROM CLIENTES";
        String url = "Jdbc:oracle:thin:@localhost:1521:xe";
        try (Connection con = DriverManager.getConnection(url, "system", "AL0921069LUCASJL");
                PreparedStatement stm = con.prepareStatement(sql);
                ResultSet rs = stm.executeQuery()) {
            int linha = 0;
            while (rs.next()) {
                linha++;
                System.out.println(linha);
                String nome = rs.getString("NOME");
                String divida = rs.getString("DIVIDA");
                String pagamento = rs.getString("PAGAMENTO");
                String dataDv = rs.getString("DATADV");

                data.addAll(new Person(nome, divida, pagamento, Person.getPagaVenci(dataDv)));
            }
        } catch (Exception es) {
            es.printStackTrace();
            System.out.println("OK!");
            SI.createExceptionDialog(es, "Erro Inesperado. \nInforme ao Fornecedor. \nErro 5.");
        }
        return data;
    }

Or perhaps the purpose of this method SCs is to update the list data? If that’s the case, I’d be better off:

    private ObservableList<Person> data = FXCollections.observableArrayList();

    public void SCs() {
        data.clear();
        String sql = "SELECT NOME,DIVIDA,PAGAMENTO,DATADV FROM CLIENTES";
        String url = "Jdbc:oracle:thin:@localhost:1521:xe";
        try (Connection con = DriverManager.getConnection(url, "system", "AL0921069LUCASJL");
                PreparedStatement stm = con.prepareStatement(sql);
                ResultSet rs = stm.executeQuery()) {
            int linha = 0;
            while (rs.next()) {
                linha++;
                System.out.println(linha);
                String nome = rs.getString("NOME");
                String divida = rs.getString("DIVIDA");
                String pagamento = rs.getString("PAGAMENTO");
                String dataDv = rs.getString("DATADV");

                data.addAll(new Person(nome, divida, pagamento, Person.getPagaVenci(dataDv)));
            }
        } catch (Exception es) {
            es.printStackTrace();
            System.out.println("OK!");
            SI.createExceptionDialog(es, "Erro Inesperado. \nInforme ao Fornecedor. \nErro 5.");
        }
    }

Also note the following:

  • In this last bit of code, I took the static. This eliminates the use of global variables and many problems associated with them. You will then work with instances of your DAO class.

  • You can move things like the database URL, username, and password to your DAO fields, avoiding having to repeat them in every method that accesses the database. It also gives you the possibility to change them easily if necessary.

  • It’s not good practice for programming to mix visualization logic (Javafx) with database access logic, and that’s exactly what you’re doing in your method SCs. The ideal would be for you to use ArrayList instead of ObservableList in its database logic and model class (Person). And add the elements to a ObservableList out of your DAO.

  • In order to avoid mixing visualization logic with data access logic when handling exceptions, exceptions occurring in the DAO should be thrown out of the method (using throw) and captured in the layer above to then be displayed to the user or treated.

  • The fact that you are placing four dates in the same field in the database is a violation of normal first form. As a result, searching or changing values within this field becomes very difficult and laborious. The ideal is to normalize it from there with a relationship 1-to-N.

  • Let us agree that SCs and getPagaVenci1 are not good names for methods!

  • Thank you for taking all this trouble to fix this code, sorry for not explaining and also for you having done everything from scratch.

  • @lucasdaniel All right. I’m grateful to have helped.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.