首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用Java将毫秒转换为TDateTime

用Java将毫秒转换为TDateTime
EN

Stack Overflow用户
提问于 2013-09-18 18:59:07
回答 3查看 1.8K关注 0票数 4

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

我有这样的事情:

代码语言:javascript
复制
Date dateInMillis = new Date(System.currentTimeMillis());
double dateInDouble = ???;

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

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-09-18 20:30:55

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

另一个不同之处是,这两种制度所使用的时代不同。Java使用的Unix时代是1970年1月1日00:00。德尔福时代是1899年12月30日00:00。Unix时代,表示为一个德尔菲TDateTime25569

因此,要将Unix时代的毫秒转换为Delphi时代的天数,可以执行以下计算:

代码语言:javascript
复制
double delphiDateTime = unixMillis/86400000.0 + 25569.0;
票数 10
EN

Stack Overflow用户

发布于 2020-07-21 19:58:51

最近,使用新的date time类发布了Java 8,下面的内容应该可以工作:

代码语言:javascript
复制
LocalDateTime localDateTime = LocalDateTime.of(1899, 12, 30, 0, 0);//Delphi date EPOCH time start
double fraction = val % 1;
long intPart = (long) (val - fraction);
localDateTime = localDateTime.plus(intPart, ChronoUnit.DAYS);
localDateTime = localDateTime.plus((long) (24*60*60*1000 * fraction), ChronoUnit.MILLIS); //fraction is a fraction of the time of day
票数 1
EN

Stack Overflow用户

发布于 2020-07-21 23:58:34

tl;dr

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

代码语言:javascript
复制
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 )。

捕捉世界协调时所看到的当前时刻。

代码语言:javascript
复制
Instant now = Instant.now() ;  

由于某些扭曲历史,作为其时代基准TDateTime类,Delphi使用1899-12-30年的第一时刻,大概在UTC中。对于日期部分,使用LocalDate

代码语言:javascript
复制
LocalDate delphiEpochDate = LocalDate.of( 1899 , Month.DECEMBER , 30 ); // No, not the 31st, the 30th.

epochDate.toString():1899-12-30

作为一种习惯,让java.time确定一天的第一分钟,因为在所有区域的所有日期都不是总是00:00。

代码语言:javascript
复制
Instant delphiEpochMoment = delphiEpochDate.atStartOfDay( ZoneOffset.UTC ).toInstant();

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

德尔福使用了一种从电子表格继承下来的糟糕的时间跟踪方法:使用double浮点小数。

整数部分代表全天,一般的24小时长日,忽略了政治时间的异常。对于这样经过的时间,我们使用Duration

代码语言:javascript
复制
Duration d = Duration.between( delphiEpochMoment , now ) ;
long days = d.toDays() ;  // Generic 24-hour long days.

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

代码语言:javascript
复制
Duration partialDay = d.minusDays( days ) ;

然后将部分金额除以一整天的长度。我们将使用毫秒的分辨率,而不是Duration的纳秒能力,因为德尔福似乎仅限于毫秒。

代码语言:javascript
复制
double millisOfPartialDay = partialDay.toMillis() ;
double millisOfFullDay = Duration.ofDays( 1 ).toMillis() ;
double tempResult = ( millisOfPartialDay / millisOfFullDay ) ;

我们应该将结果截断为毫秒。有关截断double,请参见这个答案。我们应该把所有的天数加起来。

代码语言:javascript
复制
double tempResult = days + ( millisOfPartialDay / millisOfFullDay ) ;
double result = Math.floor( tempResult * 1000 ) / 1000 ;

把这些都放在一起。

代码语言:javascript
复制
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:00Zd=12 1056815H56M10.613011S tempResult = 44033.99734505787结果= 44033.997

警告:,我还没有测试过这段代码。我也不使用德尔菲。所以买家要小心:这个代码值你花的每一分钱。

避免LocalDateTime

注意:不要使用LocalDateTime来表示瞬间。这个类代表一天一天的日期,但缺少时区的上下文或与UTC相抵的内容。例如,以2021年1月23日中午的价值为例。在日本东京是中午吗?还是中午在法国图卢兹?还是中午在美国俄亥俄州的托莱多?那将是三个截然不同的时刻,相隔几个小时。如果缺乏时区,我们不知道打算用哪一种方法。

您可以在德尔福时间跟踪这个特定的问题上避开LocalDateTime,因为德尔福(想必)使用UTC,UTC使用一般的24小时长的工作日,LocalDateTime也是如此。但是从概念上讲,使用LocalDateTime并不适合这个问题,因为我们这里需要一些时间。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18880189

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档