Pagina 1 di 3 1 2 3 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 24
  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,317
    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 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.

  4. #4
    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!!!

  5. #5
    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!!!

  6. #6
    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

  7. #7
    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.

  8. #8
    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!!!

  9. #9
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,317
    @luca200: mi sa che non hai capito esattamente quale sia il problema. Il 1° febbraio è fisso su entrambi i calcoli. Quello che cambia è la data di partenza... e cambia di un solo giorno (dal 30 novembre al 1 dicembre dello stesso anno). Quindi non ha senso che i due calcoli portino ad avere 2 giorni di differenza l'uno dall'altro...

    Quindi, se per te è corretto che dal 30 novembre il calcolo porti ad una differenza di due giorni, com'è che dal primo di dicembre (cioè dal giorno dopo) porta ad una differenza di 0 e non di 1?


    Ciao.
    Ultima modifica di LeleFT; 03-09-2014 a 11:53
    "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

  10. #10
    Utente di HTML.it L'avatar di luca200
    Registrato dal
    Apr 2002
    Messaggi
    4,120
    Quote Originariamente inviata da valia Visualizza il messaggio
    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
    Quote Originariamente inviata da LeleFT Visualizza il messaggio
    Quindi, se per te è corretto che dal primo novembre il calcolo porti ad una differenza di due giorni, com'è che dal primo di dicembre (cioè dal giorno dopo) porta ad una differenza di 0 e non di 1?
    Io la risposta ve l'ho data nel primo post

    Quote Originariamente inviata da luca200 Visualizza il messaggio
    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.
    Se non volete capirlo, non so che farci.
    Se volete risultati esatti, calcolate differenze in giorni, non in periodi.

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 © 2025 vBulletin Solutions, Inc. All rights reserved.