Pagina 1 di 3 1 2 3 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 24

Hybrid View

  1. #1
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284

    [JAVA 8] Differenza tra 2 LocalDate fornisce Period inaspettato

    Stavo provando la nuova Date-Time API di Java 8. Ho scritto questo per vedere la differenza come Period tra due LocalDate:

    codice:
    import java.time.*;
    
    public class LocalDateDiff {
        public static void main(String[] args) {
            printDiff(LocalDate.of(2012, 12,  1), LocalDate.of(2014, 2, 1));
            printDiff(LocalDate.of(2012, 11, 30), LocalDate.of(2014, 2, 1));
        }
    
        private static void printDiff(LocalDate d1, LocalDate d2) {
            Period p = Period.between(d1, d2);
    
            System.out.format("[%s , %s) = %d year(s), %d month(s), %d day(s)%n",
                    d1, d2, p.getYears(), p.getMonths(), p.getDays());
        }
    }

    A me stampa:

    [2012-12-01 , 2014-02-01) = 1 year(s), 2 month(s), 0 day(s)
    [2012-11-30 , 2014-02-01) = 1 year(s), 2 month(s), 2 day(s)


    Se scalo indietro di 1 giorno solo d1, mi aspetterei che il Period aumenti di 1 giorno .... non di 2.
    Mi sfugge qualcosa? A voi sembra corretto? (LeleFT, Alex'87: sapete qualcosa più di me della Date-Time API?)
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  2. #2
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,328
    Non ho a disposizione Java 8 (sono fermo a Java 6), per cui non posso dire nulla. Farei dei test per vedere se, in qualche modo che non è documentato, LocalDate o Period.between() tengono in considerazione le informazioni su ore/minuti/secondi... che potrebbero causare errori di arrotondamento.


    PS: non so voi, ma a me lo stile della documentazione che è stato introdotto da Java 7 fa orrore, ribrezzo e desolazione. E' 100 volte meno pulita e leggibile delle precedenti.


    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  3. #3
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Quote Originariamente inviata da LeleFT Visualizza il messaggio
    Ni... partendo dal 30/11/2012 aggiungi 1 anno.
    Arrivi al 30/11/2013. Aggiungi 2 mesi (MESI!!), arrivi al 30 gennaio 2014 (sempre per l'annoso problema dell'aggiunta di 1 mese alla data di fine di un mese di 30 giorni....) e mancano ancora 2 giorni per arrivare al 1 febbraio.
    Rispondo solo adesso perché non ho potuto prima. Comunque sì ... è proprio questo che mi "sfuggiva"!! Ora mi è chiaro il ragionamento che fa la API. Ero condizionato dal "mio" ragionamento (conta gli anni completi, conta i mesi completi, conta i giorni sfusi che rimangono) che magari non è neanche sbagliatissimo in senso generale ma evidentemente non è quello che fa la API.

    Grazie LeleFT.

    Quote Originariamente inviata da LeleFT Visualizza il messaggio
    PS: non so voi, ma a me lo stile della documentazione che è stato introdotto da Java 7 fa orrore, ribrezzo e desolazione. E' 100 volte meno pulita e leggibile delle precedenti.
    Hanno aggiunto un po' di colore, cambiato stili dei caratteri, ecc... ma le informazioni sono comunque sempre le stesse (se non aggiornate/migliorate addirittura). Secondo me è solo questione di abitudine. Anche io quando ho iniziato a leggere il javadoc di Java 7/8 ho avuto un po' di "smarrimento" iniziale ma adesso mi ci sto (pian piano) abituando.

    E comunque la documentazione di Java è tra le migliori come forma e completezza. Se vuoi vedere qualcosa di davvero deprimente, guarda la documentazione di Dojo (un framework Javascript). Ho dovuto lavorare con Dojo per diversi mesi lo scorso anno, la documentazione è davvero orrenda: link "rotti" un po' sparsi, documentazione laconica o del tutto mancante su proprietà/funzioni, un sacco di cose "deprecate" ad ogni nuova versione (molto più di quanto è successo in Java) e altre nefandezze. Sono solo contento di aver ora "dimenticato" Dojo.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  4. #4
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,328
    Quote Originariamente inviata da andbin Visualizza il messaggio
    Hanno aggiunto un po' di colore, cambiato stili dei caratteri, ecc... ma le informazioni sono comunque sempre le stesse (se non aggiornate/migliorate addirittura). Secondo me è solo questione di abitudine. Anche io quando ho iniziato a leggere il javadoc di Java 7/8 ho avuto un po' di "smarrimento" iniziale ma adesso mi ci sto (pian piano) abituando.

    E comunque la documentazione di Java è tra le migliori come forma e completezza. Se vuoi vedere qualcosa di davvero deprimente, guarda la documentazione di Dojo (un framework Javascript). Ho dovuto lavorare con Dojo per diversi mesi lo scorso anno, la documentazione è davvero orrenda: link "rotti" un po' sparsi, documentazione laconica o del tutto mancante su proprietà/funzioni, un sacco di cose "deprecate" ad ogni nuova versione (molto più di quanto è successo in Java) e altre nefandezze. Sono solo contento di aver ora "dimenticato" Dojo.

    Sì, mi riferivo solamente all'estetica (stile) della documentazione, non al contenuto, che reputo sempre di ottima qualità.
    Secondo me si è perso molto in leggibilità: c'è troppa poca differenza di colore tra i nomi dei metodi e la descrizione; il fatto di avere il tipo di ritorno allineato a sinistra (prima era allineato a destra) è disorientante; non ci sono più i bordi della tabella dei metodi (hanno preferito usare la colorazione alternata della cosiddetta "lettura facilitata" e ci può stare); manca il rientro nella descrizione del metodo (cosa che, aggiunta alla poca differenza di colore col nome del metodo, rende ancora più difficile la ricerca del metodo); prima i link erano "differenziati": i nomi dei metodi e dei costruttori erano in grassetto, mentre i parametri (laddove rappresentati da classi, quindi link alla relativa documentazione) erano in plain. Ora tutto è in grassetto e, di conseguenza, appesantito. Boh... non che la documentazione Android sia migliore, ma almeno hanno mantenuto un po' di quello che era convenzionale in Java.


    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  5. #5
    Utente di HTML.it L'avatar di luca200
    Registrato dal
    Apr 2002
    Messaggi
    4,120
    Non ho mai usato Java 8 e non conosco le specifiche di questo Period, ma esaminando le date non è che il risultato possa definirsi sbagliato.
    Se fai 30 novembre + 2 mesi arrivi al 30 gennaio, e da lì al 1° febbraio mancano 2 giorni.
    Il problema di base è che i mesi non hanno tutti la stessa durata, e quindi un periodo espresso in giorni-mesi-anni è sempre approssimato, da un certo punto di vista.

  6. #6
    Utente di HTML.it
    Registrato dal
    Feb 2007
    Messaggi
    4,157
    Quote Originariamente inviata da luca200 Visualizza il messaggio
    Non ho mai usato Java 8 e non conosco le specifiche di questo Period, ma esaminando le date non è che il risultato possa definirsi sbagliato.
    Se fai 30 novembre + 2 mesi arrivi al 30 gennaio, e da lì al 1° febbraio mancano 2 giorni.
    Il problema di base è che i mesi non hanno tutti la stessa durata, e quindi un periodo espresso in giorni-mesi-anni è sempre approssimato, da un certo punto di vista.
    l'end date non è inclusa, quindi al 1 febbraio manca 1 giorno
    RTFM Read That F*** Manual!!!

  7. #7
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Quote Originariamente inviata da luca200 Visualizza il messaggio
    Se fai 30 novembre + 2 mesi arrivi al 30 gennaio, e da lì al 1° febbraio mancano 2 giorni.
    Nel between la seconda data è esclusa, lo chiarisce bene il javadoc:

    between(LocalDate startDateInclusive, LocalDate endDateExclusive)

    Il primo caso [2012-12-01 , 2014-02-01) lo ritengo sensato e giusto: c'è tutto il 2013 in mezzo = 1 anno. C'è tutto il Gennaio 2014 (1 Febbraio escluso appunto) + tutto Dicembre 2012 = 2 mesi. E 0 altri giorni.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  8. #8
    Utente di HTML.it L'avatar di luca200
    Registrato dal
    Apr 2002
    Messaggi
    4,120
    Quote Originariamente inviata da valia Visualizza il messaggio
    l'end date non è inclusa, quindi al 1 febbraio manca 1 giorno
    Quote Originariamente inviata da andbin Visualizza il messaggio
    Nel between la seconda data è esclusa, lo chiarisce bene il javadoc:
    Se non sapete fare i calcoli evitate di scrivere a sproposito.
    La seconda data è esclusa, ma la prima è inclusa, quindi non cambia niente. Si tratta sempre di una differenza fra date. Fra il 30 gennaio e il 1° febbraio la differenza è due giorni.

  9. #9
    Utente di HTML.it
    Registrato dal
    Feb 2007
    Messaggi
    4,157
    Quote Originariamente inviata da luca200 Visualizza il messaggio
    Se non sapete fare i calcoli evitate di scrivere a sproposito.
    La seconda data è esclusa, ma la prima è inclusa, quindi non cambia niente. Si tratta sempre di una differenza fra date. Fra il 30 gennaio e il 1° febbraio la differenza è due giorni.
    ok, supponiamo che è come dici tu.
    Se dal 1 gennaio al 1 febbraio è un mese esatto, mi aspetto che dal 31 dicembre al 1 gennaio sia un mese e 1 giorno (e i conti tornano).

    Ma se conto 1 maggio 1 febbraio, mi aspetto 9 mesi. 30 aprile 1 febbraio mi aspetto 9 mesi e 1 giorno (visto che parto dal giorno prima). Se il mese è di 31 nessun problema, se è di 30 si

    [2014-05-01 , 2015-02-01) = 0 year(s), 9 month(s), 0 day(s)
    [2014-04-30 , 2015-02-01) = 0 year(s), 9 month(s), 2 day(s)

    come vedi i conti continuano a non tornare.
    RTFM Read That F*** Manual!!!

  10. #10
    Utente di HTML.it
    Registrato dal
    Feb 2007
    Messaggi
    4,157
    ciao.
    Credo che il problema sia la rimodulazione. Andando a sbirciare il codice

    codice:
    
     @Override
        public Period until(ChronoLocalDate endDateExclusive) {
            LocalDate end = LocalDate.from(endDateExclusive);
            long totalMonths = end.getProlepticMonth() - this.getProlepticMonth();  // safe
            int days = end.day - this.day;
            if (totalMonths > 0 && days < 0) {
                totalMonths--;
                LocalDate calcDate = this.plusMonths(totalMonths);
                days = (int) (end.toEpochDay() - calcDate.toEpochDay());  // safe
            } else if (totalMonths < 0 && days > 0) {
                totalMonths++;
                days -= end.lengthOfMonth();
            }
            long years = totalMonths / 12;  // safe
            int months = (int) (totalMonths % 12);  // safe
            return Period.of(Math.toIntExact(years), months, days);
        }
    questo è il metodo che fa il calcolo.
    Credo che a cannare sia questo punto qui, quello che normalizza

    codice:
     days = (int) (end.toEpochDay() - calcDate.toEpochDay());  // safe
    in particolare il metodo toEpochDay.

    Fatto prova con
    codice:
    printDiff(LocalDate.of(2013, 01, 1), LocalDate.of(2014, 2, 1));
            printDiff(LocalDate.of(2012, 12, 31), LocalDate.of(2014, 2, 1));
    e ho visto

    [2013-01-01 , 2014-02-01) = 1 year(s), 1 month(s), 0 day(s)
    [2012-12-31 , 2014-02-01) = 1 year(s), 1 month(s), 1 day(s)

    dovrei fare prove più serie per dirti altro

    ps se vuoi dare un occhio
    http://grepcode.com/file/repository....noLocalDate%29


    @leleFt
    concordo, preferivo di gran lunga la vecchia interfaccia!!
    Ultima modifica di valia; 03-09-2014 a 10:34
    RTFM Read That F*** Manual!!!

Tag per questa discussione

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2026 vBulletin Solutions, Inc. All rights reserved.