我有一个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);
答案 0 :(得分:4)
我的建议是,您跳过过时的类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编码约定。他们说变量名应该以小写字母开头。
顺便说一句,我认为存储时间戳的公认最佳做法是存储Instant
来自toInstant()
或其字符串表示(来自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());
结果与上述相同。
答案 1 :(得分:0)
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);
}