HHH-17229 Test and fix for handling negative milliseconds from java.sql.Time
This commit is contained in:
parent
b21d70ef74
commit
a81fae743c
|
@ -133,10 +133,15 @@ public class JdbcTimeJavaType extends AbstractTemporalJavaType<Date> {
|
|||
? ( (java.sql.Time) value )
|
||||
: new java.sql.Time( value.getTime() % 86_400_000 );
|
||||
final LocalTime localTime = time.toLocalTime();
|
||||
final long millis = time.getTime() % 1000;
|
||||
long millis = time.getTime() % 1000;
|
||||
if ( millis == 0 ) {
|
||||
return localTime;
|
||||
}
|
||||
if ( millis < 0 ) {
|
||||
// The milliseconds for a Time could be negative,
|
||||
// which usually means the time is in a different time zone
|
||||
millis += 1_000L;
|
||||
}
|
||||
return localTime.with( ChronoField.NANO_OF_SECOND, millis * 1_000_000L );
|
||||
}
|
||||
|
||||
|
|
|
@ -136,10 +136,15 @@ public class LocalTimeJavaType extends AbstractTemporalJavaType<LocalTime> {
|
|||
if (value instanceof Time) {
|
||||
final Time time = (Time) value;
|
||||
final LocalTime localTime = time.toLocalTime();
|
||||
final long millis = time.getTime() % 1000;
|
||||
long millis = time.getTime() % 1000;
|
||||
if ( millis == 0 ) {
|
||||
return localTime;
|
||||
}
|
||||
if ( millis < 0 ) {
|
||||
// The milliseconds for a Time could be negative,
|
||||
// which usually means the time is in a different time zone
|
||||
millis += 1_000L;
|
||||
}
|
||||
return localTime.with( ChronoField.NANO_OF_SECOND, millis * 1_000_000L );
|
||||
}
|
||||
|
||||
|
|
|
@ -186,10 +186,15 @@ public class OffsetTimeJavaType extends AbstractTemporalJavaType<OffsetTime> {
|
|||
final OffsetTime offsetTime = time.toLocalTime()
|
||||
.atOffset( getCurrentJdbcOffset( options) )
|
||||
.withOffsetSameInstant( getCurrentSystemOffset() );
|
||||
final long millis = time.getTime() % 1000;
|
||||
long millis = time.getTime() % 1000;
|
||||
if ( millis == 0 ) {
|
||||
return offsetTime;
|
||||
}
|
||||
if ( millis < 0 ) {
|
||||
// The milliseconds for a Time could be negative,
|
||||
// which usually means the time is in a different time zone
|
||||
millis += 1_000L;
|
||||
}
|
||||
return offsetTime.with( ChronoField.NANO_OF_SECOND, millis * 1_000_000L );
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
package org.hibernate.orm.test.type.descriptor.java;
|
||||
|
||||
import java.sql.Time;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalTime;
|
||||
import java.time.ZoneOffset;
|
||||
import java.util.Date;
|
||||
|
||||
import org.hibernate.type.descriptor.java.JavaType;
|
||||
import org.hibernate.type.descriptor.java.JdbcTimeJavaType;
|
||||
import org.hibernate.type.descriptor.java.LocalTimeJavaType;
|
||||
|
||||
import org.hibernate.testing.orm.junit.BaseUnitTest;
|
||||
import org.hibernate.testing.orm.junit.JiraKey;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat;
|
||||
|
||||
@BaseUnitTest
|
||||
public class JdbcTimeJavaTypeDescriptorTest {
|
||||
|
||||
@Test
|
||||
@JiraKey("HHH-17229")
|
||||
public void testUnwrap() {
|
||||
final JavaType<Date> javaType = JdbcTimeJavaType.INSTANCE;
|
||||
|
||||
final Time sqlTime = new Time(
|
||||
LocalDate.EPOCH.atTime( LocalTime.of( 0, 1, 2, 0 ) )
|
||||
.toInstant( ZoneOffset.ofHours( 4 ) )
|
||||
.plusMillis( 123 )
|
||||
.toEpochMilli()
|
||||
);
|
||||
final LocalTime wrappedSqlTime = javaType.unwrap( sqlTime, LocalTime.class, null );
|
||||
assertThat( wrappedSqlTime ).isEqualTo( LocalTime.of( 21, 1, 2, 123_000_000 ) );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
package org.hibernate.orm.test.type.descriptor.java;
|
||||
|
||||
import java.sql.Time;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalTime;
|
||||
import java.time.ZoneOffset;
|
||||
|
||||
import org.hibernate.type.descriptor.java.LocalTimeJavaType;
|
||||
|
||||
import org.hibernate.testing.orm.junit.BaseUnitTest;
|
||||
import org.hibernate.testing.orm.junit.JiraKey;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat;
|
||||
|
||||
@BaseUnitTest
|
||||
public class LocalTimeJavaTypeDescriptorTest {
|
||||
|
||||
@Test
|
||||
@JiraKey("HHH-17229")
|
||||
public void testWrap() {
|
||||
final LocalTimeJavaType javaType = LocalTimeJavaType.INSTANCE;
|
||||
|
||||
final Time sqlTime = new Time(
|
||||
LocalDate.EPOCH.atTime( LocalTime.of( 0, 1, 2, 0 ) )
|
||||
.toInstant( ZoneOffset.ofHours( 4 ) )
|
||||
.plusMillis( 123 )
|
||||
.toEpochMilli()
|
||||
);
|
||||
final LocalTime wrappedSqlTime = javaType.wrap( sqlTime, null );
|
||||
assertThat( wrappedSqlTime ).isEqualTo( LocalTime.of( 21, 1, 2, 123_000_000 ) );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
package org.hibernate.orm.test.type.descriptor.java;
|
||||
|
||||
import java.sql.Time;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalTime;
|
||||
import java.time.OffsetDateTime;
|
||||
import java.time.OffsetTime;
|
||||
import java.time.ZoneOffset;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import org.hibernate.engine.jdbc.LobCreator;
|
||||
import org.hibernate.engine.jdbc.NonContextualLobCreator;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.type.descriptor.WrapperOptions;
|
||||
import org.hibernate.type.descriptor.java.LocalTimeJavaType;
|
||||
import org.hibernate.type.descriptor.java.OffsetTimeJavaType;
|
||||
import org.hibernate.type.descriptor.jdbc.JdbcType;
|
||||
|
||||
import org.hibernate.testing.orm.junit.BaseUnitTest;
|
||||
import org.hibernate.testing.orm.junit.JiraKey;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat;
|
||||
|
||||
@BaseUnitTest
|
||||
public class OffsetTimeJavaTypeDescriptorTest {
|
||||
|
||||
@Test
|
||||
@JiraKey("HHH-17229")
|
||||
public void testWrap() {
|
||||
final OffsetTimeJavaType javaType = OffsetTimeJavaType.INSTANCE;
|
||||
final WrapperOptions wrapperOptions = new WrapperOptions() {
|
||||
@Override
|
||||
public SharedSessionContractImplementor getSession() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SessionFactoryImplementor getSessionFactory() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean useStreamForLobBinding() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPreferredSqlTypeCodeForBoolean() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public LobCreator getLobCreator() {
|
||||
return NonContextualLobCreator.INSTANCE;
|
||||
}
|
||||
|
||||
public JdbcType remapSqlTypeDescriptor(JdbcType sqlTypeDescriptor) {
|
||||
return sqlTypeDescriptor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TimeZone getJdbcTimeZone() {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
final Time sqlTime = new Time(
|
||||
LocalDate.EPOCH.atTime( LocalTime.of( 0, 1, 2, 0 ) )
|
||||
.toInstant( ZoneOffset.ofHours( 4 ) )
|
||||
.plusMillis( 123 )
|
||||
.toEpochMilli()
|
||||
);
|
||||
final OffsetTime wrappedSqlTime = javaType.wrap( sqlTime, wrapperOptions );
|
||||
assertThat( wrappedSqlTime ).isEqualTo( LocalTime.of( 21, 1, 2, 123_000_000 ).atOffset( OffsetDateTime.now().getOffset() ) );
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue