日历 getTimeInMillis 相差 1 小时

Calendar getTimeInMillis difference of 1 hour

我正在编写一个应用程序,它在 UI 中有一个 DatePicker 和一个 TimePicker。我需要获取用户设置的日期和时间并存储在服务器中。

例如用户选择“2015 年 11 月 13 日 13:00”,并且我的模拟器的时区设置为 GMT+8,返回的 timeInSec 独立于时区的 GMT 应该是“1447390800 ”,结果却是“1447387200”,相差1小时。结束我从服务器收到的显示时间也是错误的。

为什么会这样?与 GMT 时区国家的夏令时有关,或者我在代码中做错了什么?我的国家没有夏令时..

这是我的代码:

Calendar cal = Calendar.getInstance();
cal.set(mDatePicker.getYear(), mDatePicker.getMonth(), mDatePicker.getDayOfMonth(), mTimePicker.getCurrentHour(), mTimePicker.getCurrentMinute(), 0);
// get time in seconds independent of timezone <- update on 2015/11/14: this is wrong!! 
long timezoneOffset = cal.getTimeZone().getOffset(cal.getTimeInMillis());
long timeInSec = ((cal.getTimeInMillis() + timezoneOffset)/1000);

更新

再次查看代码,发现是我的TimePicker给错了值。

如果你想要UTC时间戳你可以直接使用getTimeInMillis()

public long getTimeInMillis()

Returns: the current time as UTC milliseconds from the epoch.

Reference:
http://docs.oracle.com/javase/7/docs/api/java/util/Calendar.html#getTimeInMillis()

例如,将日历日期设置为 13 Nov 2015 13:00,时区为 GMT+8:

Calendar calendar = Calendar.getInstance();
calendar.set(2015, Calendar.NOVEMBER, 13, 13, 0, 0);
int timeInSec = calendar.getTimeInMillis() / 1000;

timeInSec的值为1447390800

编辑

您使用这段代码获得的输出是什么?

Calendar calendar = Calendar.getInstance();
calendar.set(2015, Calendar.NOVEMBER, 13, 13, 0, 0);
int offset = calendar.get(Calendar.ZONE_OFFSET) + calendar.get(Calendar.DST_OFFSET);
long utcTimeInMillis = calendar.getTimeInMillis() + offset;

Calendar utcCalendar = Calendar.getInstance(Locale.ENGLISH);
utcCalendar.setTimeInMillis(utcTimeInMillis);

Log.d(TAG, "Time: " + calendar.getTime());
Log.d(TAG, "TimeInMillis: " + calendar.getTimeInMillis());
Log.d(TAG, "DisplayName: " + calendar.getTimeZone().getDisplayName());
Log.d(TAG, "Offset: " + offset);
Log.d(TAG, "UTC Time: " + utcCalendar.getTime());
Log.d(TAG, "UTC TimeInMillis: " + utcTimeInMillis);

这是我得到的结果:

Time: Fri Nov 13 13:00:00 GMT+08:00 2015
TimeInMillis: 1447390800061
DisplayName: Hong Kong Standard Time
Offset: 28800000
UTC Time: Fri Nov 13 21:00:00 GMT+08:00 2015
UTC TimeInMillis: 1447419600061

(代题作者发表).

问题出在 TimePicker 上。

Calendar.currentTimeMillis() 实际上给出时间 independent 时区(即 UTC)。这 link (Java: Timezone why different timezone give same value in millisec) is so misleading! This should be what you should be looking at: http://docs.oracle.com/javase/7/docs/api/java/util/Calendar.html#getTimeInMillis()

所以我应该这样做:

Calendar cal = Calendar.getInstance();
cal.set(mDatePicker.getYear(), mDatePicker.getMonth(), mDatePicker.getDayOfMonth(), mTimePicker.getCurrentHour(), mTimePicker.getCurrentMinute(), 0);
long timeInSec = (cal.getTimeInMillis()/1000);