gpt4 book ai didi

Java Calendar 实例递增 DAY_OF_MONTH 作为递减(仅)HOUR 或 MINUTE 的副作用

转载 作者:太空宇宙 更新时间:2023-11-03 12:45:54 33 4
gpt4 key购买 nike

我有an unfinished Android app主要 Activity 包含一个 TimePicker (@+id/tyme),一个 DatePicker (@+id/date),以及一个 TextView (@+id/dropTime),用于显示类似“DateTime”的数据,出于某种原因我需要两个 View 来指定。

因为 Javadocs 反对所有从 Date 实例中提取 DateTime 字段类型值的尝试,我想使用 Calendar 类来表示用户选择的组合年、月、日、时、分、秒。我发现我经常(但不总是)不能在不同时递增日期字段的情况下递减小时或分钟字段。这是我的 DatePicker 事件处理程序:

        date = (DatePicker) findViewById(R.id.date);
// h/t O'one https://stackoverflow.com/a/34952495/948073
date.init(
calendar.get(Calendar.YEAR),
calendar.get(Calendar.MONTH),
calendar.get(Calendar.DAY_OF_MONTH),
new DatePicker.OnDateChangedListener() {
@Override
public void onDateChanged(DatePicker datePicker, int y, int m, int d) {
System.out.println("onDateChanged(tp,"+y+","+m+","+d+")");
calendar.set(Calendar.YEAR, y);
calendar.set(Calendar.MONTH, m);
calendar.set(Calendar.DAY_OF_MONTH, d);
updateDropTime();
}
}
);

还有 TimePicker。请注意 y/m/d 字段的显式备份和恢复,以徒劳地尝试消除 h:m:s 更改期间 y:m:d 的可疑交叉污染:

        private TimePicker time;
dropTime = (TextView) findViewById(R.id.dropTime);
updateDropTime();
time = (TimePicker) findViewById(R.id.tyme);


time.setOnTimeChangedListener(new TimePicker.OnTimeChangedListener() {
public void onTimeChanged(TimePicker tp, int h, int m) {
System.out.println("onTimeChanged(tp,"+h+","+m+")");
// Save state of y/m/d portion of calendar
int y = calendar.get(Calendar.YEAR);
int mo = calendar.get(Calendar.MONTH);
int d = calendar.get(Calendar.DAY_OF_MONTH);
// Set h and m fields of calendar based on user input
calendar.set(Calendar.HOUR, h);
calendar.set(Calendar.MINUTE, m);
// Restore state of y/m/d fields
calendar.set(Calendar.YEAR, y);
calendar.set(Calendar.MONTH, mo);
calendar.set(Calendar.DAY_OF_MONTH, d);
// In theory y/m/d portion of datetime should be unchanged
updateDropTime();
}
});

这两个事件处理程序都调用了 updateDropTime(),如下所示:

private void updateDropTime() {
String disp = DateFormat.getDateTimeInstance().format(calendar.getTimeInMillis());
dropTime.setText(disp);
}

我怀疑导致 disp 值的方法链中的某些东西是看似困惑的行为发生的地方,因为我认为我已经系统地消除了对日期字段的任何更改可以想象,时间字段变化的副作用。

最佳答案

这一行是错误的:

            calendar.set(Calendar.HOUR, h);

相反,你想要:

            calendar.set(Calendar.HOUR_OF_DAY, h);

您在 onTimeChanged() 中获得的 h 是 24 小时制的一天中的小时。 Calendar.HOUR 表示 AM 或 PM 中的小时,即 12 小时制。

这怎么会导致您的问题?示例:原始时间是 20:25(如果您愿意,也可以是晚上 8:25)。用户将其更改为 13:28(下午 1:28)。您将 Calendar.HOUR 设置为 13。由于原始时间是下午并且您没有更改它,您实际上是将时间设置为下午 13:28。这是无稽之谈,但 Calendar 并不关心,它只是将其解释为 1:28 AM 第二天。设置日期没有帮助,因为在你这样做的时候,字段还没有计算,所以内部时间仍然是正确日期的下午 13:28。只有当您最后调用 getTimeInMillis() 时,才会计算所有字段、检测到溢出并增加日期。

Calendar 默认宽松

如果您想收到有关此类错误的通知(我们都会不时发生),请在创建后对 Calendar 对象调用 setLenient(false)它。这将导致它不接受超出范围的值,例如 HOUR 的 13。

java.time

如果您根本不想为 Calendar 类操心,那么您肯定不是第一个,还有一个更好、对程序员更友好的替代方案。现代 Java 日期和时间 API 内置于 Java 8 及更高版本中,在 Android 上,您可以在 ThreeTenABP 中找到它。 , 请参阅 How to use ThreeTenABP in Android Project .我建议将日期保存在 LocalDate 对象中,将一天中的时间保存在 LocalTime 中,这样用户就可以独立更新每个对象而没有交叉污染的风险。只有在 updateDropTime() 中,您才会使用 LocalDate.atTime() 将两者组合成一个 LocalDateTime,然后将其格式化为您想要的显示格式使用 DateTimeFormatter

public void onTimeChanged(TimePicker tp, int h, int m) {
System.out.println("onTimeChanged(tp," + h + "," + m + ")");
time = LocalTime.of(h, m);
updateDropTime();
}

更新可能是这样的:

private void updateDropTime() {
String disp = date.atTime(time)
.format(DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT));
dropTime.setText(disp);
}

关于Java Calendar 实例递增 DAY_OF_MONTH 作为递减(仅)HOUR 或 MINUTE 的副作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45260922/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com