【发布时间】:2023-03-29 13:40:02
【问题描述】:
在任何本机 Java 类中是否有一种方法可以计算特定年份的天数?例如,它是 Leap year(366 天)还是正常年份(365 天)?
还是需要我自己写?
我正在计算两个日期之间的天数,例如,距离我的生日还有多少天。我想考虑到闰年的 2 月 29 日。除了 29 号,我都完成了。
【问题讨论】:
在任何本机 Java 类中是否有一种方法可以计算特定年份的天数?例如,它是 Leap year(366 天)还是正常年份(365 天)?
还是需要我自己写?
我正在计算两个日期之间的天数,例如,距离我的生日还有多少天。我想考虑到闰年的 2 月 29 日。除了 29 号,我都完成了。
【问题讨论】:
另一种方法是向Calendar 类询问给定年份的实际最大天数:
Calendar cal = Calendar.getInstance();
cal.setTime(new Date());
int numOfDays = cal.getActualMaximum(Calendar.DAY_OF_YEAR);
System.out.println(numOfDays);
这将返回 366 表示双分裂年份,365 表示正常年份。
注意,我使用了getActualMaximum 而不是getMaximum,它总是返回 366。
【讨论】:
java.util.Date、java.util.Calendar 和 java.text.SimpleTextFormat 现在是 legacy,被java.time 类取代。见Tutorial by Oracle。
Date/Calendar/等而受苦。类。详情请见my Answer。
Year.of( 2015 ).length()
……和……
Year.isLeap( 2015 )
java.time.Year在 Java 8 及更高版本中,我们有 java.time package。 (Tutorial)
lengthYear 类表示单个年份值。你可以询问它的长度。
int daysInYear = Year.of( 2015 ).length();
isLeap您也可以询问某年是否为闰年。
Boolean isLeapYear = Year.isLeap( 2015 );
例如,使用Java的ternary operator获取一年中的天数,如:
minVal = (a
在我们的例子中,我们需要一年中的天数。非闰年是 365,闰年是 366。
int daysInYear = ( Year.isLeap( 2015 ) ) ? 366 : 365 ;
您可以获得日期的年份编号。这个数字从 1 到 365,或闰年为 366。
int dayOfYear = LocalDate.now( ZoneId.of( "America/Montreal" ).getDayOfYear() ;
换个方向,获取一年中某一天的日期。
Year.now( ZoneId.of( "America/Montreal" ) ).atDay( 159 ) ;
在处理一年时,您可以通过比较这些日期数来确定经过的天数。但是有一种更简单的方法;继续阅读。
使用ChronoUnit 枚举来计算经过的天数。
LocalDate start = LocalDate.of( 2017 , 2 , 23 ) ;
LocalDate stop = LocalDate.of( 2017 , 3 , 11 ) ;
int daysBetween = ChronoUnit.DAYS.between( start , stop );
自动处理Leap Year。
java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧 legacy 日期时间类,例如 java.util.Date、Calendar 和 SimpleDateFormat。
Joda-Time 项目现在位于maintenance mode,建议迁移到java.time 类。
要了解更多信息,请参阅Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310。
从哪里获取 java.time 类?
ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。您可以在这里找到一些有用的类,例如Interval、YearWeek、YearQuarter 和more。
【讨论】:
GregorianCalendar 标准类有一个isLeapyear() 方法。如果你得到的只是一个年份数字(比如2008),那么使用this构造函数构造一个日期,然后检查isLeapYear()方法。
【讨论】:
一年中的天数:
LocalDate d = LocalDate.parse("2020-12-31"); // import java.time.LocalDate;
return d.lengthOfYear(); // 366
离我生日还有几天:
LocalDate birth = LocalDate.parse("2000-02-29");
LocalDate today = LocalDate.now(); // or pass a timezone as the parameter
LocalDate thisYearBirthday = birth.withYear(today.getYear()); // it gives Feb 28 if the birth was on Feb 29, but the year is not leap.
LocalDate nextBirthday = today.isAfter(thisYearBirthday)
? birth.withYear(today.getYear() + 1)
: thisYearBirthday;
return DAYS.between(today, nextBirthday); // import static java.time.temporal.ChronoUnit.DAYS;
【讨论】:
对于日期时间计算,我强烈建议使用JodaTime 库。特别是对于您需要的东西,它将是一个衬里:
Days.daysBetween(date1, date2).getDays();
我希望这会有所帮助。
【讨论】:
您可以查看the Wikipedia page 以获得一些非常好的伪代码:
if year modulo 400 is 0
then is_leap_year
else if year modulo 100 is 0
then not_leap_year
else if year modulo 4 is 0
then is_leap_year
else
not_leap_year
我相信您可以弄清楚如何在 Java 中实现该逻辑。 :-)
【讨论】:
GregorianCalendar 类之前。撇开 Java 的许多其他日期/时间问题不谈,这就是这种情况下要走的路!
Joda 和这个特定的 example 可能最好地解决您的确切用例。
【讨论】:
您可以使用TimeUnit 类。对于您的特定需求,应该这样做:
public static int daysBetween(Date a, Date b) {
final long dMs = a.getTime() - b.getTime();
return TimeUnit.DAYS.convert(dMs, TimeUnit.MILLISECONDS);
}
老实说,不过,我看不出闰年在这个计算中起到什么作用。也许我错过了你问题的某些方面?
编辑:愚蠢的我,闰年魔法发生在Date.getTime()。反正你不用这样处理。
【讨论】: