Android:如何从选中的年月日获取星期名称?代码返回结果异常
解决日期计算返回错误星期的问题
哦,这个问题我太熟悉了!你遇到的问题根源在于你用了已经过时的java.util.Date构造函数,它的参数规则特别反直觉,再加上你对月份的处理有误,才导致日期计算偏差,返回了两天前的星期。
问题根源分析
- 年份参数规则错误:
Date(int year, int month, int date)构造函数的年份参数要求是当前年份减去1900,比如2024年需要传2024-1900=124,你直接传picker.Year会导致年份被解析成picker.Year + 1900,日期直接跑到几百年后,星期计算自然出错。 - 月份处理错误:Android的
DatePicker返回的Month本身就是0-based(0代表1月,11代表12月),你额外加1后,月份变成了1-12,而Date构造函数要求月份参数是0-11,这又把日期往后推了一个月,进一步加剧了偏差。 - 旧API的固有缺陷:
SimpleDateFormat和java.util.Date都是线程不安全的,设计上存在诸多不合理之处,很容易引发各种日期时间相关的bug。
解决方案
方案1:临时修复旧代码(不推荐)
如果你只是想临时修复现有代码,可以调整年份和月份的处理逻辑:
DatePicker picker; int date = picker.getDayOfMonth(); int month = picker.getMonth(); // 保持0-based,不要加1 int year = picker.getYear(); SimpleDateFormat simpledateformat = new SimpleDateFormat("EEE"); // 年份需要减去1900,匹配Date构造函数的要求 Date dt = new Date(year - 1900, month, date); String dayOfWeek = simpledateformat.format(dt);
方案2:使用java.time新API(强烈推荐)
Java 8及Android API 26+引入的java.time包彻底解决了旧日期类的问题,它的类不可变、线程安全,设计更直观:
DatePicker picker; int day = picker.getDayOfMonth(); int month = picker.getMonth() + 1; // java.time的月份是1-based int year = picker.getYear(); // 构造本地日期对象 LocalDate localDate = LocalDate.of(year, month, day); // 获取星期枚举,可灵活设置显示样式和语言 DayOfWeek dayOfWeek = localDate.getDayOfWeek(); // SHORT表示缩写(如Mon),FULL表示全称(如Monday),可根据需求调整 String dayName = dayOfWeek.getDisplayName(TextStyle.SHORT, Locale.getDefault());
如果你的项目是Android API 26以下版本,可以通过ThreeTenABP库来使用java.time的功能:
- 在
build.gradle中添加依赖:
implementation 'com.jakewharton.threetenabp:threetenabp:1.4.2'
- 在自定义Application类中初始化:
@Override public void onCreate() { super.onCreate(); AndroidThreeTen.init(this); }
内容的提问来源于stack exchange,提问作者Prachi Karapurkar
相关产品推荐
相关产品推荐

