我目前正在开发一个Android应用程序..我必须记录加速计传感器事件坐标和事件时间。我得到了传感器事件时间戳,如“3497855005850”,但我无法将事件时间戳转换为用户可读的日期时间格式。谢谢提前
如何将SensorEvent时间戳转换为unix时间戳?
答案 0 :(得分:35)
传感器时间戳实际上是纳秒的正常运行时间,不是系统时间(以纳秒为单位)。请参阅SensorEvent.timestamp to absolute (utc) timestamp?。
理论上,您可以使用以下方法将传感器时间戳转换为时间(以毫秒为单位)
long timeInMillis = (new Date()).getTime()
+ (sensorEvent.timestamp - System.nanoTime()) / 1000000L;
您甚至可以通过两次(new Date()).getTime()
来电调整System.nanoTime()
来电,并将它们平均以接近实际偏移量。
然后您可以将传感器时间格式化为日期和时间。
答案 1 :(得分:3)
您可以在onSensorChanged(SensorEvent)
功能中设置参考时间变量。
参考当前时间和事件时间。当事件到达时从事件时间中减去传感器指示时间,您将有纳秒的差异。您可以将该差值除以1,000,000添加到当前时间参考,以获得事件时间(以毫秒为单位)
计算此错误可能是一个事件的最大0.5毫秒。您可以通过偶尔更改引用时间来最小化错误。
private long sensorTimeReference = 0l;
private long myTimeReference = 0l;
public void onSensorChanged(SensorEvent event) {
// set reference times
if(sensorTimeReference == 0l && myTimeReference == 0l) {
sensorTimeReference = event.timestamp;
myTimeReference = System.currentTimeMillis();
}
// set event timestamp to current time in milliseconds
event.timestamp = myTimeReference +
Math.round((event.timestamp - sensorTimeReference) / 1000000.0);
// some code...
}
答案 2 :(得分:1)
我遇到了同样的问题,并使用了ehartwell solution。不过我使用的是System.currentTimeMillis()
而不是new Date().getTime()
。
此外,我发现最大300毫秒的sensorEvent.timeStamp
和System.nanoTime()
的偏移量大部分是<1}。 200毫秒。根据所需的准确度,您可以忽略这种差异。
如果我使用Boban S. solution,则初始化时的差异是正确的。但是,测量的正确时间和时间不同。估计的测量时间是将来的。
答案 3 :(得分:1)
我看到三种获得Millis(Kotlin)的方法
val millis = Date().getTime() + (event.timestamp - System.nanoTime()) / 1000000L
val millis = System.currentTimeMillis() + (event.timestamp - System.nanoTime()) / 1000000L
val millis = System.currentTimeMillis() + (event.timestamp - SystemClock.elapsedRealtimeNanos()) / 1000000L
所有三个结果都相同,但是当我想查看从计算值到当前时间的差异
val diff = System.currentTimeMillis() - millis
我看到'diff'的值为 -359704905 吗?
Log.d("diff", "" + event.timestamp + " - " + System.nanoTime())
差异:541695268300000-181990403666592
差异:541695277240000-181990405818592
差异:541695286859000-181990411901592
差异:541695296139000-181990412584592
差异:541695305735000-181990415222592
所以所有建议的解决方案不正确
对我来说,这种简单的方式符合我的需求
override fun onSensorChanged(sensorEvent: SensorEvent?) {
val millis = System.currentTimeMillis()
}
答案 4 :(得分:1)
https://source.android.com/devices/sensors/hal-interface.html#sensors_event_t
“时间戳记必须与经过的RealtimeNano时钟同步”
所以
$('#submit-btn').on('click', function() {
if($('#username').val().length < 6) {
alert("Hey, that username isn't like enough bro");
}
else {
$('form').submit();
}
});
答案 5 :(得分:0)
因设备而异。它可能基于时代,自启动以来的时间以及CPU唤醒时间。最好的方法是先读取所有三个,然后查看时间戳最接近哪个,然后根据偏移量进行转换。
答案 6 :(得分:0)
SensorEvent#timestamp
documentation官方声明:
[event.time是]事件发生的时间(以纳秒为单位)。对于给定的传感器,每个新的传感器事件应使用与SystemClock.elapsedRealtimeNanos()相同的时基单调增加。
挑战
SystemClock.currentTimeNanos()
(例如Nexus 4)。与设备无关的解决方案:
/**
* Calculates the static offset (ms) which needs to
* be added to the `event.time` (ns) to get the Unix
* timestamp of the event.
*
* @param eventTimeNanos the {@code SensorEvent.time} to be used to determine the time offset
* @return the offset in milliseconds
*/
private long eventTimeOffset(final long eventTimeNanos) {
// Capture timestamps of event reporting time
final long elapsedRealTimeMillis = SystemClock.elapsedRealtime();
final long upTimeMillis = SystemClock.uptimeMillis();
final long currentTimeMillis = System.currentTimeMillis();
// Check which timestamp the event.time is closest to the event.time
final long eventTimeMillis = eventTimeNanos / 1_000_000L;
final long elapsedTimeDiff = elapsedRealTimeMillis - eventTimeMillis;
final long upTimeDiff = upTimeMillis - eventTimeMillis;
final long currentTimeDiff = currentTimeMillis - eventTimeMillis;
// Default case (elapsedRealTime, following the documentation)
if (Math.abs(elapsedTimeDiff) <= Math.min(Math.abs(upTimeDiff), Math.abs(currentTimeDiff))) {
final long bootTimeMillis = currentTimeMillis - elapsedRealTimeMillis;
return bootTimeMillis;
}
// Other seen case (currentTime, e.g. Nexus 4)
if (Math.abs(currentTimeDiff) <= Math.abs(upTimeDiff)) {
return 0;
}
// Possible case, but unknown if actually used by manufacturers (upTime)
throw new IllegalStateException("The event.time seems to be upTime. In this case we cannot use a static offset to calculate the Unix timestamp of the event");
}
注册时间延迟
event.time
和触发传感器事件侦听器的时间(注册时间)之间的延迟无关,因为我们仅使用SystemClock
来计算偏移量。关于“可能的情况”(请参见代码):
尚不清楚是否有任何制造商将upTime
用作event.time
。因此,我们抛出异常以查看是否确实发生过这种情况。
如果发生这种情况,并且如果我们计算currentTime
和upTime
之间的静态偏移,则当设备再次进入(深度)睡眠时,这将导致时间偏移。我们需要为每个非常繁重的事件动态计算偏移量。
如果在设备上发生这种情况,可以使用https://developer.android.com/training/monitoring-device-state/doze-standby#testing_doze_and_app_standby
进行测试