Java日历添加年份不起作用

时间:2010-10-07 15:19:55

标签: java calendar

请点赞我:

我只是想在当前日期添加10年,然后从中减去过期日期以返回年数:

public int getMaxYears() {
  int max = 0;
  Calendar ten_year_later = Calendar.getInstance();
  ten_year_later.setTime(new Date());
  ten_year_later.add(Calendar.YEAR, 10);
  Calendar expiration = Calendar.getInstance();
  expiration.setTime(expiration_date);
  max = (int) (ten_year_later.getTimeInMillis() - expiration.getTimeInMillis())/(365 * 24 * 60 * 60 * 1000);
  return max;
}

当我调试时,日历始终保持当前年份。

任何人?

7 个答案:

答案 0 :(得分:11)

您有一个int / long转换问题:365 * 24 * 60 * 60 * 1000 其评估结果为31536000000,因此超过Integer.MAX_VALUE 2147483647 这有效:

public static void main(String[] args) {
          Calendar ten_year_later = Calendar.getInstance();
          System.out.println( ten_year_later.getTime() );
          ten_year_later.setTime(new Date()); 
          ten_year_later.add(Calendar.YEAR, 10);
          System.out.println( ten_year_later.getTime() );
          Calendar expiration = Calendar.getInstance(); 
          expiration.setTime(expiration.getTime()); 
          long max = (ten_year_later.getTimeInMillis() - expiration.getTimeInMillis())/(365 * 24 * 60 * 60 * 1000L); 
          System.out.println( "max " + max );
        } 

答案 1 :(得分:5)

您对max的计算错误。 int不能以毫秒计算一年。

而是用

替换它
max = ten_year_later.get(Calendar.YEAR) - expiration.get(Calendar.YEAR);

或者更好,请使用JodaTime

DateTime tenYearsLater = new DateTime().plusYears(10);
DateTime expiration = new DateTime(expiration_date.getTime());
Period period = new Period(expiration, tenYearsLater);
return period.getYears();

答案 2 :(得分:4)

这是一个应该起作用的简单例子。

Calendar cal = new GregorianCalendar();
cal.setTime(new Date());
cal.add(Calendar.YEAR, yearsToAdd);
Date retDate = cal.getTime();

请记住使用long来获取时间,以毫秒为单位!

答案 3 :(得分:1)

日历是懒惰的,因此在您要求之前,它可能不会重新计算所有其他字段。之前我在调试器中抛弃了这个。如果你System.out.println(ten_year_later);会怎样?

答案 4 :(得分:1)

我在评论中注意到你对一年中毫秒数的计算不正确(没关系int / long问题)。

由于您有两个日历,每个日历可以保留一年,为什么不编写这样的代码(未编译,因此可能包含拼写错误):

Calendar cal1 = Calendar.newInstance();   // this will use current time
cal1.add(Calendar.YEAR, 10);
Calendar cal2 = Calendar.newInstance();
cal2.setDate(expiration);
return cal1.get(Calendar.YEAR) - cal2.get(Calendar.YEAR);

假设这是你真正想要的......

答案 5 :(得分:1)

tl; dr

使用现代的 java.time 类。可以单线完成(不是我建议这样做)。

Period
.between(
    ( ( GregorianCalendar) myCalendarExpiration ).toZonedDateTime().toLocalDate() ,
    ZonedDateTime.now( ZoneId.of( "Asia/Kolkata" ) ).plusYears( 10 ).toLocalDate() 
)
.getYears()

java.time

现代方法使用 java.time 类取代了诸如Calendar之类的传统日期时间类。

Calendar的通常具体实现是GregorianCalendar。现在将其替换为ZonedDateTime。您可以通过在旧类上调用新方法来回转换。

ZonedDateTime zdtExpiration = ( ( GregorianCalendar) myCal ).toZonedDateTime() ;

获取当前时刻。

ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdtNow  = ZonedDateTime.now( z ) ;

加十年。

ZonedDateTime zdtLater = zdtNow.plusYears( 10 ) ;

计算这两个时刻之间的经过时间(以年为单位)。

Period p = Period.between(
    zdtExpiration.toLocalDate() , 
    zdtLater.toLocalDate()
) ;

审问整年。

int yearsElapsed = p.getYears() ;

关于 java.time

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

要了解更多信息,请参见Oracle Tutorial。并在Stack Overflow中搜索许多示例和说明。规格为JSR 310

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

您可以直接与数据库交换 java.time 对象。使用符合JDBC driver或更高版本的JDBC 4.2。不需要字符串,不需要java.sql.*类。

在哪里获取java.time类?

ThreeTen-Extra项目使用其他类扩展了java.time。该项目为将来可能在java.time中添加内容提供了一个试验场。您可能会在这里找到一些有用的类,例如IntervalYearWeekYearQuartermore

答案 6 :(得分:0)

一年中的毫秒数远远超出了int的范围,因此ten_year_later.getTimeInMillis() - expiration.getTimeInMillis()的int cast和计算365 * 24 * 60 * 60 * 1000的估算值都将计算为不正确的值。

ten_year_later应该是正确的。 R. Bemrose写道,没有必要调用computeFields。