You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 02:09:01