Ricavare un cron da una lista

di il
5 risposte

Ricavare un cron da una lista

Salve a tutti,

mi sono trovato davanti a un problema del genere:
ho una List<String> dates che contiene le stringhe di date in questo formato "yyyy-MM-dd'T’HH:mm:ss"
Okay che devo fare un iter tipo
for (String s : dates)
{
//qui devo fare, non so come
}
Il problema consiste nell'avere una lista e come output produrre un cron : "0 * * * * MON*" oppure "0 0/30 8-10 * * *" in base alle date che ho nella lista, ovviamente se il numero delle date identici sono maggiori di 50%. Non so se mi spiego.

Qualcuno ha avuto a che fare con un compito del genere, qualche dritta anche a livello del codice - per capire l'andamento.

5 Risposte

  • Re: Ricavare un cron da una lista

    arnizibert ha scritto:


    Okay che devo fare un iter tipo
    for (String s : dates)
    {
    //qui devo fare, non so come
    }
    Le date in stringa così, da sole servono a poco/nulla. Va effettuato un parsing di ciascuna stringa al fine di ottenere:
    - un java.util.Date e poi un java.util.Calendar ("vecchia" API)
    oppure
    - un java.time.LocalDateTime (nuova API Java 8+)

    arnizibert ha scritto:


    Il problema consiste nell'avere una lista e come output produrre un cron : "0 * * * * MON*" oppure "0 0/30 8-10 * * *" in base alle date che ho nella lista
    Guarda che, detto molto in generale, "dedurre" l'espressione generalizzata di un cron partendo da una serie di date reali e specifiche, è qualcosa di parecchio complicato e per niente banale ...
    E in base a quante/quali date, potrebbe anche non essere fattibile.

    arnizibert ha scritto:


    ovviamente se il numero delle date identici sono maggiori di 50%.
    Non capisco particolarmente questa parte ..


    Prova a scrivere delle date/ore specifiche e dire che cron dovrebbe dedurre
  • Re: Ricavare un cron da una lista

    Grazie per la risposta...
    Prova a scrivere delle date/ore specifiche e dire che cron dovrebbe dedurre
    Allora provo a dettagliare:
    Ho delle date fatte cosi`:
    "2022-01-24T19:53:00"
    "2022-01-24T19:54:00"
    "2022-01-24T19:55:00"
    "2022-01-22T19:53:00"
    "2022-01-22T19:53:00"
    Con il numero delle date nella lista >50% intendo dire le occorrenze.
    Vedi che ci sono 3 date col 24 gennaio ? Ecco..sono la maggior parte e quindi dovrebbe essere prodotto in output on cron del genere: "0 * * * * MON"
  • Re: Ricavare un cron da una lista

    arnizibert ha scritto:


    Allora provo a dettagliare:
    Ho delle date fatte cosi`:
    "2022-01-24T19:53:00"
    "2022-01-24T19:54:00"
    "2022-01-24T19:55:00"

    Vedi che ci sono 3 date col 24 gennaio ? Ecco..sono la maggior parte e quindi dovrebbe essere prodotto in output on cron del genere: "0 * * * * MON"
    0 * * * * MON vuol dire "ogni minuto (al secondo 00) ma solo al Lunedì". Quindi almeno per quelle 3 date, sì, corrispondono al cron (il 24/01/2022 è un Lunedì).
    Ma questo è tutto sommato un caso semplice. Dovresti ordinare le date (se già non lo sono), verificare che la data è la stessa (facilissimo) e che l'orario da una all'altra varia esattamente di 1 minuto (fattibile).

    Ma prova a pensare a casi un po' più articolati ....
  • Re: Ricavare un cron da una lista

    andbin ha scritto:


    arnizibert ha scritto:


    Allora provo a dettagliare:
    Ho delle date fatte cosi`:
    "2022-01-24T19:53:00"
    "2022-01-24T19:54:00"
    "2022-01-24T19:55:00"

    Vedi che ci sono 3 date col 24 gennaio ? Ecco..sono la maggior parte e quindi dovrebbe essere prodotto in output on cron del genere: "0 * * * * MON"
    0 * * * * MON vuol dire "ogni minuto (al secondo 00) ma solo al Lunedì". Quindi almeno per quelle 3 date, sì, corrispondono al cron (il 24/01/2022 è un Lunedì).
    Ma questo è tutto sommato un caso semplice. Dovresti ordinare le date (se già non lo sono), verificare che la data è la stessa (facilissimo) e che l'orario da una all'altra varia esattamente di 1 minuto (fattibile).

    Ma prova a pensare a casi un po' più articolati ....

    Grazie per la risposta, sempre il TOP.
            if (freqMap != null && freqMap.get(monthList.get(index - 1)) == sortedDates.size()
                    || freqMap != null && (freqMap.get(monthList.get(index - 1)) * 100 / sortedDates.size()) > 50) {
                System.out.println(monthList.get(index - 1).substring(0, 3));
            }
    Ci sono arrivano a fare una cosa del genere. Tipo sono arrivano all'ultimo indice:
    vado a vedere quante volte il valore di quell'indice si riscontra, se e` riscontrato piu del 50% allora ci faccio qualcosa.

    Ma a livello di Java Stream c'era la possibilita` di farla piu` breve? Non so se mi spiego

    ====================UPD====================
    Ci sono arrivato ed il cron e` generato correttamente.
    Pero` come faccio a controllare se il cron che ho generato soddisfi le date su una lista?
    Tipo ho questa cron:
    0 * 19 24 JAN MON e devo vedere se si trovano delle date che soddisfanno la cron:
    E date sono queste:
            dates.add("2022-01-24T19:53:30");
            dates.add("2022-01-24T20:02:30");
            dates.add("2022-01-24T19:54:30");
            dates.add("2022-01-24T19:55:30");
            dates.add("2022-01-24T19:56:30");
            dates.add("2022-01-24T19:58:00");
            dates.add("2022-01-24T19:57:00");
            dates.add("2022-01-24T19:59:00");
            dates.add("2022-01-24T20:00:00");
            dates.add("2020-01-24T20:01:00");
            
    ALtra cosa e` validazione, purtroppo non posso usare le librerie di spring e quartz che facciano la cosa per me.
  • Re: Ricavare un cron da una lista

    arnizibert ha scritto:


            if (freqMap != null && freqMap.get(monthList.get(index - 1)) == sortedDates.size()
                    || freqMap != null && (freqMap.get(monthList.get(index - 1)) * 100 / sortedDates.size()) > 50) {
                System.out.println(monthList.get(index - 1).substring(0, 3));
            }
    Ci sono arrivano a fare una cosa del genere. Tipo sono arrivano all'ultimo indice:
    vado a vedere quante volte il valore di quell'indice si riscontra, se e` riscontrato piu del 50% allora ci faccio qualcosa.

    Ma a livello di Java Stream c'era la possibilita` di farla piu` breve? Non so se mi spiego
    Innanzitutto le date NON le devi trattare solo come stringhe, va fatto un parsing per ottenere un Calendar o (meglio) LocalDateTime. Da questi puoi accedere a ore, minuti, ecc... in maniera corretta, senza fare substring o altro di poco "pulito".

    E comunque ribadisco che fare una logica che possa trattare un po' tutte le casistiche in generale, è abbastanza difficile. Ecco un caso emblematico:

    2022-01-24T19:53:05
    2022-01-24T19:53:25
    2022-01-24T19:54:05
    2022-01-24T19:54:25

    Qui la distanza tra i secondi sui minuti non è regolare, quindi non lo puoi modellare come es. ripetizione ogni tot secondi. Però si può osservare la correlazione che c'è tra i due 05 e i due 25. Che è meno facile ...
    2022-01-24T19:53:05 <---+
                            |
    2022-01-24T19:53:25 <-------+
                            |   |
    2022-01-24T19:54:05 <---+   |
                                |
    2022-01-24T19:54:25 <-------+
    Quindi lo si può rappresentare con: 5,25 53,54 19 24 JAN ? 2022

    E questo è ancora un caso basilare ...

    arnizibert ha scritto:


    Pero` come faccio a controllare se il cron che ho generato soddisfi le date su una lista?
    Tipo ho questa cron:
    0 * 19 24 JAN MON e devo vedere se si trovano delle date che soddisfanno la cron:
    Questa è una parte concettualmente più facile. Ma per farla bene sarebbe buona cosa avere una classe es. CronExpression che "modella" l'espressione (non come stringa ma come i vari field già interpretati), possibilmente immutabile. In modo da poterla usare così:
    CronExpression expr1 = CronExpression.parse("5,25 53,54 19 24 JAN ? 2022");
    
    LocalDateTime dt = LocalDateTime.parse("2022-01-24T19:53:05");
    
    if (expr1.matches(dt)) { ..... }
    A meno di trovare una classe tipo CronExpression già fatta in qualche libreria, farla da zero sarebbe già questo un gran bel "esercizio"
Devi accedere o registrarti per scrivere nel forum
5 risposte