Android Calendar.getInstance() 今天午夜后没有得到
Android Calendar.getInstance() does not get today after midnight
我有以下代码:
Calendar nextSchedule = Calendar.getInstance();
nextSchedule.set(Calendar.HOUR_OF_DAY, 0);
nextSchedule.set(Calendar.MINUTE, 0);
nextSchedule.set(Calendar.SECOND, 10);
nextSchedule.set(Calendar.MILLISECOND, 0);
nextSchedule.add(Calendar.DAY_OF_YEAR, 1);
Calendar cal = Calendar.getInstance();
long diff = nextSchedule.getTimeInMillis() - cal.getTimeInMillis();
long seconds = diff / 1000;
long minutes = seconds / 60;
long hours = minutes / 60;
正如预期的那样,上午 11 点左右它给了我 13/12 小时但是在小部件中执行以下操作时:
Calendar nextSchedule = Calendar.getInstance();
nextSchedule.set(Calendar.HOUR_OF_DAY, 0);
nextSchedule.set(Calendar.MINUTE, 0);
nextSchedule.set(Calendar.SECOND, 10);
nextSchedule.set(Calendar.MILLISECOND, 0);
nextSchedule.add(Calendar.DAY_OF_YEAR, 1);
alarmManager.setExact(AlarmManager.RTC_WAKEUP, nextSchedule.getTimeInMillis(), pendingIntent);
1:30am左右,依旧没有更新。只有在凌晨 2 点到 9 点之间(我睡着了)它才更新。
其他地方也发生了类似的怪事。我有一个带有以下代码的日历视图 (applandeo):cvCalendar.setOnDayClickListener(eventDay -> showDateItems(eventDay,lvCalendar));
private void showDateItems(EventDay eventDay, ListView lvCalendar) {
Calendar cal = Calendar.getInstance();
Calendar cal2 = Calendar.getInstance();
cal.set(eventDay.getCalendar().get(Calendar.YEAR),eventDay.getCalendar().get(Calendar.MONTH),eventDay.getCalendar().get(Calendar.DATE));
cal2.set(eventDay.getCalendar().get(Calendar.YEAR),eventDay.getCalendar().get(Calendar.MONTH),1);
cal2.add(Calendar.MONTH, -1);
ArrayList<String> items = new ArrayList<>();
String line;
for (ItemsHistoryItem item: Utils.getInstance().itemsHistory) {
if (item.getxDay() < Utils.getInstance().calenderToEpoch(cal2) && item.getyDay() < Utils.getInstance().calenderToEpoch(cal2)) break;
if (item.getxDay() != Utils.getInstance().calenderToEpoch(cal) && item.getyDay() != Utils.getInstance().calenderToEpoch(cal)) continue;
line = item.getItemId() + ": $" + item.getAmount();
if (item.getxDay() == Utils.getInstance().calenderToEpoch(cal))
line += " (x day)";
else
line += " (y day)";
items.add(line);
}
ArrayAdapter<String> lcAdapter = new ArrayAdapter<>(requireActivity(), android.R.layout.simple_list_item_1, items);
lvCalendar.setAdapter(lcAdapter);
}
long calenderToEpoch(Calendar cal2) {
return TimeUnit.MILLISECONDS.toDays(cal2.getTimeInMillis());
}
基本上,上面的代码扫描项目的日期,当用户 select 某个日期时,他会得到一个项目列表,其中日期(x 和 y)属于该日期。在白天这样做时,它会起作用。当在 1:30am 中这样做时(例如),它会提前一天移动,因此如果用户单击 12-oct,他将获得 11-oct 的项目。在凌晨 2 点到 9 点之间,它 "shifts" 返回并按预期工作。
知道这里出了什么问题吗?
如果你希望它在你想要的时间准确触发,我有一个正确使用 alarmmanager 的建议,否则当设备处于深度睡眠模式并延迟时它不会按时触发:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// use setAlarmClock function of AlarmManager
// but this function will show an alarm icon on statusbar
// if you dont want to show that icon you can use
// setExactAndAllowWhileIdle function but that will not be
// perfectly exact
}
else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
// use setExact function of AlarmManager
}
else {
// use set function of AlarmManager
}
显然 Calendar.getInstance() 在我的情况下的默认时区是 GMT+3,所以在凌晨 3 点显示项目的日期并且更新了小部件。要修复它,我只需执行以下操作:
Calendar cal = Calendar.getInstance();
cal.setTimeZone(TimeZone.getTimeZone("UTC"));
我有以下代码:
Calendar nextSchedule = Calendar.getInstance();
nextSchedule.set(Calendar.HOUR_OF_DAY, 0);
nextSchedule.set(Calendar.MINUTE, 0);
nextSchedule.set(Calendar.SECOND, 10);
nextSchedule.set(Calendar.MILLISECOND, 0);
nextSchedule.add(Calendar.DAY_OF_YEAR, 1);
Calendar cal = Calendar.getInstance();
long diff = nextSchedule.getTimeInMillis() - cal.getTimeInMillis();
long seconds = diff / 1000;
long minutes = seconds / 60;
long hours = minutes / 60;
正如预期的那样,上午 11 点左右它给了我 13/12 小时但是在小部件中执行以下操作时:
Calendar nextSchedule = Calendar.getInstance();
nextSchedule.set(Calendar.HOUR_OF_DAY, 0);
nextSchedule.set(Calendar.MINUTE, 0);
nextSchedule.set(Calendar.SECOND, 10);
nextSchedule.set(Calendar.MILLISECOND, 0);
nextSchedule.add(Calendar.DAY_OF_YEAR, 1);
alarmManager.setExact(AlarmManager.RTC_WAKEUP, nextSchedule.getTimeInMillis(), pendingIntent);
1:30am左右,依旧没有更新。只有在凌晨 2 点到 9 点之间(我睡着了)它才更新。
其他地方也发生了类似的怪事。我有一个带有以下代码的日历视图 (applandeo):cvCalendar.setOnDayClickListener(eventDay -> showDateItems(eventDay,lvCalendar));
private void showDateItems(EventDay eventDay, ListView lvCalendar) {
Calendar cal = Calendar.getInstance();
Calendar cal2 = Calendar.getInstance();
cal.set(eventDay.getCalendar().get(Calendar.YEAR),eventDay.getCalendar().get(Calendar.MONTH),eventDay.getCalendar().get(Calendar.DATE));
cal2.set(eventDay.getCalendar().get(Calendar.YEAR),eventDay.getCalendar().get(Calendar.MONTH),1);
cal2.add(Calendar.MONTH, -1);
ArrayList<String> items = new ArrayList<>();
String line;
for (ItemsHistoryItem item: Utils.getInstance().itemsHistory) {
if (item.getxDay() < Utils.getInstance().calenderToEpoch(cal2) && item.getyDay() < Utils.getInstance().calenderToEpoch(cal2)) break;
if (item.getxDay() != Utils.getInstance().calenderToEpoch(cal) && item.getyDay() != Utils.getInstance().calenderToEpoch(cal)) continue;
line = item.getItemId() + ": $" + item.getAmount();
if (item.getxDay() == Utils.getInstance().calenderToEpoch(cal))
line += " (x day)";
else
line += " (y day)";
items.add(line);
}
ArrayAdapter<String> lcAdapter = new ArrayAdapter<>(requireActivity(), android.R.layout.simple_list_item_1, items);
lvCalendar.setAdapter(lcAdapter);
}
long calenderToEpoch(Calendar cal2) {
return TimeUnit.MILLISECONDS.toDays(cal2.getTimeInMillis());
}
基本上,上面的代码扫描项目的日期,当用户 select 某个日期时,他会得到一个项目列表,其中日期(x 和 y)属于该日期。在白天这样做时,它会起作用。当在 1:30am 中这样做时(例如),它会提前一天移动,因此如果用户单击 12-oct,他将获得 11-oct 的项目。在凌晨 2 点到 9 点之间,它 "shifts" 返回并按预期工作。
知道这里出了什么问题吗?
如果你希望它在你想要的时间准确触发,我有一个正确使用 alarmmanager 的建议,否则当设备处于深度睡眠模式并延迟时它不会按时触发:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// use setAlarmClock function of AlarmManager
// but this function will show an alarm icon on statusbar
// if you dont want to show that icon you can use
// setExactAndAllowWhileIdle function but that will not be
// perfectly exact
}
else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
// use setExact function of AlarmManager
}
else {
// use set function of AlarmManager
}
显然 Calendar.getInstance() 在我的情况下的默认时区是 GMT+3,所以在凌晨 3 点显示项目的日期并且更新了小部件。要修复它,我只需执行以下操作:
Calendar cal = Calendar.getInstance();
cal.setTimeZone(TimeZone.getTimeZone("UTC"));