2017-04-18 6 views
5

LocalDate moins un Period (comme "28 années, 1 mois et 27 jours"), obtenir un mauvais résultat.LocalDate moins une période obtenir le mauvais résultat

Mais moins un Period (seulement avoir des jours unité, comme "10282" jours) obtenir le bon résultat. Y a-t-il quelque chose à remarquer?

public static void main(String[] args) { 
    printAgeAndBirthday(1989, 2, 22); 

    printBirthdayFromPeriod(28, 1, 27); 
} 
    private static void printBirthdayFromPeriod(int years, int months, int days) { 
    final Period period = Period.of(years, months, days); 
    final LocalDate now = LocalDate.now(); 
    final LocalDate birthday = now.minus(28, ChronoUnit.YEARS) 
      .minus(1, ChronoUnit.MONTHS) 
      .minus(27, ChronoUnit.DAYS); 

    System.out.println("your birthday is : "+ birthday);//1989-02-19 
    System.out.println("your birthday is : "+ now.minusYears(28).minusMonths(1).minusDays(27));//1989-02-19 
    System.out.println("your birthday is : "+ now.minus(period));//1989-02-19 
    System.out.println("your birthday is : "+period.subtractFrom(now));//1989-02-19 
    System.out.println("your birthday is : "+ now.minus(Period.ofDays(10282)));//1989-02-22 
} 

private static void printAgeAndBirthday(int year, int month, int dayOfMonth) { 
    LocalDate today = LocalDate.now(); 
    LocalDate birthday = LocalDate.of(year, month, dayOfMonth); 

    Period p = Period.between(birthday, today); 
    long p2 = ChronoUnit.DAYS.between(birthday, today); 
    System.out.printf("You are %d years, %d months, and %d days old. (%d days total)%n", 
      p.getYears(), p.getMonths(), p.getDays(), p2); 

    LocalDate nextBDay = birthday.withYear(today.getYear()); 

    //If your birthday has occurred this year already, add 1 to the year. 
    if (nextBDay.isBefore(today) || nextBDay.isEqual(today)) { 
     nextBDay = nextBDay.plusYears(1); 
    } 

    Period p_1 = Period.between(today, nextBDay); 
    long p_2 = ChronoUnit.DAYS.between(today, nextBDay); 
    System.out.printf("There are %d months, and %d days until your next birthday. (%d total)%n", 
      p_1.getMonths(), p_1.getDays(), p_2); 
} 

le journal de la console:

You are 28 years, 1 months, and 27 days old. (10282 days total) 
There are 10 months, and 4 days until your next birthday. (310 total) 
your birthday is : 1989-02-19 
your birthday is : 1989-02-19 
your birthday is : 1989-02-19 
your birthday is : 1989-02-19 
your birthday is : 1989-02-22 

version java: jdk1.8.0_45

+4

Ne pas utiliser la période pour faire des calculs exacts. Voir ce poste connexe: http://stackoverflow.com/questions/41945704/adding-and-subtracting-period-from-localdate-doesnt-produce-the-same-date – assylias

+1

Si je soustrais un mois et 27 jours à compter d'aujourd'hui, Je reçois le 19 février. Donc c'est correct. – Holger

Répondre

12

Votre cas peut être simplifié à

LocalDate date1 = LocalDate.of(2017, 2, 22), date2 = LocalDate.of(2017, 4, 18); 
Period p = Period.between(date1, date2); 
System.out.println("date1 + p: "+date1.plus(p)); 
System.out.println("date2 - p: "+date2.minus(p)); 

qui imprimeraEn d'autres termes, le nombre d'années n'est pas pertinent (sauf si l'une des années concernées est une année bissextile et l'autre non, mais ici, les deux ne le sont pas). Ce qui suit illustre le problème:

February      March                      April 
19 20 21 22 23 24 25 26 27 28 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 
↑  │                     ↑                    ↑ 
│  └──────────────────────────── plus one Month ───────────────────────────────────────┴───────────────────────── plus 27 days ─────────────────────────────────────────┤ 
│                    ↑                       ↓ 
└───────────────────────── minus 27 days ────────────────────────────────────────┴─────────────────── minus one month ────────────────────────────────────────────────────────┘ 

Cela changera, si vous changez la direction:

Period p2 = Period.between(date2, date1); 
System.out.println("date1 - p2: "+date1.minus(p2)); 
System.out.println("date2 + p2: "+date2.plus(p2)); 

qui imprimera

date1 - p2: 2017-04-15 
date2 + p2: 2017-02-22 

Ainsi, lorsque vous exprimez une période en termes d'années , mois et jours, la direction devient pertinente. En revanche, le nombre de jours entre plaine deux dates est invariant:

LocalDate date1 = LocalDate.of(2017, 2, 22), date2 = LocalDate.of(2017, 4, 18); 
Period p = Period.ofDays((int)ChronoUnit.DAYS.between(date1, date2)); 
System.out.println("date1 + p: "+date1.plus(p)); 
System.out.println("date2 - p: "+date2.minus(p)); 
date1 + p: 2017-04-18 
date2 - p: 2017-02-22 
+0

merci pour votre réponse sincèrement. Je l'ai . quand je soustrais LocalDate par période, utiliser l'unité de jours sera correct. – ChouChou