java day of month_Java Calendar实例增加DAY_OF_MONTH作为递减(仅)HOUR或MINUTE的副作用

我有一个带有TimePicker(@ id / tyme)的主活动的an unfinished Android app,一个DatePicker(@id / date)和一个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();

}

}

);

和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()中获得的是24小时制的一天中的小时. Calendar.HOUR表示AM或PM内的小时,即12小时制.

这怎么会导致你的问题?示例:原始时间为20:25(如果您愿意,则为8:25 PM).用户将其更改为13:28(1:28 PM).您将Calendar.HOUR设置为13.由于原始时间是在PM并且您不更改此项,因此您实际上将时间设置为下午13:28.这是胡说八道,但日历并不关心,它只是将其解释为第二天凌晨1点28分.设置日期并没有帮助,因为当你这样做时,字段尚未计算,因此内部时间仍然是正确的一天下午13:28.只有在最后调用getTimeInMillis()时,才会计算所有字段,检测到溢出并增加日期.

日历是默认的宽松

如果您希望收到有关此类错误的通知(我们不时制作的错误),请在创建日历对象后调用setLenient(false).这将导致它不接受超出范围的值,如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);

}

标签:android,java,datetime,date,calendar

来源: https://codeday.me/bug/20190828/1751232.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值