我的程序获取当前日期,然后在循环中向该日期添加一周,并打印出新的日期。类似于:
Calendar cal = Calendar.getInstance();
for (int i=0; i < 52; i++) {
cal.add(Calendar.DATE, 7);
// print date out
}
add方法的工作方式和我预期的一样,直到12月30日,这一年从2012年跳到了2013年。
因此,使用今天的日期4/16/2012,我测试了一些不同的输入:
this - cal.add(Calendar.DATE, 38*7);
yields- "date:1/7/2013"
this - cal.add(Calendar.DATE, 37*7);
yields- "date:12/31/2013"
this - cal.add(Calendar.DATE, 37*7-1);
yields- "date:12/30/2013"
this - cal.add(Calendar.DATE, 37*7-2);
yields- "date:12/29/2012"
所以我注意到到12月30日和12月31日,这一年是正确的,然后当它回到1月份时,它又进行了自我修正。它这样做有什么原因吗?这与2012年是闰年有什么关系,还是我误解了add方法
发布于 2019-01-07 02:09:31
您是否使用SimpleDateFormat
打印日期并使用YYYY
生成年份?如果是这样的话,这就是问题所在。因为YYYY
生成的是周-年,而不是日历年。由于2012年12月30日在2013年的第1周,因此YYYY
生产2013年。要获取日历年,请在SimpleDateFormat
格式字符串中使用yyyy
。
发布于 2019-01-08 07:06:07
tl;dr
使用现代的java.time类,而不是像Calendar
这样可怕的遗留类。
LocalDate // Represent a date-only value with `LocalDate`, without time-of-day and without time zone.
.now( // Capture the current date.
ZoneId.systemDefault() // Specify your desired/expected time zone explicitly.
) // Returns a `LocalDate` object.
.plusWeeks( 1 ) // Add a week, producing a new `LocalDate` object with values based on the original, per the immutable objects pattern.
.toString() // Generate text representing this date value in standard ISO 8601 format of YYYY-MM-DD.
2019-01-23
java.time
现代方法使用java.time类。
Calendar
和GregorianCalendar
类很糟糕,设计得很糟糕,有缺陷。避开他们。现在专门被ZonedDateTime
类所取代。
LocalDate
LocalDate
类表示不带时间和time zone或offset-from-UTC的仅日期值。
在确定日期时,时区至关重要。在任何给定的时刻,全球各地的日期都会因地区而异。例如,午夜过后的几分钟在Paris France中是新的一天,而在Montréal Québec中仍然是“昨天”。
如果未指定时区,JVM将隐式应用其当前的默认时区。运行时(!)中默认值可能为change at any moment,因此您的结果可能会有所不同。最好将所需/预期的时区显式指定为参数。
指定Continent/Region
格式的proper time zone name,如America/Montreal
、Africa/Casablanca
或Pacific/Auckland
。切勿使用2-4个字母的缩写,例如EST
或IST
,因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。
ZoneId z = ZoneId.of( "America/Montreal" ) ;
LocalDate today = LocalDate.now( z ) ;
要生成以标准ISO8601格式表示该日期值的文本,只需调用toString
。
String output = today.toString() ;
日期数学很简单,有各种plus…
和minus…
方法。
LocalDate weekLater = today.plusWeeks( 1 ) ;
您还可以将时间跨度定义为Period
或Duration
。然后再加上这个。
Period p = Period.ofWeeks( 1 ) ;
LocalDate weekLater = today.plus( p ) ;
你的例子
让我们测试一下您的示例日期。
LocalDate ld = LocalDate.of( 2012 , Month.APRIL , 16 ) ;
Period period38Weeks = Period.ofWeeks( 38 ) ;
Period period37Weeks = Period.ofWeeks( 37 ) ;
Period period37WeeksLess1Days = period37Weeks.minusDays( 1 ) ;
Period period37WeeksLess2Days = period37Weeks.minusDays( 2 ) ;
LocalDate later_38 = ld.plus( period38Weeks ) ;
LocalDate later_37 = ld.plus( period37Weeks ) ;
LocalDate later_37_1 = ld.plus( period37WeeksLess1Days ) ;
LocalDate later_37_2 = ld.plus( period37WeeksLess2Days ) ;
运行code live at IdeOne.com。没问题。第38周在2013年,而第37周日期在2012年。
later_38.toString():2013-01-07
later_37.toString():2012-12-31
later_37_1.toString():2012-12-30
later_37_2.toString():2012-12-29
关于java.time
框架内置于Java8和更高版本中。这些类取代了麻烦的旧legacy日期时间类,如java.util.Date
、Calendar
和SimpleDateFormat
。
现在在maintenance mode中的项目建议迁移到java.time类。
要了解更多信息,请参阅。和搜索堆栈溢出,以获得许多示例和解释。规范为JSR 310。
您可以直接与数据库交换java.time对象。使用与JDBC 4.2或更高版本兼容的JDBC driver。不需要字符串,也不需要java.sql.*
类。
从哪里获取java.time类?
中的
项目使用额外的类扩展了java.time。这个项目是未来可能添加到java.time中的试验场。您可能会在这里找到一些有用的类,如Interval
、YearWeek
、YearQuarter
和more。
发布于 2012-04-17 04:27:54
它应该是:
cal.add(Calendar.DAY_OF_YEAR, 7);
Calendar.DATE
与Calendar.DAY_OF_MONTH
相同。
https://stackoverflow.com/questions/10181138
复制相似问题