【发布时间】:2012-06-12 12:42:36
【问题描述】:
对于重复发生的事件,我想在我的 Android 日历应用程序中显示下一次发生的剩余天数。
示例:
Today: 2012-06-12
Reoccurring event: 19th June
=> 13 days left
为了实现这一点,我将第一个匹配项保存在数据类型为 Calendar 的对象中:
private Calendar cal;
...
cal = new GregorianCalendar();
cal.set(Calendar.YEAR, USER_INPUT_YEAR);
cal.set(Calendar.MONTH, USER_INPUT_MONTH);
...
为了计算剩余天数,我使用了这个函数:
public int getDaysLeft() {
Date next = this.getNextOccurrence();
if (next == null) {
return -1;
}
else {
long differenceInMilliseconds = next.getTime()-System.currentTimeMillis();
double differenceInDays = (double) differenceInMilliseconds/DateUtils.DAY_IN_MILLIS;
return (int) Math.ceil(differenceInDays);
}
}
哪个使用这个功能:
public Date getNextOccurrence() {
if (this.cal == null) {
return null;
}
else {
Calendar today = new GregorianCalendar();
Calendar next = new GregorianCalendar();
next.setTime(this.cal.getTime());
next.set(Calendar.YEAR, today.get(Calendar.YEAR));
if ((today.get(Calendar.MONTH) > this.cal.get(Calendar.MONTH)) || ((today.get(Calendar.MONTH) == this.cal.get(Calendar.MONTH)) && (today.get(Calendar.DAY_OF_MONTH) > this.cal.get(Calendar.DAY_OF_MONTH)))) {
next.add(Calendar.YEAR, 1);
}
return next.getTime();
}
}
顺便说一句,要获取初始日期,我希望找到一个 YYYY-MM-DD 值并像这样解析它:
(new SimpleDateFormat("yyyy-MM-dd")).parse(INPUT_DATE_STRING)
这在大多数情况下都可以正常工作,但一些用户报告他们将-1469913 等数字视为“剩余天数”。怎么会这样?
我认为日期 (cal) 可能未设置或无效,但它会显示 -1 或类似的东西,因为所有部分都有空检查,对吧?
-1469913 的意思类似于几年前的-4027!由于这是一个重复发生的事件,我认为“剩余天数”信息应始终在 0 到 366 之间。什么可能导致此代码产生这样的数字?这是否意味着getNextOccurrence() 返回的数据是过去 4027 年?我无法解释这种行为。
我希望你能帮助我。提前非常感谢您!
编辑:因为它可能会有所帮助:使用 DateFormat.getDateInstance().format() 时,错误日期的年份始终输出为 1,例如Jan 3, 1。尽管如此,getDaysLeft() 的结果是 4k 年。
编辑 #2: 我发现像 1--22199-1 这样的日期会产生“还剩 4k 年”的输出。尽管如此,它还是被(new SimpleDateFormat("yyyy-MM-dd")).parse() 成功解析。同样,-1-1-1-91- 被正确解析为Jan 1, 2。
编辑#3:事实证明,像“0000-01-03”这样简单的日期造成了所有麻烦。当我以毫秒为单位输出时间时,它显示-62167222800000。然后当我将它输出到 GMT 字符串时,它会显示 0001-01-03 - 很奇怪,不是吗?当我将年份设置为1900 时,以毫秒为单位的时间突然变为-122095040400000。为什么?
【问题讨论】:
-
Joda 附议——但这不是很容易调试吗?
-
为什么是乔达?
Calendar类实际上非常有用且易于处理,不是吗?但这对我来说并不容易调试,因为我没有要测试的输入数据。但它只能是一个无效的日期,因为重复发生的事件总是在未来 366 天或更短的时间内,还是我违背了基本的数学? -
@MarcoW。因为这样的事情和更多的事情在乔达是微不足道的。我不明白“没有输入数据”来测试;你有足够的钱在 4k 年前得到一些东西,所以这似乎是一个很好的起点。即使你没有那个,我几乎可以肯定,当正确重构时,日期数学是可测试的。
-
问题是:我只知道输出(4k 年前),但我不知道哪个输入(日期字符串)产生了这个输出。
-
我怀疑这是否相关,但是:-1469913 实际上是大约 4024 年前(因为一年大约是 365.25 天)。我注意到这是 2*2012。您是否有可能在某处得到否定的年份数字,使用 -2012 而不是 2012? (查看您的代码,我看不出有什么明显的方法可以实现。)
标签: android date calendar gregorian-calendar