【发布时间】:2019-04-24 18:01:34
【问题描述】:
我有一个连接到 java web 服务器的 Arduino 程序,我需要同步时间。但是有一个一小时的同步问题。
这个Java程序的输出:
public class Test {
public static void main(String[] args) {
java.util.Date d = new java.util.Date(2018-1900, 11-1, 22, 05, 48, 10); // 22th Nov 2018, 05:48:10
System.out.println(d);
long t = d.getTime() / 1000;
System.out.println(t);
}
}
是
Thu Nov 22 05:48:10 CET 2018
1542862090
然后,我查看https://www.unixtimestamp.com/
Enter a Timestamp: 1542862090 -> Convert ->
Timestamp Converter: 1542862090 Is equivalent to: 11/22/2018 @ 4:48am (UTC)
为什么我会有这个一小时的差异(05:48 - 4:48)?
相比之下,在 Arduino 中使用 this library 运行等效程序:
#include <RtcDS3231.h>
void setup() {
Serial.begin(115200);
RtcDateTime date = RtcDateTime(2018, 11, 22, 05, 48, 10); // 22th Nov 2018, 05:48:10
uint32_t t = date.Epoch32Time();
Serial.println(t);
}
输出为:1542865690
然后,我查看https://www.unixtimestamp.com/ 输入时间戳:1542865690 -> 转换 ->
Timestamp Converter: 1542865690 Is equivalent to: 11/22/2018 @ 5:48am (UTC)
这看起来是正确的。
问题是java web服务器发送epoch时间(一个长数字)给arduino,arduino重建数据如下,我得到一小时的差:
RtcDateTime date = RtcDateTime(0);
date2.InitWithEpoch32Time(t);
Serial.println(date.Hour()); // 4
如何在 Java 中获得正确的纪元时间,与时区无关? 或者,Java 结果是否正确,而 arduino 库有问题?我错过了什么?
【问题讨论】:
-
05:48:10 CETvs4:48am (UTC)CET != UTC -
也根据 javadocs docs.oracle.com/javase/7/docs/api/java/util/… 在本地时区。顺便说一句,这是一个非常不推荐使用的方法
-
谢谢。问题是
Date.getTime(和System.currentTimeMillis)使用默认系统时区返回纪元时间(在我的例子中是苏黎世)。那个arduino库没有时区的概念(所以,它使用相当于ZoneOffset.UTC)。所以我们需要使用ZoneOffset.UTC显式返回时间。long t = java.time.LocalDateTime.now.atZone(java.time.ZoneOffset.UTC).toInstant.toEpochMilli / 1000 -
改写我上一条评论,我的 java 程序使用
ZoneId.systemDefault计算纪元时间,而 arduino 库使用ZoneOffset.UTC的等效项解析纪元时间。由于该 arduino 库不处理时区,我的解决方案是告诉 java 程序也使用ZoneOffset.UTC。long t = java.time.LocalDateTime.now.atZone(java.time.ZoneOffset.UTC).toInstant.toEpochMilli / 1000 -
永远不要使用
LocalDateTime处理时刻。正是这里使用的 错误 类。