Lor*_*ori 3 java datetime android calendar date
我有一个未完成的Android应用程序,主要活动有TimePicker
(@+id/tyme
),a DatePicker
(@+id/date
)和a TextView
(@+id/dropTime
),用于显示类似"DateTime"的数据,由于某种原因,我需要指定两个视图.
因为Javadocs不赞成从Date
实例中提取DateTime-field-type值的所有尝试,所以我想使用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();
}
}
);
Run Code Online (Sandbox Code Playgroud)
而且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();
}
});
Run Code Online (Sandbox Code Playgroud)
这两个事件处理程序都调用updateDropTime()
,如下所示:
private void updateDropTime() {
String disp = DateFormat.getDateTimeInstance().format(calendar.getTimeInMillis());
dropTime.setText(disp);
}
Run Code Online (Sandbox Code Playgroud)
我怀疑方法链中导致价值的东西disp
是看似混乱的行为发生的地方,我认为我已经系统地标记了日期字段的任何变化,这些变化可能是时间字段变化的副作用.
这条线错了:
calendar.set(Calendar.HOUR, h);
Run Code Online (Sandbox Code Playgroud)
相反,你想要:
calendar.set(Calendar.HOUR_OF_DAY, h);
Run Code Online (Sandbox Code Playgroud)
将h
你在onTimeChanged()
上一个24小时制的一天的时间.Calendar.HOUR
指AM或PM内的小时,即12小时制.
这怎么会导致你的问题?示例:原始时间为20:25(如果您愿意,则为8:25 PM).用户将其更改为13:28(1:28 PM).您设置Calendar.HOUR
为13.由于原始时间是在PM并且您不更改此项,因此您实际上将时间设置为下午13:28.这是无稽之谈,但Calendar
并不关心,它只是在第二天将其解释为1:28
AM .设置日期并没有帮助,因为当你这样做时,字段尚未计算,因此内部时间仍然是正确的一天下午13:28.只有在最后调用时,才会计算所有字段,检测到溢出并增加日期.getTimeInMillis()
Calendar
是默认的宽松如果您希望收到有关此类错误(我们不时制作的错误)的通知setLenient(false)
,请Calendar
在创建后调用您的对象.这将导致它不接受像13这样的超出范围的值HOUR
.
如果你根本不想打扰这个Calendar
课程,你肯定远离第一个,并且有一个更好,更程序友好的选择.现代Java日期和时间API内置于Java 8及更高版本中,在Android上您可以在ThreeTenABP 中使用它,请参阅如何在Android项目中使用ThreeTenABP.我建议将日期保存在一个LocalDate
对象和一天中的时间,LocalTime
以便用户可以独立更新每个,而不存在交叉污染的风险.只有updateDropTime()
将两者合并为一个LocalDateTime
使用LocalDate.atTime()
,然后使用a 将其格式化为所需的显示格式DateTimeFormatter
.
public void onTimeChanged(TimePicker tp, int h, int m) {
System.out.println("onTimeChanged(tp," + h + "," + m + ")");
time = LocalTime.of(h, m);
updateDropTime();
}
Run Code Online (Sandbox Code Playgroud)
更新可能会像:
private void updateDropTime() {
String disp = date.atTime(time)
.format(DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT));
dropTime.setText(disp);
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
221 次 |
最近记录: |