将年份添加到 Java 日历不起作用

发布于 2024-09-26 04:32:45 字数 510 浏览 1 评论 0 原文

请告诉我这一点:

我只是想在当前日期上加上 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;
}

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

有人吗?

Please enlight me on this :

I'm simply trying to add 10 years to the current date then substract an expiration date from it to return the number of years:

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;
}

When I debug this, the calendar always stay at the current year.

Anyone ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

江南月 2024-10-03 04:32:45

你有一个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 );
        } 

You have a problem with int / long conversion: 365 * 24 * 60 * 60 * 1000
Which evaluates to 31536000000 and therefore exceeds Integer.MAX_VALUE 2147483647
This works:

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 );
        } 
魂牵梦绕锁你心扉 2024-10-03 04:32:45

您对 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();

Your calculation of max is wrong. An int cannot hold a year in millis.

Rather replace it by

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

Or better, use JodaTime:

DateTime tenYearsLater = new DateTime().plusYears(10);
DateTime expiration = new DateTime(expiration_date.getTime());
Period period = new Period(expiration, tenYearsLater);
return period.getYears();
隱形的亼 2024-10-03 04:32:45

这是一个应该有效的简单示例。

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

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

Here's a simple example of what should work.

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

Just remember to use a long to get the time in milliseconds!

つ低調成傷 2024-10-03 04:32:45

日历是惰性的,因此它可能不会重新计算所有其他字段,直到您要求它们为止。这让我之前在调试器中感到困惑。如果您 System.out.println(ten_year_later); 会发生什么?

Calendar is lazy, so it might not recalculate all the other fields until you ask for them. That's thrown me off in the debugger before. What happens if you System.out.println(ten_year_later);?

<逆流佳人身旁 2024-10-03 04:32:45

我在评论中指出,您对一年中的毫秒数的计算不正确(不用介意 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);

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

I've noted in a comment that you have an incorrect calculation for number of millis in a year (nevermind the int/long issue).

Since you have two calendars, each of which can keep a year, why don't you write your code like this (not compiled, so may contain typos):

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);

Assuming that's what you really want ...

相守太难 2024-10-03 04:32:45

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 及更高版本中。这些类取代了麻烦的旧遗留日期时间类,例如java.util.Date, 日历, & SimpleDateFormat

要了解更多信息,请参阅 Oracle 教程。并在 Stack Overflow 上搜索许多示例和解释。规范为 JSR 310

Joda-Time 项目,现已在 维护模式,建议迁移到java.time 类。

您可以直接与数据库交换java.time对象。使用符合 JDBC 驱动程序 /jeps/170" rel="nofollow noreferrer">JDBC 4.2 或更高版本。不需要字符串,不需要 java.sql.* 类。

从哪里获取 java.time 类?

ThreeTen-Extra 项目通过附加类扩展了 java.time 。该项目是 java.time 未来可能添加的内容的试验场。您可能会在这里找到一些有用的类,例如 间隔YearWeek<代码>YearQuarter,以及更多

tl;dr

Use modern java.time classes. Can be done in a one-liner (not that I recommend that).

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

java.time

The modern approach uses the java.time classes that supplanted the legacy date-time classes such as Calendar.

The usual concrete implementation of Calendar is GregorianCalendar. This is now replaced by ZonedDateTime. You can convert back and forth by calling new methods on the old classes.

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

Get current moment.

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

Add ten years.

ZonedDateTime zdtLater = zdtNow.plusYears( 10 ) ;

Calculate elapsed time in years between the dates of those two moments.

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

Interrogate for the number of full years.

int yearsElapsed = p.getYears() ;

About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.

Where to obtain the java.time classes?

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

岁月静好 2024-10-03 04:32:45

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

ten_year_later 应该是正确的。无需像 R. Bemrose 所写的那样调用computeFields。

The number of milliseconds in a year is well outside the range of an int, so both the int cast of ten_year_later.getTimeInMillis() - expiration.getTimeInMillis() and the calculation 365 * 24 * 60 * 60 * 1000 will evaluate to incorrect values.

The ten_year_later should be correct. There is no need to invoke computeFields as R. Bemrose wrote.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文