在Java中将毫秒转换为TDateTime

时间:2013-09-18 18:59:07

标签: java android delphi

我在Android项目中需要使用TDateTime类型(Delphi)保存文件。我的日期是毫秒,但我不知道如何将毫秒转换为TDateTime

我有这样的事情:

Date dateInMillis = new Date(System.currentTimeMillis());
double dateInDouble = ???;

我会很高兴有任何提示可以帮助我解决这个问题。

3 个答案:

答案 0 :(得分:9)

德尔福的TDateTime以天为单位测量时间。 Java遵循Unix标准并以毫秒为单位进行测量。要在两者之间进行转换,您需要按照一天中的毫秒数进行缩放86400000

另一个区别是两个系统使用不同的时期。 Java使用的Unix时代是1970年1月1日00:00。德尔福时代是1899年12月30日00:00。以Delphi TDateTime表示的Unix时代是25569

因此,要将从Unix时代的毫秒转换为德尔福时代的天数,请执行以下计算:

double delphiDateTime = unixMillis/86400000.0 + 25569.0;

答案 1 :(得分:1)

最近在Java 8中发布了具有新日期时间类的代码,以下内容应该可以工作:

AND 1 = 1/COALESCE(@processSuccess, 0)

答案 2 :(得分:1)

tl; dr

使用几年前取代Date类的现代 java.time 类。

Duration duration =
        Duration.between(
                LocalDate.of( 1899 , Month.DECEMBER , 30 ).atStartOfDay( ZoneOffset.UTC ).toInstant() ,  // Epoch reference moment used by Delphi.
                Instant.now()  // Current moment as seen in UTC.
        );
double temp =
        // Get a whole number of days (integer ) + a decimal fraction of partial day = a `double` number = the `TDateTime` type in Delphi.
        duration.toDays() +
                (
                        ( double ) duration.minusDays( duration.toDays() ).toMillis()     // Milliseconds in our partial day.
                                /
                                ( double ) Duration.ofDays( 1 ).toMillis()                // Milliseconds in a full day, a generic 24-hour day.
                );
double r = Math.floor( temp * 1000 ) / 1000;  // Truncate to third decimal place to represent a resolution of milliseconds, the limit of `TDateTime` type in Delphi.

java.time

在Java中仅使用现代的 java.time 类,而不使用诸如java.util.Datejava.sql.Date之类的旧类。

按UTC捕获当前时刻。

Instant now = Instant.now() ;  

由于某些twisted history,因为其TDateTime类的epoch reference可能是在UTC中使用了1899-12-30的第一时刻。对于日期部分,请使用LocalDate

LocalDate delphiEpochDate = LocalDate.of( 1899 , Month.DECEMBER , 30 ); // No, not the 31st, the 30th.

epochDate.toString():1899-12-30

作为一种习惯,让 java.time 确定一天的第一时刻,因为在所有区域的所有日期并非总是00:00。

Instant delphiEpochMoment = delphiEpochDate.atStartOfDay( ZoneOffset.UTC ).toInstant();

odt.toString():1899-12-30T00:00Z

Delphi使用一种可怕的方法来跟踪从电子表格继承的时间:使用double浮点分数。

整数部分表示整天,即24小时的普通天,忽略了政治时间的异常情况。对于这样的经过时间,我们使用Duration

Duration d = Duration.between( delphiEpochMoment , now ) ;
long days = d.toDays() ;  // Generic 24-hour long days.

接下来,获取代表一天24小时的一部分的小数部分。首先,我们减去整天的数量,剩下部分时间。

Duration partialDay = d.minusDays( days ) ;

然后将部分金额除以一整天的时间。我们将使用毫秒级的分辨率,而不是Duration的纳秒级能力,因为似乎Delphi限于毫秒级。

double millisOfPartialDay = partialDay.toMillis() ;
double millisOfFullDay = Duration.ofDays( 1 ).toMillis() ;
double tempResult = ( millisOfPartialDay / millisOfFullDay ) ;

我们应该将结果截断为毫秒。有关截断double的信息,请参见this Answer。而且我们应该加上我们的总天数。

double tempResult = days + ( millisOfPartialDay / millisOfFullDay ) ;
double result = Math.floor( tempResult * 1000 ) / 1000 ;

将它们放在一起。

Instant now = Instant.now();

LocalDate delphiEpochDate = LocalDate.of( 1899 , Month.DECEMBER , 30 ); // No, not the 31st, the 30th.
Instant delphiEpochMoment = delphiEpochDate.atStartOfDay( ZoneOffset.UTC ).toInstant();

Duration d = Duration.between( delphiEpochMoment , now );
long days = d.toDays();  // Generic 24-hour long days.

Duration partialDay = d.minusDays( days );

double millisOfPartialDay = partialDay.toMillis();
double millisOfFullDay = Duration.ofDays( 1 ).toMillis();

double tempResult = days + ( millisOfPartialDay / millisOfFullDay );
double result = Math.floor( tempResult * 1000 ) / 1000;  // Truncate to third decimal place to represent a resolution of milliseconds.

System.out.println( "delphiEpochMoment = " + delphiEpochMoment );
System.out.println( "d = " + d );
System.out.println( "tempResult = " + tempResult );
System.out.println( "result = " + result );

delphiEpochMoment = 1899-12-30T00:00:00Z

d = PT1056815H56M10.613011S

tempResult = 44033.99734505787

结果= 44033.997

注意事项:我尚未测试此代码。而且我不使用Delphi。因此,买家要当心:此代码值得您为此付出的每一分钱。

避免使用LocalDateTime

当心:请不要使用LocalDateTime来代表时刻。此类表示带有日期的日期,但缺少时区或UTC偏移量的上下文。例如,以2021年1月23日的正午值为准。在日本东京会是正午吗?还是法国图卢兹中午?还是美国俄亥俄州托莱多的中午?那将是三个非常不同的时刻,相隔几个小时。如果时区不足,我们不知道要使用哪个。

在这个特定的Delphi时间跟踪问题中,您可以摆脱LocalDateTime的困扰,因为Delphi(大概)使用UTC,而UTC与LocalDateTime一样使用24小时通用天。但是从概念上讲,LocalDateTime并不适合解决此问题,因为我们需要一些时间。

Table of date-time types in Java, both modern and legacy