我有两个日期,格式如下出生日期假设为 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;
}
请任何人帮助我提前谢谢
根据您的问题,您想使用 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 天
我会找到下一个生日日期
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);
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 | 出生日期: 1995-04-09 | 今日: 2016-07-24| 下一个生日: 2017-04-09
Period
现在我们继续计算距离下一个生日的时间。Period
类以年、月和日表示时间跨度。
Period period = Period.between ( today , nextBirthday ).normalized ();
我们可以询问月份部分和天数部分。
int months = period.getMonths();
int days = period.getDays();
字符串
至于以字符串形式报告这些值,用于数据交换以及可能向人类报告的一些报告,我建议在与时间线无关的时间段内使用标准的ISO 8601格式:PnYnMnDTnHnMnS
。P
标记开始,T
分隔小时-分钟-秒部分(如果有(。所以一个月零六天就P1M6D
.
java.time 中的 Period
和 Duration
类在其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类型一样。但不幸的是,对于Period
和Duration
对象来说,这似乎是不可能的。
TemporalAdjuster
可以将此代码打包到实现TemporalAdjuster
的类中。然后,您可以使用简单的with
语法使用它。
LocalDate nextBirthday = dateOfBirth.with( MyTemporalAdjusters.nextRecurringMonthDay( myYearMonth ) );
关于 java.time
java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧传统日期时间类,如java.util.Date
、Calendar
和SimpleDateFormat
。
Joda-Time 项目现在处于维护模式,建议迁移到 java.time 类。
要了解更多信息,请参阅 Oracle 教程。并搜索堆栈溢出以获取许多示例和解释。规范为 JSR 310。
从哪里获得java.time类?
- Java SE 8 和 SE 9 及更高版本
- 内置。
- 具有捆绑实现的标准 Java API 的一部分。
- Java 9添加了一些小功能和修复。
- Java SE 6 和 SE 7
- 许多java.time功能在ThreeTen-Backport中向后移植到Java 6和7。
- 人造人
- ThreeTenABP项目专门为Android改编了ThreeTen-Backport(如上所述(。
- 请参阅如何使用ThreeTenABP...。
ThreeTen-Extra项目通过额外的类扩展了java.time。这个项目是未来可能添加到java.time的试验场。你可以在这里找到一些有用的类,如Interval
、YearWeek
、YearQuarter
等。