2

我需要解析自定义定义的日期格式,该格式在我需要通信的设备中定义,其中日期以从 2000 年开始计算的秒数给出。

我试图用来GregorianCalendar解析这些数据,这是我试过的代码:

    GregorianCalendar calendar = new GregorianCalendar();
    calendar.setGregorianChange(new Date(2000 - 1900, 0, 1));

Date对象对应于 2000 年 1 月 1 日。我认为有了这个我setTimeInMillis可以得到正确的日期乘以我读到的时间1000,因为它是以秒而不是以毫秒为单位计算的GregorianCalendar,但它不起作用。我试过setTimeInMillis(0)了,等待对应的时间对应于calendar2000 年 1 月 1 日,但它没有,它对应于 1969 年 12 月 18 日。

我怎样才能配置GregorianCalendar,所以我可以setTimeInMillis(0),它对应于 2000 年 1 月 1 日?如果不可能,我可以使用任何其他类来代替自己创建所有代码吗?

提前致谢。

4

5 回答 5

2

创建一个日期为 2000/01/01 并以毫秒为单位获取时间,然后从您的设备获取以毫秒为单位的时间。将两者相加,并根据您的心愿创建日期和日历...

于 2012-12-13T10:19:16.903 回答
2

setGregorianChange只会改变从儒略到格里高利的转换发生的时间点。它默认为正确的历史值。

但是由于几乎所有其他人都在使用预测公历,所以这个函数有一个有效的用例:

setGregorianChange(new Date(Long.MIN_VALUE)) //Julian never happened

这也是 JodaTime 默认使用的。

无论如何,您可以946684800000L从正常的毫秒 unix 时间戳中减去,然后除以 1000:

public static long secondsSince2000(Date input) {
    final long epoch = 946684800000L;
    return (input.getTime() - epoch) / 1000L;
}

从 2000 年以来的秒数转换:

public static Calendar fromSecondsSince2000( long seconds ) {
    final long epoch = 946684800000L;
    Calendar cal = GregorianCalendar.getInstance();
    long timestamp = epoch + seconds * 1000L;
    cal.setTime(new Date(timestamp));
    return cal;
}

要查看两者都在工作:

    long sec = secondsSince2000(new Date());
    Calendar cal = fromSecondsSince2000( sec );
    System.out.println(cal.getTime().toString().equals(new Date().toString()));

他们应该打印true

于 2012-12-13T11:31:38.390 回答
1

您正在使用不推荐使用的构造函数Date。此外,您使用它的方式错误。

它应该是 GregorianCalendar(year + 1900, month, date)。根据Oracle 文档

顺便说一句,为什么不使用JodaTime?然后你会得到很多方便的东西:

DateTime dt = new DateTime(year, monthOfYear, dayOfMonth, hourOfDay, minuteOfHour);
于 2012-12-13T10:24:06.397 回答
0

您要做的是更改 Epoch,默认为 2000/01/01(Unix 时间戳)。所以你想要的只是一种以 2000/01/01 作为 Epoch 的 Unix 时间戳。

我会以 2000/01/01 的毫秒为单位获取 unix 时间戳,并将其保存为常量。现在,子类 GregorianCalendar 以便您可以从输入数据中添加这些毫秒并返回正确的日期。

也许你也可以看看JSR-310

于 2012-12-13T10:23:05.050 回答
0

这会做

Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("America/Los_Angeles")); // change the timezone as you wish
cal.set(Calendar.YEAR, 2000);
cal.set(Calendar.MONTH, 0);
cal.set(Calendar.DATE, 1);   
cal.set(Calendar.HOUR, 00);
cal.set(Calendar.MINUTE, 00);
cal.set(Calendar.SECOND, 00);
cal.set(Calendar.MILLISECOND, 00);

cal.add(Calendar.MILLISECOND, 1000); // calculate and add your millisec here where 1000 is added 
于 2012-12-13T10:36:02.687 回答