2016-01-07 52 views
0

我想创建一个日历对象并将其设置为当年的某一年和一周。日历获得年份返回错误结果

Calendar calendar = Calendar.getInstance(); 
calendar.set(Calendar.WEEK_OF_YEAR, weekOfYear); // 1 
calendar.set(Calendar.YEAR, year); // 2016 
setWeekChecked(calendar); 

这是日历对象的的toString我将它传递给setWeekChecked方法:

java.util.GregorianCalendar中[时间= ?, areFieldsSet =假,宽大=真,区=美国/纽约,Firstdayofweek可= 1,minimalDaysInFirstWeek = 1,ERA = 1,YEAR = 2016,MONTH = 0,WEEK_OF_YEAR = 1,WEEK_OF_MONTH = 2,DAY_OF_MONTH = 7,DAY_OF_YEAR = 7,DAY_OF_WEEK = 5,DAY_OF_WEEK_IN_MONTH = 1,AM_PM = 0,HOUR = 5,HOUR_OF_DAY = 5,MINUTE = 25,SECOND = 43,微差= 219,ZONE_OFFSET = -18000000,DST_OFFSET = 0]

在setWeekChecked方法:

public void setWeekChecked(final Calendar cal) { 
    final int targetWeek = cal.get(Calendar.WEEK_OF_YEAR); // Returns 1 
    final int targetYear = cal.get(Calendar.YEAR); // Returns 2015?? 
} 

这是日历对象的现在了toString:

java.util.GregorianCalendar中[时间= 1451557543219,areFieldsSet =真,宽大=真,区=美国/纽约,Firstdayofweek可= 1,minimalDaysInFirstWeek = 1,ERA = 1,YEAR = 2015,月= 11,WEEK_OF_YEAR = 1,WEEK_OF_MONTH = 5,DAY_OF_MONTH = 31,DAY_OF_YEAR = 365,DAY_OF_WEEK = 5,DAY_OF_WEEK_IN_MONTH = 5,AM_PM = 0 ,HOUR = 5,HOUR_OF_DAY = 5,MINUTE = 25,SECOND = 43,MILLISECOND = 219,ZONE_OFFSET = -18000000,DST_OFFSET = 0]

我在做什么错?

+0

我不知道这个问题,但通常在压光机教程我看到+1的年份和月份域 –

+0

@VivekMishra:未与年... –

+0

是,在指数月开始0 –

回答

8

我怀疑日历试图在2016年

现在的第一个星期使用当前日的一周(今天是星期四),看着你的日历设置,你有Firstdayofweek可= 1(星期日到星期六运行周)和minimalDaysInFirstWeek = 1(所以今年的第一周是包含1月1日的第一周)。

这意味着2016年第一周的日历从2015年27月27日到2016年1月2日。因此,第一周的周四是12月31日 - 这正是您向我们显示的日历所说的日历。

从根本上说,以“一年的周”日历算术技巧,原因是:

  • 有很多的看着他们不同的特定文化的方式
  • 通常要求不指定那些你“重新真正感兴趣的

我强烈建议使用约达时间,如果在所有可能使您的日期/时间处理代码更清晰下手,但你仍然需要解决正是你的意思是“将其设置为当年的某一年和一周”。请注意,乔达时间将“周年”(用于星期几和星期几)的概念与“年份”(月份和月份中使用)的概念区分开来,这非常有帮助。您需要注意的是,对于给定的日期,周年和年份可能会有所不同。

+0

很好的解释和一个合理的原因 –

0

TL;博士

LocalDate.of(2016 , Month.JULY , 1) 
     .with(IsoFields.WEEK_OF_WEEK_BASED_YEAR , 1) 

详细

Answer by Jon Skeet是正确的。更新:我们有更好的方法。

内置于Java 8及更高版本中的java.time类取代了与最早版本的Java捆绑在一起的麻烦的旧式遗留日期 - 时间类。并且java.time正式取代了Joda-Time,因为该项目现在处于维护模式。正如Skeet指出的那样,有不同的方法可以定义每周的年份。

java.time类为week-of-year的标准ISO 8601定义提供支持。这个定义是,第一周是周四的第一周,而那周是周一开始。因此,本周的开始可能包括前一年的一天或更多天,最后一周可能包括来年的一天或更多天。这一年总是有52周或53周。

有关更多详细信息,请参阅my Answer到类似的问题。

LocalDate类代表没有时间和没有时区的仅有日期的值。

获得所需年份中间附近的日期。所需年份为以周为单位的年份而不是一个日历年,因此必须避免日历年的开始或结束。在你的情况,你想2016年

LocalDate ld = LocalDate.of(2016 , Month.JULY , 1) ; 

下一页基于为期一周的一年中,我们通过使用IsoFields.WEEK_OF_WEEK_BASED_YEAR调整该日期到所需的一周。

LocalDate dayIn2016W01 = ld.with(IsoFields.WEEK_OF_WEEK_BASED_YEAR , 1) ; 

如果你想这一周的第一天,使用另一个TemporalAdjusterTemporalAdjusters类。

LocalDate firstDayOf2016W01 = dayIn2016W01.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY)); 

提示:当Android的变得更强大,使用YearWeek类从ThreeTen-Extra项目。


关于java.time

java.time框架是建立在Java 8和更高版本。这些类取代了日期时间类legacy,如java.util.Date,Calendar,& SimpleDateFormat

Joda-Time项目现在位于maintenance mode,建议迁移到java.time类。请参阅Oracle Tutorial。并搜索堆栈溢出了很多例子和解释。规格是JSR 310

从哪里获取java.time类?