Java日历添加不增加年份

时间:2012-12-24 10:10:15

标签: java android calendar

我有一个存储周开始日期的变量,但是当我从2012年到2013年时,它不会更新年份。

日期和月份添加正确,所以它正确地从26/12到02/01,但它仍然是2012年。

// roll one week forward
Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(mPrefsHelper.getWeekStart());
cal.add(Calendar.WEEK_OF_YEAR, 1);

3 个答案:

答案 0 :(得分:1)

来自java.util.Calendar

的javadoc
First Week
     

日历使用两个参数定义特定于语言环境的七天工作周:一周的第一天和第一天的最小天数   一周(从1到7)。这些数字取自语言环境资源   构建日历时的数据。它们也可能被指定   明确地通过设置其值的方法。

     

设置或获取WEEK_OF_MONTH或WEEK_OF_YEAR字段时,日历必须将月份或年份的第一周确定为   参照点。一个月或一年的第一周被定义为   最早的七天时间从getFirstDayOfWeek()开始   至少包含该月的getMinimalDaysInFirstWeek()天或   年。周数在第一周之前编号为......,-1,0;周数   2,3,......跟着它。请注意,返回的规范化编号   get()可能不同。例如,特定的Calendar子类可以   将前一周的第1周指定为前一周的第n周   年。

它是特定于语言环境的。在您的情况下,如果本周包含新年的天数,则将其计为新年的第1周。

答案 1 :(得分:1)

tl; dr

使用 ThreeTen-Extra 库中的YearWeek类。

LocalDate firstDayOfFirstYearWeekOfNextWeekBasedYear =     // Represent a date-only value, without a time-of-day, without a time zone.
    YearWeek                                               // Represent an entire week of a week-based year using standard ISO 8601 definition of a week and year.
    .of(                                                   // Determine the year-week of a particular date.
        LocalDate.now( ZoneId.of( "America/Montreal" ) )   // Capture the current date as seen in the wall-clock time used by the people of a particular region (a time zone). 
    )                                                      // Returns a `YearWeek` object.
    .plusYears( 1 )                                        // Returns a `YearWeek` object representing the following year's year-week.
    .withWeek( 1 )                                         // Adjust to the first week of that week-based-year.
    .atDay( DayOfWeek.MONDAY )                             // Determine the date of a day-of-week within that week. Returns a `LocalDate`. Remember, this might be a date in the *previous* calendar year.
; 

java.time

现代方法使用 java.time 类,该类在几年前取代了麻烦的旧式日期时间类,例如Calendar

LocalDate

对于没有日期和时区的仅日期值,请使用LocalDate

LocalDate localDate = LocalDate.of( 2012 , Month.DECEMBER , 26 ) ;

下一周的第二天

我们使用TemporalAdjuster移到另一个日期。在TemporalAdjusters类中找到了几种实现。我们希望next能够找到某个星期几的下一个日期。

TemporalAdjuster ta = TemporalAdjusters.next( DayOfWeek.WEDNESDAY ) ;

应用该日期以获取下一个日期。

LocalDate nextWednesday = localDate.with( ta ) ;
  

nextWednesday.toString():2013-01-02

是的,我们确实将年份从2012年过渡到2013年。

请参阅此code run live at IdeOne.com

年周

如果要按一年中的第几周找到日期,则更为复杂。您必须按周定义您的意思。第1周是否包含1月1日?还是第一周的第一周完全由新年起算?还是#1在新的一年中的某个星期几?

ISO 8601标准周

标准ISO 8601 definition of week将第一个星期定义为包含新年的第一个星期四。因此,以周为基础的年份有52周或53周,从周一至周日运行,并且可以从上一个/下一个日历年开始的几天开始/结束。

如果这符合您的需求,建议您将 ThreeTen-Extra 库添加到您的项目中。这为您提供了YearWeek类。

YearWeek yw = YearWeek.from( LocalDate.of( 2012 , Month.DECEMBER , 26 ) ) ;
YearWeek ywNext = yw.plusWeeks( 1 ) ;

从那周开始一天。

LocalDate ld = ywNext.atDay( DayOfWeek.MONDAY ) ;

要获取任何本地日期之后的一周中第一周的第一天的第一天:

LocalDate ld = 
    YearWeek
    .of( someLocalDate )
    .plusYears( 1 )
    .withWeek( 1 )
    .atDay( DayOfWeek.MONDAY ) 
; 

关于 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类?

Table of which java.time library to use with which version of Java or Android

答案 2 :(得分:0)

道歉,感谢您的所有回复。我的问题特定于我的代码,在某些时候我正在这样做:

mCalendar.clear();
mCalendar.setFirstDayOfWeek(Calendar.MONDAY);
mCalendar.set(Calendar.WEEK_OF_YEAR, week);
mCalendar.set(Calendar.YEAR, year);

并使用我从之前的代码获得的日期获得的值。

所以这是一个约会(比如1月2日星期三),它有一周的一年和一年的2013年。它清除日历并正确设置周和年,但是我当时再次调用这个,这是以某种方式将年份设定为2012年。我在大多数情况下基本上都删除了这段代码,现在工作正常。