我必须得到自1989年12月31日凌晨12:00以来的秒数。 第二个解析器来自Garmin Fleet Management。 这是我的代码:
public int getDate(){
Date d1 = new Date(1989, 12, 31, 12, 0, 0);
Date today = new Date();
long diff = today.getTime() - d1.getTime();
return (int)(diff/1000);
}
Garmin解析器中getDate()的秒数显示为2021年7月28日晚上08:35,而不是现在。
这里(按文档说明)我需要的日期时间
这是一个无符号的32位整数,其值是自1989年12月31日12:00 UTC以来的秒数。
我犯了哪个错误?
答案 0 :(得分:2)
您应该返回long
并将差异换成Math.abs()
,以获得表达差异的正面结果。
public static long getDate() {
Date d1 = new Date(1989, 12, 31, 12, 0, 0);
Date today = new Date();
long diff = Math.abs(today.getTime() - d1.getTime());
return (diff/1000);
}
Java中没有unsigned
。
Morover这个Date
的构造函数已经过时了,所以使用Calendar
是更好的方法:
public static long getDate() {
Calendar d1 = new GregorianCalendar(1989, 11, 31, 0, 0, 0);
Date today = new Date();
long diff = Math.abs(today.getTime() - d1.getTime().getTime());
return (diff/1000);
}
答案 1 :(得分:2)
您应该使用Calendar
实例而不是Date
不推荐使用哪个构造函数:
public static long getDate(){
Calendar calendar = new GregorianCalendar(1989, 11, 31, 0, 0, 0);
Date today = new Date();
long diff = today.getTime() - calendar.getTime().getTime();
return diff / 1000;
}
Date
构造函数接受year
作为(current year value - 1900)
格式。通过Javadoc
:
- @param年度减去1900年。
- @param月份0-11之间。
- @param在1月31日之间的日期。
- @see java.util.Calendar
- @deprecated从JDK 1.1版开始,
- 由
取代Calendar.set(year + 1900, month, date)
- 或
GregorianCalendar(year + 1900, month, date)
。
另外你应该使用long
(Java中没有unsigned int
)返回值
答案 2 :(得分:1)
您正在使用已弃用的API。年份论证不是直接年份,而是从1900年起的年数。
@Deprecated 公共日期(int year, int月, 日期, 小时, int min) 已过时。从JDK版本1.1开始,由Calendar.set(年份+ 1900,月份,日期,小时,分钟)或GregorianCalendar(年份+ 1900,月份,日期,小时,分钟)替换。 分配Date对象并对其进行初始化,使其表示本地时区中年,月,日,小时和分参数指定的分钟开始时刻。 参数: 年 - 减去1900年。
答案 3 :(得分:1)
Duration.between( // Represent a span-of-time unattached to the timeline.
Instant.parse( "1989-12-31T00:00:00Z" ) , // Garmin epoch reference date.
Instant.now() // Capture the current moment in UTC.
) // Returns a `Duration` object.
.toSeconds() // This span-of-time as a total number of whole seconds. Beware of data loss: Any fractional second is ignored.
其他答案使用过时的类。
Java 8及更高版本内置了java.time框架。支持旧的麻烦日期时间类,如java.util.Date
& .Calendar
。
long
vs int
正如其他人提到的,Java没有无符号整数 - 只有签名。所以这里我们使用64位long
而不是32位int
。 Java 8允许您对int
值执行某些操作,而假装它们是无符号的,但我们实际上没有未签名的int
类型。有关详细信息,请参阅此另一个问题Declaring an unsigned int in java,其中包括为Google Guava等库中的无符号整数设计的几个类。
Instant
在java.time中,Instant
是UTC中时间轴上的一个时刻。 Duration
表示一个时间跨度,以秒为单位加上几分之一秒作为纳秒。
不确定“1989年12月31日12:00 12:00”是指当天的第一时刻(00:00:00.0
)还是当天的结束。我将以epoch作为第一时刻。实际上,据Garmin在2004-09-16发表的这份PDF文件Garmin Device Interface Specification指出:
7.3.14 time_type
time_type在某些数据结构中用于指示绝对时间。它是一个无符号的32位整数,其值是自1989年12月31日12:00以来的秒数。
代码。
Instant garminEpoch = Instant.parse( "1989-12-31T00:00:00Z" );
Instant now = Instant.now();
Duration duration = Duration.between( garminEpoch , now );
long seconds = duration.getSeconds(); // This span of time as a total number of seconds.
java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.Date
,Calendar
和& SimpleDateFormat
现在位于Joda-Time的maintenance mode项目建议迁移到java.time类。
要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310。
您可以直接与数据库交换 java.time 对象。使用符合JDBC driver或更高版本的JDBC 4.2。不需要字符串,不需要java.sql.*
类。
从哪里获取java.time类?
ThreeTen-Extra项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如Interval
,YearWeek
,YearQuarter
和more。
答案 4 :(得分:0)
我偶然发现了Garmin的问题,我认为你的日期错误:'1989年12月31日上午12点'从30日到31日是午夜,或者“用军事术语在31日零时,在世界其他地方0:00h!你有中午时间!
此时间参考来自“ Garmin设备接口规范,2006年5月19日,图号:001-00063-00 Rev. C ”,其中包含:
7.3.14 time_type
time_type在某些数据结构中用于指示绝对时间。它是无符号的32位整数及其值 是自UTC时间1989年12月31日凌晨12:00起的秒数。
我不确定这是Garmin特定的还是典型的GPS设备时间问题,因为GPS时间是重要的,例如闰秒分开。至少ina Garmin记录需要构建的UTC时间: 1.上述参考日期 2.闰秒(2018年= 18) 3.拖曳(从星期日0:00h开始的星期几秒) 4.和wn_days(周数天)
总的来说,我的Python3结构是:
tref = time.mktime((1989, 12, 31, 0, 0, 0, 0, 0, -1))
tsec = tref + wn_days * 86400. + tow - leap_scnds
pvttime = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(tsec))
# result: e.g. 2018-02-22 15:09:49 UTC
这给了我正确的UTC时间。