通过 java.util.Calendar.add() 添加一周失败

发布于 2024-10-05 09:34:01 字数 789 浏览 8 评论 0原文

我正在尝试在两个日期(结束日期是今天)之间的所有几周内迭代我的 Java 程序。首先,我得到开始日期:

Calendar start = Calendar.getInstance();
start = data.getFirstDate(users, threads);

到目前为止,一切顺利。开始日期是正确的,我可以使用它。现在我重申:

Calendar current = start;
while(current.before(Calendar.getInstance()) {
    // Do something
    current.add(Calendar.DATE, 7);
}

嗯,这种方法可行。我从 2002/8/23 开始,然后是 2002/8/30,然后是 2002/9/7...直到 2002/11/30。之后的日期是 2003/0/6,这既不正确,也不是有效日期!

我做错了什么?我尝试了 current.add(Calendar.DATE, 7)current.add(Calendar.WEEK_OF_YEAR, 1)current.add(Calendar.DAY_OF_YEAR, 7) ) 和其他两种方式。使用 current.roll(Calendar.DATE, 7) 不起作用,因为我停留在同一个月。使用 GregorianCalendar 也没有效果。

任何建议将不胜感激!

谢谢 朱利安

I'm trying to iterate in my Java program over all weeks between two dates (the end date being today). First, I get the starting date:

Calendar start = Calendar.getInstance();
start = data.getFirstDate(users, threads);

So far, so good. The start date is correct and I can work with it. Now I iterate:

Calendar current = start;
while(current.before(Calendar.getInstance()) {
    // Do something
    current.add(Calendar.DATE, 7);
}

Well, this kind of works. I start at 2002/8/23, then comes 2002/8/30, then 2002/9/7... UNTIL 2002/11/30. The date after that is 2003/0/6, which is neither correct nor even a valid date!

What am I doing wrong? I tried current.add(Calendar.DATE, 7), current.add(Calendar.WEEK_OF_YEAR, 1), current.add(Calendar.DAY_OF_YEAR, 7) and two other ways. Using current.roll(Calendar.DATE, 7) does not work because I stay in the same month. Using GregorianCalendar has no effect as well.

Any suggestions would be greatly appreciated!

Thanks
Julian

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

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

发布评论

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

评论(4

浊酒尽余欢 2024-10-12 09:34:01

Calendar API 中的月份字段是从 0 开始的,而不是从 1 开始的。所以 0 代表一月。别问我为什么。

The month field in the Calendar API is 0-based not 1-based. So 0 stands for January. Don't ask me why.

苏辞 2024-10-12 09:34:01

我认为您对日期的解释不正确。月份字段从零开始,即 JANUARY 为 0。因此,2002/11/30 是 12 月 30 日。

I think your interpretation of the dates is incorrect. The month field is zero-based, i.e. JANUARY is 0. So, 2002/11/30 is DECEMBER 30th.

轮廓§ 2024-10-12 09:34:01

如果您将 0 视为月份,则为 1 月,因为月份是基于 0 索引的。 0 是一月,11 是十二月。

If you're seeing 0 as a month, that's January since months are 0 index based. 0 is January and 11 is December.

无远思近则忧 2024-10-12 09:34:01

tl;dr

LocalDate.now().plusWeeks( 1 ).isBefore( stopDate )

java.time

现代答案使用 java.time 类而不是 Calendar

LocalDate

LocalDate 类表示仅日期值,没有时间和时区。

时区对于确定日期至关重要。对于任何特定时刻,全球各地的日期都会因地区而异。例如,在法国巴黎午夜过后几分钟,又是新的一天“昨天”在魁北克蒙特利尔

如果未指定时区,JVM 会隐式应用其当前的默认时区。该默认值可能随时更改,因此您的结果可能会有所不同。最好明确指定您想要/预期的时区作为参数。

大陆/地区格式指定正确的时区名称 ,例如 America/Montreal非洲/卡萨布兰卡,或太平洋/奥克兰 。切勿使用 3-4 个字母的缩写,例如 ESTIST,因为它们不是真正的时区,不是标准化的,甚至不是唯一的( !)。

ZoneId z = ZoneId.of( "America/Montreal" );
LocalDate today = LocalDate.now( z );
LocalDate weekLater = today.plusWeeks( 1 ) ;

获取您的开始日期。您可以用数字指定月份,一月到十二月的合理编号为 1-12,这与旧类中疯狂的从零开始的编号不同。

LocalDate start = LocalDate.of( 2017 , 2 , 23 ) ;  // Month is 1-12 for January-December.

或者,更好的是,使用 月份预定义的枚举对象,一年中的每个月都有一个。

LocalDate start = LocalDate.of( 2017 , Month.FEBRUARY , 23 ) ;

从这里开始,循环只是基本的 Java,使用 LocalDate 对象的比较方法:isBeforeisAfterisEqual

LocalDate ld = start ;
while( ld.isBefore( today ) ) {
    ld = ld.plusWeeks( 1 ) ;
    …
}

关于 java.time

java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧遗留日期时间类,例如java.util.Date, 日历, & ; SimpleDateFormat

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

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

从哪里获取 java.time 类?

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

tl;dr

LocalDate.now().plusWeeks( 1 ).isBefore( stopDate )

java.time

The modern answer uses java.time classes rather than Calendar.

LocalDate

The LocalDate class represents a date-only value without time-of-day and without time zone.

A time zone is crucial in determining a date. For any given moment, the date varies around the globe by zone. For example, a few minutes after midnight in Paris France is a new day while still “yesterday” in Montréal Québec.

If no time zone is specified, the JVM implicitly applies its current default time zone. That default may change at any moment, so your results may vary. Better to specify your desired/expected time zone explicitly as an argument.

Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 3-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).

ZoneId z = ZoneId.of( "America/Montreal" );
LocalDate today = LocalDate.now( z );
LocalDate weekLater = today.plusWeeks( 1 ) ;

Get your starting date. You may specify the month by a number, with sane numbering 1-12 for January-December, unlike the crazy zero-based numbering in the legacy class.

LocalDate start = LocalDate.of( 2017 , 2 , 23 ) ;  // Month is 1-12 for January-December.

Or, better, use the Month enum objects pre-defined, one for each month of the year.

LocalDate start = LocalDate.of( 2017 , Month.FEBRUARY , 23 ) ;

From there, looping is just basic Java, using the LocalDate object’s comparison methods: isBefore, isAfter, and isEqual.

LocalDate ld = start ;
while( ld.isBefore( today ) ) {
    ld = ld.plusWeeks( 1 ) ;
    …
}

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.

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

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

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.

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