Skip to content

Commit 4b172ed

Browse files
committed
HHH-18036 Truncate time-related milliseconds when creating a java.sql.Date
1 parent fda2901 commit 4b172ed

File tree

2 files changed

+39
-9
lines changed

2 files changed

+39
-9
lines changed

hibernate-core/src/main/java/org/hibernate/type/descriptor/java/JdbcDateJavaType.java

+22-9
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ public Object unwrap(Date value, Class type, WrapperOptions options) {
145145
}
146146

147147
if ( java.sql.Timestamp.class.isAssignableFrom( type ) ) {
148-
return new java.sql.Timestamp( value.getTime() );
148+
return new java.sql.Timestamp( unwrapDateEpoch( value ) );
149149
}
150150

151151
if ( java.sql.Time.class.isAssignableFrom( type ) ) {
@@ -158,18 +158,31 @@ public Object unwrap(Date value, Class type, WrapperOptions options) {
158158
private LocalDate unwrapLocalDate(Date value) {
159159
return value instanceof java.sql.Date
160160
? ( (java.sql.Date) value ).toLocalDate()
161-
: new java.sql.Date( value.getTime() ).toLocalDate();
161+
: new java.sql.Date( unwrapDateEpoch( value ) ).toLocalDate();
162162
}
163163

164164
private java.sql.Date unwrapSqlDate(Date value) {
165-
return value instanceof java.sql.Date
166-
? (java.sql.Date) value
167-
: new java.sql.Date( value.getTime() );
165+
if ( value instanceof java.sql.Date ) {
166+
final java.sql.Date sqlDate = (java.sql.Date) value;
167+
final long dateEpoch = toDateEpoch( sqlDate.getTime() );
168+
return dateEpoch == sqlDate.getTime() ? sqlDate : new java.sql.Date( dateEpoch );
169+
}
170+
return new java.sql.Date( unwrapDateEpoch( value ) );
168171

169172
}
170173

171174
private static long unwrapDateEpoch(Date value) {
172-
return value.getTime();
175+
return toDateEpoch( value.getTime() );
176+
}
177+
178+
private static long toDateEpoch(long value) {
179+
Calendar calendar = Calendar.getInstance();
180+
calendar.setTimeInMillis( value );
181+
calendar.set(Calendar.HOUR_OF_DAY, 0);
182+
calendar.clear(Calendar.MINUTE);
183+
calendar.clear(Calendar.SECOND);
184+
calendar.clear(Calendar.MILLISECOND);
185+
return calendar.getTimeInMillis();
173186
}
174187

175188
@Override
@@ -183,15 +196,15 @@ public Date wrap(Object value, WrapperOptions options) {
183196
}
184197

185198
if ( value instanceof Long ) {
186-
return new java.sql.Date( (Long) value );
199+
return new java.sql.Date( toDateEpoch( (Long) value ) );
187200
}
188201

189202
if ( value instanceof Calendar ) {
190-
return new java.sql.Date( ( (Calendar) value ).getTimeInMillis() );
203+
return new java.sql.Date( toDateEpoch( ( (Calendar) value ).getTimeInMillis() ) );
191204
}
192205

193206
if ( value instanceof Date ) {
194-
return new java.sql.Date( ( (Date) value ).getTime() );
207+
return unwrapSqlDate( (Date) value );
195208
}
196209

197210
if ( value instanceof LocalDate ) {

hibernate-core/src/test/java/org/hibernate/orm/test/type/descriptor/java/JdbcDateJavaTypeDescriptorTest.java

+17
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
package org.hibernate.orm.test.type.descriptor.java;
22

33
import java.sql.Date;
4+
import java.time.ZoneOffset;
5+
import java.time.ZonedDateTime;
46

57
import org.hibernate.type.descriptor.java.JdbcDateJavaType;
68

79
import org.hibernate.testing.orm.junit.BaseUnitTest;
10+
import org.hibernate.testing.orm.junit.JiraKey;
811
import org.junit.jupiter.api.Test;
912

1013
import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat;
@@ -32,6 +35,7 @@ public void testIsInstance() {
3235
}
3336

3437
@Test
38+
@JiraKey("HHH-18036")
3539
public void testWrap() {
3640
final JdbcDateJavaType javaType = JdbcDateJavaType.INSTANCE;
3741

@@ -42,5 +46,18 @@ public void testWrap() {
4246
final java.util.Date utilDate = new java.util.Date( 0 );
4347
final java.util.Date wrappedUtilDate = javaType.wrap( utilDate, null );
4448
assertThat( wrappedUtilDate ).isInstanceOf( java.sql.Date.class );
49+
50+
final java.util.Date utilDateWithTime = java.util.Date.from( ZonedDateTime.of(
51+
2000,
52+
1,
53+
1,
54+
12,
55+
0,
56+
0,
57+
0,
58+
ZoneOffset.UTC
59+
).toInstant() );
60+
final java.util.Date wrappedUtilDateWithTime = javaType.wrap( utilDateWithTime, null );
61+
assertThat( wrappedUtilDateWithTime ).isEqualTo( java.sql.Date.valueOf( "2000-01-01" ) );
4562
}
4663
}

0 commit comments

Comments
 (0)