在任何本机Java类中都没有一种方法可以计算出特定年份中的多少天? 例如,是year年(366天)还是正常年份(365天)?
还是我需要自己写?
我正在计算两个日期之间的天数,例如,距离我生日还剩多少天。 我要考虑到year年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。
这应该是正确的答案
@NoodleofDeath实际上,这个答案在Java 8中已于2014年过时。麻烦的旧日期时间类(例如java.util.Date,java.util.Calendar和java.text.SimpleTextFormat)现在已被遗留,由java.time类取代。请参见Oracle教程。
@BasilBourque我同意,如果可能的话,应该使用java.time类。但是对于我们这些不具备使用Java 8的奢侈的人来说,这个答案还不是过时的。 OP指的是java.util.Calendar和java.util.Date,这个答案对我们许多人仍然非常适用。这就是我一直在寻找的答案。
@SamuraiSoul在ThreeTen-Backport项目中,许多java.time功能都向后移植到Java 6和Java 7。在ThreeTenABP项目中进一步适用于Android。因此,没有理由遭受可怜的旧版Date / Calendar / etc的折磨。类。有关详细信息,请参见我的答案。
GregorianCalendar standar类具有isLeapyear()方法。如果您仅有的是年份数字(例如2008),请使用此构造函数构造一个日期,然后再检查isLeapyear()方法。
呸。愚蠢的Java及其所有内容的库。 :-P(+1)
是的,将库用于日期SUCKS。通过自己的for年,不同月份,leap秒的测试,加法数学是……无所谓的方法。 :)
但是,您可以轻松地将" MyCalendar"定义为新标准,并神奇地通过所有相关测试。
@Autocracy:只有内置的日期库很烂。向Jon Skeet询问。
是的,我在深夜写了这篇文章,但我忘了提到Im使用Calendar类和Calendar.get(Calendar.DAY_OF_YEAR)来计算差异。我只有一个疑问-如果我这样做,例如,Calendar.add(Calendar.MONTH,14)会否将结果年份设置为a年?还是全年只有365天?
它应该并且足够容易测试。在已知的leap年中设置日期,并在2月29日前完成添加。
是的,确实如此。那时不需要GregorianCalendar,我现在将一直使用我以前使用的东西,并使用TimeUnit.DAYS.convert()计算余数。
tl; dr
Year.of( 2015 )
.length()
java.time
在Java 8和更高版本中,我们具有java.time包。 (教程)
length
Year类表示单个年份的值。您可以询问其长度。
int daysInYear = Year.of( 2015 ).length();
isLeap
您还可以询问一年是否为Le年。
Boolean isLeapYear = Year.isLeap( 2015 );
例如,使用Java的三元运算符获取一年中的天数,例如:
minVal = (a < b) ? a : b;
在我们的情况下,我们需要一年中的天数。非non年为365,Le年为366。
int daysInYear = ( Year.isLeap( 2015 ) ) ? 366 : 365 ;
一年中的一天
您可以获取日期的年份数字。该数字从1到365,或a年为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 );
自动处理Le年。
关于java.time
java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧旧式日期时间类,例如java.util.Date,Calendar和SimpleDateFormat。
现在处于维护模式的Joda-Time项目建议迁移到java.time类。
要了解更多信息,请参见Oracle教程。并在Stack Overflow中搜索许多示例和说明。规格为JSR 310。
在哪里获取java.time类?
Java SE 8,Java SE 9和更高版本
内置的
标准Java API的一部分,具有捆绑的实现。
Java 9添加了一些次要功能和修复。
Java SE 6和Java SE 7
java.time的许多功能在ThreeTen-Backport中都被反向移植到Java 6和7。
安卓系统
ThreeTenABP项目专门针对Android改编了ThreeTen-Backport(如上所述)。
请参阅如何使用ThreeTenABP…。
ThreeTen-Extra项目使用其他类扩展了java.time。该项目为将来可能在java.time中添加内容提供了一个试验场。您可能会在这里找到一些有用的类,例如Interval,YearWeek,YearQuarter等。
很好,但是不要"调整"我的英语。
先生,您赢得奖牌了吗?谢谢!
对于DateTime计算,我强烈建议使用JodaTime库。特别是对于您所需要的,它是一个衬垫:
Days.daysBetween(date1, date2).getDays();
我希望这有帮助。
+1用于添加强制性的Joda-Time答案
只为执行一个简单的计算而对实现整个库不感兴趣。
GregorianCalendar.isLeapYear(int年)
不是静态方法...必须创建一个实例。瘸。
使用Joda和此特定示例可能会最好地解决您的确切用例。
您可以在Wikipedia页面上查看一些非常好的伪代码:
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中实现该逻辑。 :-)
看起来就像在重新发明轮子。
是的,同意,这是在我了解Javas GregorianCalendar类之前。 Java除了许多其他日期/时间问题,在这种情况下这就是解决方法!
为什么要下票?这是查找leap年的" the"算法。
@Cem Catikkas:绝对正确,但是问题是"这是一个有用的答案"。这是一个Java问题,因此我可以看到使用Java库的一个更好的答案,而改头换面是不好的。谢谢你的支持! :-)
您可以使用TimeUnit类。对于您的特定需求,应该这样做:
public static int daysBetween(Date a, Date b) {
final long dMs = a.getTime() - b.getTime();
return TimeUnit.DAYS.convert(dMs, TimeUnit.MILLISECONDS);
}
老实说,我看不出leap年在此计算中起什么作用。也许我错过了您的问题的某些方面?
编辑:愚蠢的我,the年魔法发生在Date.getTime()中。无论如何,您不必这样处理。