ThreeTenABP
我的建议是你跳过过时的 Calendar 和 GregorianCalendar 类,开始使用现代 Java 日期和时间 API。使用起来要好得多。即使DatePicker 返回值是为与旧类一起使用而设计的。即使现代 API 还没有在很多 Android 手机上原生(这将会到来)。
您需要获得the ThreeTenABP library。有用的问题:How to use ThreeTenABP in Android Project。那么你的代码可以是这样的:
long dps = LocalDate.of(dpStart.getYear(), Month.values()[dpStart.getMonth()],
dpStart.getDayOfMonth())
.atStartOfDay(ZoneOffset.UTC)
.toInstant()
.toEpochMilli();
String newStartDate = Long.toString(dps);
选择 2017 年 9 月 4 日,结果将是1504483200000。
我将日期选择器的基于 0 的月份转换为 LocalDate 更人性化的基于 1 的月份的方式有点奇怪。如果您发现添加 1 更简单,那也可以:
long dps = LocalDate.of(dpStart.getYear(), dpStart.getMonth() + 1, dpStart.getDayOfMonth())
// …
我已重命名您的变量以符合 Java 编码约定。他们说变量名应该以小写字母开头。
顺便说一句,我认为存储时间戳的公认最佳做法是存储从toInstant() 获得的Instant 或其字符串表示形式(来自toString()),而不是毫秒值。对于我们大多数人来说,毫秒值很难解释,例如当我们在调试器中看到它们时。 Instant 的值很容易理解,至少大致上它们指的是什么时间。更好的人类可读格式是LocalDate 的字符串表示,它看起来像2017-09-04。 Instant 和 LocalDate 的字符串表示形式均符合 ISO 8601。
过时的解决方案
如果您绝对不想依赖像 ThreeTenABP 这样的第三方库,即使是暂时的直到现代日期和时间 API 出现在 Android 上,我相信 Calendar 的解决方案是 (1) 确保它使用 UTC时区 (2) 清除小时、分钟、秒和毫秒以确保您获得午夜的时间:
Calendar calendar = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
calendar.clear();
calendar.set(dpStart.getYear(), dpStart.getMonth(), dpStart.getDayOfMonth());
结果同上。