MaterialDatePicker选择后返回错误日期及时区显示异常问题求助
问题根源
- MaterialDatePicker 所有返回/接收的时间戳均为选中日期对应UTC时区零点的毫秒值,和本地时区无关。直接将该时间戳转为本地时区日期时,会因为时区差出现日期偏移:西半球时区(如美洲/Tijuana)会出现日期减1,东半球时区如果UTC时间已过当天零点但本地还在次日的情况也会出现偏移。
MaterialDatePicker.todayInUtcMilliseconds()返回的是UTC时区当天零点的时间戳,当本地日期和UTC日期不一致时,就会出现默认选中值和实际本地日期不符的问题。
修复方案
1. 修正默认选中值
自行计算本地当前日期对应UTC零点的时间戳,传入setSelection,不要直接使用todayInUtcMilliseconds()。
2. 修正选中日期的转换逻辑
拿到返回的UTC时间戳后,先在UTC时区解析出年月日,再赋值给本地时区的Calendar对象进行格式化,避免时区转换导致的日期偏移。
修复后完整代码
public void startDateSelectionPicker() { try { // 计算本地今日对应UTC零点的时间戳,作为默认选中值 Calendar localToday = Calendar.getInstance(); Calendar utcToday = Calendar.getInstance(TimeZone.getTimeZone("UTC")); utcToday.set(localToday.get(Calendar.YEAR), localToday.get(Calendar.MONTH), localToday.get(Calendar.DAY_OF_MONTH), 0, 0, 0); long defaultSelection = utcToday.getTimeInMillis(); MaterialDatePicker<Long> picker = MaterialDatePicker.Builder.datePicker() .setSelection(defaultSelection) .setTheme(R.style.CustomDatePickerDialog) .build(); picker.addOnPositiveButtonClickListener(selection -> { // 先在UTC时区解析选中的年月日 Calendar utcCal = Calendar.getInstance(TimeZone.getTimeZone("UTC")); utcCal.setTimeInMillis(selection); int year = utcCal.get(Calendar.YEAR); int month = utcCal.get(Calendar.MONTH); int day = utcCal.get(Calendar.DAY_OF_MONTH); // 赋值给本地时区Calendar,避免偏移 Calendar localCal = Calendar.getInstance(); localCal.set(year, month, day, 0, 0, 0); String date = ToolsManager.calendarToDate(this, localCal, "yyyy-MM-dd"); }); picker.show(getSupportFragmentManager(), picker.getTag()); } catch (IllegalArgumentException e) { // 建议添加异常捕获日志,方便排查问题 } } // calendarToDate方法无需修改 public static String calendarToDate(Context context, Calendar calendar, String dateFormat) { if (calendar == null) { return null; } Locale locale = context.getResources().getConfiguration().locale; DateFormat df = new SimpleDateFormat(dateFormat, locale); return df.format(calendar.getTime()); }
内容的提问来源于stack exchange,提问作者yozhik
相关产品推荐
相关产品推荐

