这是Android GregorianCalendar中的错误吗?

时间:2015-01-26 10:40:10

标签: android debugging gregorian-calendar

所以,它是2015年1月26日,我在Android设备上运行以下代码;

GregorianCalendar date = new GregorianCalendar();
SimpleDateFormat df = new SimpleDateFormat();

// Set date to 4 weeks ago, and then use it for the first BETWEEN date in the above query    
date.set(GregorianCalendar.WEEK_OF_YEAR, date.get(GregorianCalendar.WEEK_OF_YEAR)-4);
System.out.println(df.format(new Date(date.getTimeInMillis())));
// Set date to 2 weeks time, and then use it for the second BETWEEN date in the above query

date.set(GregorianCalendar.WEEK_OF_YEAR, date.get(GregorianCalendar.WEEK_OF_YEAR)+6);
System.out.println(df.format(new Date(date.getTimeInMillis())));

我得到了输出;

29/12/14 10:29
09/02/14 10:29

在Windows计算机上的标准Java上运行此代码段会显示正确的结果,第二个日期为09/02/15 10:29。所以在Android上,当我们要求日期回到4周时,正确地滚动年份,但是当我们要求它提前6周(超过我们的原始日期)时,它不会再次向前滚动。 / p>

我在5.0.2和4.4.2

上观察到了这一点

所以问题是,这是一个错误还是某种错综复杂的预期行为(功能)?

2 个答案:

答案 0 :(得分:2)

您不应该使用Calendar.set。您正在尝试将周字段设置为无效值,并希望它可以找出您的预期含义。这可能适用于桌面JVM,但你不应该依赖它 - 显然 - Android的实现确实以不同的方式处理它。

使用Calendar.add代替实际执行的操作:通过适当的调整从字段中添加或减去。

date.add(GregorianCalendar.WEEK_OF_YEAR, -4);
date.add(GregorianCalendar.WEEK_OF_YEAR, 6);

答案 1 :(得分:2)

我非常确定如何计算和处理某些Calendar字段以及 错误的复杂性。您使用算术调整而不是使用add(...)方法这一事实可能也会使事情变得复杂。

来自文档...

  

一个月或一年的第一周定义为从getFirstDayOfWeek()开始并且至少包含该月或年的getMinimalDaysInFirstWeek()天的最早七天。

在这种情况下,一年中的第一周,即WEEK_OF_YEAR = 1,从1月4日或5日开始,具体取决于一周的第一天是否分别设置为星期日或星期一。

Calendar类是抽象的,扩展它的具体类的不同实现可能表现不同,但允许在一年内有一个0或甚至-1的索引。日期1 - >的事实第3或第1 - >第4天(取决于一周的第一天)明显落在2015年内意味着从12月28日或29日开始的那一周被归类为第0周。

1月26日属于WEEK_OF_YEAR = 4(无论是一周的第一天),因此当您从当前WEEK_OF_YEAR中减去4时,它返回0并将该日期调整为该周的星期一,即12月29日。

当您在之前调整的日期中添加6周时出现问题 - 此时它是2014年12月29日。正如我所说,您正在使用算术调整而不是使用add(...)方法。由于您未手动调整年份,因此假设它应保持在2014年内,并且通过增加6周您导致溢出/回滚到2014年初,而不是动态调整YEAR以及WEEK_OF_YEAR等。

相关问题