如何使用Joda时间libaray计算下一个生日

时间:2016-07-24 13:44:22

标签: java date time android-jodatime

我的格式有两个日期 出生日期假设为1995/04/09,当前日期为2016/07/24 那么我怎样才能让下个生日剩下几个月和几天

public String getNextBirthdayMonths() {
     LocalDate dateOfBirth = new LocalDate(startYear, startMonth, startDay);
     LocalDate currentDate = new LocalDate();

     Period period = new Period(dateOfBirth, currentDate);
     PeriodFormatter periodFormatter = new PeriodFormatterBuilder()
                              .appendMonths().appendSuffix(" Months ")
                              .appendDays().appendSuffix(" Days ")
                              .printZeroNever().toFormatter();

        String nextBirthday = periodFormatter.print(period);
        return "" + nextBirthday;
}

请有人帮我提前谢谢

3 个答案:

答案 0 :(得分:3)

根据您的问题,您想使用Joda计算下一个生日。 以下代码将帮助您提供即将到来的生日月份。

   LocalDate dateOfBirth = new LocalDate(1995, 4, 9);
   LocalDate currentDate = new LocalDate();
   // Take birthDay  and birthMonth  from dateOfBirth 
   int birthDay = dateOfBirth.getDayOfMonth();
   int birthMonth = dateOfBirth.getMonthOfYear();
   // Current year's birthday
   LocalDate currentYearBirthDay = new LocalDate().withDayOfMonth(birthDay)
                        .withMonthOfYear(birthMonth);
   PeriodType monthDay = PeriodType.yearMonthDayTime().withYearsRemoved();
   PeriodFormatter periodFormatter = new PeriodFormatterBuilder()
        .appendMonths().appendSuffix(" Months ").appendDays()
        .appendSuffix(" Days ").printZeroNever().toFormatter();
   if (currentYearBirthDay.isAfter(currentDate)) {
       Period period = new Period(currentDate, currentYearBirthDay,monthDay );
       String currentBirthday = periodFormatter.print(period);
       System.out.println(currentBirthday );
   } else {
        LocalDate nextYearBirthDay =currentYearBirthDay.plusYears(1);
        Period period = new Period(currentDate, nextYearBirthDay ,monthDay );
        String nextBirthday = periodFormatter.print(period);
        System.out.println(nextBirthday);
   }

输出:

  

8个月16天

答案 1 :(得分:1)

我会找到下一个生日日期

LocalDate today = new LocalDate();
LocalDate birthDate = new LocalDate(1900, 7, 12);

int age = new Period(birthDate, today).getYears();

LocalDate nextBirthday = birthDate.plusYears(age + 1);

然后计算它在几个月和几天内到达该日期的时间

PeriodType monthsAndDays = PeriodType.yearMonthDay().withYearsRemoved();
Period leftToBirthday = new Period(today, nextBirthday, monthsAndDays);

PeriodFormatter periodFormatter = new PeriodFormatterBuilder()
        .appendMonths().appendSuffix(" Months ")
        .appendDays().appendSuffix(" Days ")
        .toFormatter();

return periodFormatter.print(leftToBirthday);

答案 2 :(得分:0)

java.time

Joda-Time团队建议迁移到java.time类。

解析

您的输入值接近标准ISO 8601格式。我们可以通过用连字符替换斜杠来转换它。

String input = "1995/04/09".replace ( "/" , "-" );

java.time类默认使用ISO 8601格式来解析和生成表示日期时间值的字符串。因此无需定义格式化模式。 LocalDate类可以直接解析输入。

LocalDate

LocalDate类表示没有时间且没有时区的仅限日期的值。

LocalDate dateOfBirth = LocalDate.parse ( input );

MonthDay

我们所需要的所有重复年度活动,如生日,就是月份和日期。为此,java.time类包括MonthDay

MonthDay monthDayOfBirth = MonthDay.from ( dateOfBirth );

接下来我们需要当前日期。请注意,虽然LocalDate内部没有存储时区,但我们需要一个时区来确定今天的日期。对于任何给定的时刻,日期在时区上随时间变化。例如,午夜过后几分钟是巴黎新的一天,而蒙特利尔仍然是“昨天”。

ZoneId zoneId = ZoneId.of ( "America/Montreal" );
LocalDate today = LocalDate.now ( zoneId );
int year = today.getYear ();

通过当前年份,我们可以通过询问MonthDay实例来创建当年的生日。

LocalDate nextBirthday = monthDayOfBirth.atYear ( year );

确认确定的日期确实是下一个生日。可能已经过去了,在这种情况下我们需要添加一年。

if ( nextBirthday.isBefore ( today ) ) {
    nextBirthday = nextBirthday.plusYears ( 1 );
}

转储到控制台。

System.out.println ( "input: " + input + " | dateOfBirth: " + dateOfBirth + " | today: " + today + " | nextBirthday: " + nextBirthday );
  

输入:1995-04-09 | dateOfBirth:1995-04-09 |今天:2016-07-24 | nextBirthday:2017-04-09

Period

现在我们继续计算到下一个生日的时间。 Period类表示以年,月和日为单位的时间跨度。

 Period period = Period.between ( today ,  nextBirthday ).normalized ();

我们可以查询月份和日期部分。

int months = period.getMonths();
int days = period.getDays();

字符串

至于在字符串中报告这些值,用于数据交换以及可能用于某些人类报告,我建议使用标准ISO 8601格式一段时间与时间线无关:PnYnMnDTnHnMnSP标记开始,T分隔小时 - 分 - 秒部分(如果有)。因此,一个月零六天将是P1M6D

java.time中的PeriodDuration类默认在toString方法中使用此格式。

String output = period.toString();

或创建自己的字符串。

String message = months + " Months " + days + " Days";
System.out.println ( "period: " + period.toString () + " | message: " + message );
  

期间:P8M16D |消息:8个月16天

我希望我知道如何使用DateTimeFormatter自动本地化为Locale指定的人类语言和文化规范,就像我们可以使用其他java.time类型一样。但遗憾的是,PeriodDuration对象似乎无法做到这一点。

TemporalAdjuster

可以将此代码打包到实现TemporalAdjuster的类中。然后,您可以使用简单的with语法。

LocalDate nextBirthday = dateOfBirth.with( MyTemporalAdjusters.nextRecurringMonthDay( myYearMonth ) );

关于java.time

java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.DateCalendar和& SimpleDateFormat

现在位于Joda-Timemaintenance mode项目建议迁移到java.time类。

要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310

从哪里获取java.time类?

ThreeTen-Extra项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如IntervalYearWeekYearQuartermore