首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用Joda time libaray计算下一个生日

如何使用Joda time libaray计算下一个生日
EN

Stack Overflow用户
提问于 2016-07-24 13:44:21
回答 3查看 1.3K关注 0票数 2

我有两个格式的日期,如出生日期,假设1995/04/09和当前日期2016/07/24,那么我如何才能把剩下的几个月和几天留到下一个生日

代码语言:javascript
复制
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;
}

请大家提前帮我谢谢

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-07-24 21:08:04

java.time

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

解析

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

代码语言:javascript
复制
String input = "1995/04/09".replace ( "/" , "-" );

默认情况下,java.time类使用ISO8601格式来解析和生成表示日期时间值的字符串。所以不需要定义格式模式。LocalDate类可以直接解析输入。

LocalDate

LocalDate类表示一个日期纯值,没有一天的时间,也没有时区.

代码语言:javascript
复制
LocalDate dateOfBirth = LocalDate.parse ( input );

MonthDay

我们每年只需要一个月和一个天就可以重复举办生日等年度活动。java.time类包括用于此目的的MonthDay

代码语言:javascript
复制
MonthDay monthDayOfBirth = MonthDay.from ( dateOfBirth );

接下来我们需要现在的日期。注意,虽然LocalDate内部不存储时区,但我们需要时区来确定今天的日期。在任何特定时刻,世界各地的日期都会因时区而异。例如,午夜过后的几分钟,巴黎就迎来了新的一天,而“昨天”仍在蒙托雷。

代码语言:javascript
复制
ZoneId zoneId = ZoneId.of ( "America/Montreal" );
LocalDate today = LocalDate.now ( zoneId );
int year = today.getYear ();

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

代码语言:javascript
复制
LocalDate nextBirthday = monthDayOfBirth.atYear ( year );

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

代码语言:javascript
复制
if ( nextBirthday.isBefore ( today ) ) {
    nextBirthday = nextBirthday.plusYears ( 1 );
}

转储到控制台。

代码语言:javascript
复制
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类以年、月和日表示一段时间。

代码语言:javascript
复制
 Period period = Period.between ( today ,  nextBirthday ).normalized ();

我们可以审问月份部分和白天部分。

代码语言:javascript
复制
int months = period.getMonths();
int days = period.getDays();

字符串

至于在字符串中报告这些值,为了数据交换,可能还为了向人类报告,我建议在不绑定到时间线的时间范围内使用标准的ISO 8601格式:PnYnMnDTnHnMnSP标记开始,T分隔小时-分钟-秒部分(如果有的话)。所以一个月零六天是P1M6D

PeriodDuration类在java.time中默认在其toString方法中使用这种格式。

代码语言:javascript
复制
String output = period.toString();

或者创建自己的字符串。

代码语言:javascript
复制
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语法一起使用。

代码语言:javascript
复制
LocalDate nextBirthday = dateOfBirth.with( MyTemporalAdjusters.nextRecurringMonthDay( myYearMonth ) );

关于java.time

java.time框架内置到Java8和更高版本中。这些类取代了麻烦的旧遗赠日期时间类,如java.util.DateCalendarSimpleDateFormat

尤达-时间项目现在在维护模式中,建议迁移到java.time类。

要了解更多信息,请参见Oracle教程。并搜索堆栈溢出以获得许多示例和解释。规范是JSR 310

在哪里获得java.time类?

  • Java 8东南9以及后来的
    • 内置的。
    • 带有捆绑实现的标准Java的一部分。
    • Java 9添加了一些次要的特性和修复。

  • Java 6SE 7
    • java.time的大部分功能都是在http://www.threeten.org/threetenbp/中移植到Java6&7中的。

三次-额外项目使用其他类扩展java.time。这个项目是将来可能加入java.time的试验场。您可以在这里找到一些有用的类,如IntervalYearWeekYearQuarter更多

票数 0
EN

Stack Overflow用户

发布于 2016-07-24 14:29:47

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

代码语言:javascript
复制
   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天

票数 3
EN

Stack Overflow用户

发布于 2016-07-24 16:03:15

我会找到下一个生日日期

代码语言:javascript
复制
LocalDate today = new LocalDate();
LocalDate birthDate = new LocalDate(1900, 7, 12);

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

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

然后数一数到那个日期还有多少个月或几天

代码语言:javascript
复制
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);
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38552679

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档