Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/ant/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
不同环境下测试中的Java OffsetDateTime精度问题_Java_H2_Spock - Fatal编程技术网

不同环境下测试中的Java OffsetDateTime精度问题

不同环境下测试中的Java OffsetDateTime精度问题,java,h2,spock,Java,H2,Spock,我正在Spock中运行测试,尝试比较两个OffsetDateTime对象。测试与H2数据库集成。我的实体名为Beacon,它具有创建时间属性。这是实体: @Entity @Table(name = "beacons") @Getter @Setter public class Beacon { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id

我正在Spock中运行测试,尝试比较两个OffsetDateTime对象。测试与H2数据库集成。我的实体名为Beacon,它具有创建时间属性。这是实体:

@Entity
@Table(name = "beacons")
@Getter
@Setter
public class Beacon {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Integer id;

    private OffsetDateTime creationTime;
}
然后,在Spock测试中,我执行以下操作:创建新的Beacon对象:

def beacon = new Beacon(
        id: id,
        creationTime: OffsetDateTime.now()
)
然后我将Beacon对象保存在数据库中,获取它并比较CreationTime:

beaconRepository.save(beacon)
def savedBeacon = beaconRepository.findById(id)
beacon.getCreationTime() == savedBeacon.getCreationTime()

现在,在Unix和MacOS上,一切都正常工作,而在Windows上,此测试失败,因为savedBeacon.getCreationTime()返回的时间比beacon.getCreationTime()更精确。为什么会这样?当然,我知道一些解决方法,比如将creationTime定义为OffsetDateTime.now(Clock.tickMillis(ZoneId.systemDefault()),但有没有更好的解决方案?

我建议使用,因为它比较了日期的表示形式,这才是您真正的目标。

您的列在数据库中是如何定义的?它应该具有带时区的时间戳(9),否则值将四舍五入到微秒

SQL标准要求
时间戳
时区时间戳
数据类型的默认分数秒精度为6

Java 8中的各种
.now()
方法最多返回3个小数位数。由于Java 9,它们通常返回6或7位数,具体取决于操作系统,将来可能会返回更多位数(例如,在Linux上,可以使用9位数,但Java目前只使用6位数)


JSR-310数据类型最多支持9位数字。一些数据库管理系统(包括H2)也支持多达9位数字(很少有数据库支持更多数字)。但其他一些DBMS最多只支持6位数字。

您的“解决方法”正是您应该如何做到这一点。为什么你认为这不是一个足够好的解决方案?我认为这可能是一些溢出…编辑你的问题,报告在你的每台计算机上部署了什么版本的Java:
System.getProperty(“Java.version”)
。我相信这不会改变结果——对象的精度不同,因此isEqual也会返回false。请查看isEqual()的源代码,它会回答您的问题。扰流器-它统一了感知。精确性的统一在哪里
public boolean isEqual(OffsetDateTime other){return ToepochsSecond()==other.ToepochsSecond()&&toLocalTime().getNano()==other.toLocalTime().getNano();}
将只返回
0
,而另一个Timeamp将返回与
0
不同的内容,所以wojtekt说,它对您没有帮助。您必须反过来,将另一个时间戳截断到相同的精度。如果一个时间戳的精度只有毫秒/微秒,则基本原理也适用。