Datetime 在Java中将POSIX时间转换为Joda时间

Datetime 在Java中将POSIX时间转换为Joda时间,datetime,posix,jodatime,Datetime,Posix,Jodatime,在Java中,将POSIX时间戳(如1401793903.3493562(双精度或字符串)转换为JodaDateTime对象的最准确方法是什么 POSIX时间是自1970-01-01以来的秒数,即上述数字对应于(python):datetime.fromtimstamp(1401793903.3493562)=>datetime.datetime(2014,6,3,13,11,43,349356)最简单的方法是转换为毫秒并使用构造函数datetime(long) 最简单的方法是转换为毫秒并使用构

在Java中,将POSIX时间戳(如
1401793903.3493562
(双精度或字符串)转换为Joda
DateTime
对象的最准确方法是什么


POSIX时间是自1970-01-01以来的秒数,即上述数字对应于(python):
datetime.fromtimstamp(1401793903.3493562)
=>
datetime.datetime(2014,6,3,13,11,43,349356)
最简单的方法是转换为毫秒并使用构造函数
datetime(long)


最简单的方法是转换为毫秒并使用构造函数
DateTime(long)

你可以用这个。它从UNIX epoch开始使用毫秒,不计算闰秒,因此它几乎与POSIX时间戳相同。唯一的区别是1000的因数将秒转换为毫秒。我的建议(使用String而不是double有时更精确):

你可以用这个。它从UNIX epoch开始使用毫秒,不计算闰秒,因此它几乎与POSIX时间戳相同。唯一的区别是1000的因数将秒转换为毫秒。我的建议(使用String而不是double有时更精确):



这是POSIX时间——它是自epoch以来的秒数。上面的值实际上是今天的值。所以你的建议行不通。@OlegS。在你们的格式中,什么是点前的数字,什么是点后的数字?据我所知,秒数在点之前,但点之后是什么?在C和Linux中,POSIX时间是自1970-01-01以来的秒数,是点之后的几分之一秒。最接近上述数字对应于爪哇磨坊的表示,即1401793903349356。上面的数字是(python):
datetime.fromtimestamp(1401793903.3493562)
=>
datetime.datetime(2014,6,3,13,11,43,349356)
这是我一直在考虑的解决方案,唯一困扰我的是精度的损失。显然,在Java中,我不能比mills做得更好(至少在Joda中是这样),但我不确定在将双精度转换为长精度的过程中,是否会进一步降低精度。看起来不是,所以看起来不需要像其他地方建议的那样使用
BigDecimal
。你认为呢?这取决于你的用例,以及你开始使用的类型。如果以字符串形式获取值,请使用
BigDecimal
保持精度。如果您以一个
双精度开始,那么您已经失去了可能关心的任何精度,因此当前的答案对您没有任何影响。这是POSIX时间--它是自epoch以来的秒数。上面的值实际上是今天的值。所以你的建议行不通。@OlegS。在你们的格式中,什么是点前的数字,什么是点后的数字?据我所知,秒数在点之前,但点之后是什么?在C和Linux中,POSIX时间是自1970-01-01以来的秒数,是点之后的几分之一秒。最接近上述数字对应于爪哇磨坊的表示,即1401793903349356。上面的数字是(python):
datetime.fromtimestamp(1401793903.3493562)
=>
datetime.datetime(2014,6,3,13,11,43,349356)
这是我一直在考虑的解决方案,唯一困扰我的是精度的损失。显然,在Java中,我不能比mills做得更好(至少在Joda中是这样),但我不确定在将双精度转换为长精度的过程中,是否会进一步降低精度。看起来不是,所以看起来不需要像其他地方建议的那样使用
BigDecimal
。你认为呢?这取决于你的用例,以及你开始使用的类型。如果以字符串形式获取值,请使用
BigDecimal
保持精度。如果你从一个
double
开始,你已经失去了你可能关心的任何精度,因此当前的答案不会对你造成任何伤害。在这里使用
BigDecimal
或者如果double可以容纳15位数字(至少在接下来的几十年中),使用
String
作为初始表示形式的实际好处是什么优于Java提供的毫秒精度。在某个时刻,POSIX时间戳将变得不如长毫秒那么精确,但这离现在还有大约一个世纪:)@OlegS。这是一个正确的观点
double
可能就足够了,尽管我不能完全确定它是否适用于每个时间戳(double不能正确表示某些值)。首先,我只看到了你希望的“最准确的方式”和基于
SimpleDateFormat
的答案,所以我的答案是快速反应(至少没有错)。是的,你的答案是正确的,所以+1。POSIX时间通常在C或python中以双精度值的形式返回,因此除此之外没有什么需要改进的地方。转换为long我一直认为是个问题,但实际上并不是因为乘以1e3不会改变双重代表的意义。否则,正如我现在所说,POSIX时间比基于Joda millis的精确得多,精确了4个数量级,但随着时间的推移,这种情况会发生变化by@OlegS. 请记住,
double
是一个浮点数。例如,测试值
0.1d
“0.1”
。您将看到远分数部分的细微差别(如果您将时间戳用于如此精细的分数)。当然,但由于比Java millis表示法(现在)精确4个数量级,我可能可以牺牲最后一个数字而不影响结果,我可以吗?在这里使用
BigDecimal
,或者在double可以容纳15位数字的情况下使用
String
作为初始表示法的实际好处是什么(至少在接下来的几十年中)比Java提供的毫秒精度更好。在某个时刻,POSIX时间戳将变得不如长毫秒那么精确,但这离现在还有大约一个世纪:)@OlegS。这是一个正确的观点
  double posixTimestamp = 1401793903.3493562;
  long millis = (long) posixTimestamp * 1000;
  DateTime date = new DateTime(millis);
double timestamp = 1401793903.3493562; // in seconds
BigDecimal bd = new BigDecimal(timestamp);

// transform to milliseconds
bd = bd.multiply(new BigDecimal(1000)).setScale(0, RoundingMode.HALF_UP);

// create Joda object
DateTime dt = new DateTime(bd.longValue());

System.out.println(bd); // 1401793903349
System.out.println(dt); // 2014-06-03T13:11:43.349+02:00 (in my timezone)