【问题标题】:how to get GMT timestamp from DatePicker?如何从 DatePicker 获取 GMT 时间戳?
【发布时间】:2026-01-05 09:40:02
【问题描述】:

我有一个DatePicker 元素(“DPstart”)。
我想将午夜的timestamp(以毫秒为单位)保存在字符串“newStartDate”中,不考虑用户的时区。
我该怎么做?

DatePicker DPstart = (DatePicker) findViewById(R.id.datePickerStart);
Calendar calendar = new GregorianCalendar(DPstart.getYear(), DPstart.getMonth(), DPstart.getDayOfMonth());
long DPS = calendar.getTimeInMillis();
String newStartDate = Long.toString(DPS);

【问题讨论】:

标签: java android datepicker timestamp epoch


【解决方案1】:

ThreeTenABP

我的建议是你跳过过时的 CalendarGregorianCalendar 类,开始使用现代 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-04InstantLocalDate 的字符串表示形式均符合 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());

结果同上。

【讨论】:

    【解决方案2】:
    public Long timestampFromString(String format,String time){
            // format example "yyyy.MM.dd hh:mm"
            DateFormat formatter = new SimpleDateFormat(format);
            Date date = null;
            try {
                date = formatter.parse(time);
                return date.getTime();
            } catch (ParseException e) {
                e.printStackTrace();
            }
            return null;
        }
        public String stringFromTimestamp(String format,Long time){
            Timestamp timestamp = new Timestamp(time);
            return new SimpleDateFormat(format).format(timestamp);
        }
    

    【讨论】:

    • 感谢您的贡献。三点:(1)请不要教年轻人使用陈旧过时且臭名昭著的SimpleDateFormat类。至少不是第一选择。而且不是没有任何保留。今天我们在java.time, the modern Java date and time API, 和它的DateTimeFormatter 中做得更好。是的,您可以在 Android 上使用它。对于较旧的 Android,请参阅 How to use ThreeTenABP in Android Project。 ——
    • — (2) 好像它在回答一个不同的问题,不是吗? (3) 请在你的答案中附上一些解释。代码是如何工作的,尤其是它是如何回答问题的(如果是的话:-)这是我们都从解释中学到的。