我们知道,计算机的时间是从1970年开始的,而java获取时间的方法System.currentTimeMillis()的返回值也是从0开始的,0就代表1970年一月一日。
那么这个如果值为负数会怎么样?1969年?
今天在读SystemServer源码的时候看到其中run方法修复时间的一段。它是这么处理的。
// If a device's clock is before 1970 (before 0), a lot of
// APIs crash dealing with negative numbers, notably
// java.io.File#setLastModified, so instead we fake it and
// hope that time from cell towers or NTP fixes it shortly.
if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
Slog.w(TAG, "System clock is before 1970; setting to 1970.");
SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
}
也就是手机的时钟可能是小于1970年的,但如果小于这个值的话java.io.File#setLastModified则会引起崩溃,因此android源码在这里加了个判断,如果时间小于1970,则把时间设置为1970年。。(注释是说1970年,但实际上拿EARLIEST_SUPPORTED_TIME
这个时间戳计算是1972/9/27 8:0:0,不知道为什么是这个时间,难道这就是口是心非??)
具体就是:
// The earliest supported time. We pick one day into 1970, to
// give any timezone code room without going into negative time.
private static final long EARLIEST_SUPPORTED_TIME = 86400 * 1000;
实现设置CurrentTimeMillis的代码:
/**
* Sets the current wall time, in milliseconds. Requires the calling
* process to have appropriate permissions.
*
* @return if the clock was successfully set to the specified time.
*/
public static boolean setCurrentTimeMillis(long millis) {
IBinder b = ServiceManager.getService(Context.ALARM_SERVICE);
IAlarmManager mgr = IAlarmManager.Stub.asInterface(b);
if (mgr == null) {
return false;
}
try {
return mgr.setTime(millis);
} catch (RemoteException e) {
Slog.e(TAG, "Unable to set RTC", e);
} catch (SecurityException e) {
Slog.e(TAG, "Unable to set RTC", e);
}
return false;
}
关键的就是mgr.setTime(millis);
设置了时间
public boolean setTime(long millis) throws RemoteException {
Parcel _data = Parcel.obtain();
Parcel _reply = Parcel.obtain();
boolean _result;
try {
_data.writeInterfaceToken("android.app.IAlarmManager");
_data.writeLong(millis);
this.mRemote.transact(2, _data, _reply, 0);
_reply.readException();
_result = 0 != _reply.readInt();
} finally {
_reply.recycle();
_data.recycle();
}
return _result;
}