自1989年12月31日凌晨12:00起,Java

时间:2016-03-25 12:09:57

标签: java date garmin

我必须得到自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以来的秒数。

我犯了哪个错误?

5 个答案:

答案 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)

TL;博士

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.time

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中,InstantUTC中时间轴上的一个时刻。 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.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.DateCalendar和& SimpleDateFormat

现在位于Joda-Timemaintenance 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的试验场。您可以在此处找到一些有用的课程,例如IntervalYearWeekYearQuartermore

答案 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时间。