Fix temporal round in tests and render calendar with milliseconds precision

This commit is contained in:
Christian Beikov 2022-12-08 12:29:42 +01:00
parent 7376a1cdfb
commit a9be2e1584
17 changed files with 248 additions and 86 deletions

View File

@ -94,6 +94,7 @@ import static org.hibernate.type.descriptor.DateTimeUtils.appendAsDate;
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsLocalTime; import static org.hibernate.type.descriptor.DateTimeUtils.appendAsLocalTime;
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTime; import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTime;
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTimestampWithMicros; import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTimestampWithMicros;
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTimestampWithMillis;
/** /**
* A {@linkplain Dialect SQL dialect} for CockroachDB. * A {@linkplain Dialect SQL dialect} for CockroachDB.
@ -646,7 +647,7 @@ public class CockroachLegacyDialect extends Dialect {
break; break;
case TIMESTAMP: case TIMESTAMP:
appender.appendSql( "timestamp with time zone '" ); appender.appendSql( "timestamp with time zone '" );
appendAsTimestampWithMicros( appender, calendar, jdbcTimeZone ); appendAsTimestampWithMillis( appender, calendar, jdbcTimeZone );
appender.appendSql( '\'' ); appender.appendSql( '\'' );
break; break;
default: default:

View File

@ -106,6 +106,7 @@ import static org.hibernate.type.descriptor.DateTimeUtils.appendAsDate;
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsLocalTime; import static org.hibernate.type.descriptor.DateTimeUtils.appendAsLocalTime;
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTime; import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTime;
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTimestampWithMicros; import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTimestampWithMicros;
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTimestampWithMillis;
/** /**
* A legacy {@linkplain Dialect SQL dialect} for H2. * A legacy {@linkplain Dialect SQL dialect} for H2.
@ -536,7 +537,7 @@ public class H2LegacyDialect extends Dialect {
break; break;
case TIMESTAMP: case TIMESTAMP:
appender.appendSql( "timestamp with time zone '" ); appender.appendSql( "timestamp with time zone '" );
appendAsTimestampWithMicros( appender, calendar, jdbcTimeZone ); appendAsTimestampWithMillis( appender, calendar, jdbcTimeZone );
appender.appendSql( '\'' ); appender.appendSql( '\'' );
break; break;
default: default:

View File

@ -133,6 +133,7 @@ import static org.hibernate.type.descriptor.DateTimeUtils.appendAsDate;
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsLocalTime; import static org.hibernate.type.descriptor.DateTimeUtils.appendAsLocalTime;
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTime; import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTime;
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTimestampWithMicros; import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTimestampWithMicros;
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTimestampWithMillis;
/** /**
* A {@linkplain Dialect SQL dialect} for PostgreSQL 8 and above. * A {@linkplain Dialect SQL dialect} for PostgreSQL 8 and above.
@ -1119,7 +1120,7 @@ public class PostgreSQLLegacyDialect extends Dialect {
break; break;
case TIMESTAMP: case TIMESTAMP:
appender.appendSql( "timestamp with time zone '" ); appender.appendSql( "timestamp with time zone '" );
appendAsTimestampWithMicros( appender, calendar, jdbcTimeZone ); appendAsTimestampWithMillis( appender, calendar, jdbcTimeZone );
appender.appendSql( '\'' ); appender.appendSql( '\'' );
break; break;
default: default:

View File

@ -86,6 +86,7 @@ import static org.hibernate.type.SqlTypes.*;
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsDate; import static org.hibernate.type.descriptor.DateTimeUtils.appendAsDate;
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTime; import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTime;
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTimestampWithMicros; import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTimestampWithMicros;
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTimestampWithMillis;
/** /**
* A dialect for Microsoft SQL Server 2000 and above * A dialect for Microsoft SQL Server 2000 and above
@ -924,7 +925,7 @@ public class SQLServerLegacyDialect extends AbstractTransactSQLDialect {
break; break;
case TIMESTAMP: case TIMESTAMP:
appender.appendSql( "cast('" ); appender.appendSql( "cast('" );
appendAsTimestampWithMicros( appender, calendar, jdbcTimeZone ); appendAsTimestampWithMillis( appender, calendar, jdbcTimeZone );
appender.appendSql( "' as datetime2)" ); appender.appendSql( "' as datetime2)" );
break; break;
default: default:

View File

@ -83,6 +83,7 @@ import static org.hibernate.type.SqlTypes.VARBINARY;
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsDate; import static org.hibernate.type.descriptor.DateTimeUtils.appendAsDate;
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTime; import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTime;
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTimestampWithMicros; import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTimestampWithMicros;
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTimestampWithMillis;
/** /**
* An SQL dialect for SQLite. * An SQL dialect for SQLite.
@ -713,7 +714,7 @@ public class SQLiteDialect extends Dialect {
break; break;
case TIMESTAMP: case TIMESTAMP:
appender.appendSql( "datetime(" ); appender.appendSql( "datetime(" );
appendAsTimestampWithMicros( appender, calendar, jdbcTimeZone ); appendAsTimestampWithMillis( appender, calendar, jdbcTimeZone );
appender.appendSql( ')' ); appender.appendSql( ')' );
break; break;
default: default:

View File

@ -104,6 +104,7 @@ import static org.hibernate.type.descriptor.DateTimeUtils.appendAsDate;
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsLocalTime; import static org.hibernate.type.descriptor.DateTimeUtils.appendAsLocalTime;
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTime; import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTime;
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTimestampWithMicros; import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTimestampWithMicros;
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTimestampWithMillis;
/** /**
* A {@linkplain Dialect SQL dialect} for CockroachDB. * A {@linkplain Dialect SQL dialect} for CockroachDB.
@ -664,7 +665,7 @@ public class CockroachDialect extends Dialect {
break; break;
case TIMESTAMP: case TIMESTAMP:
appender.appendSql( "timestamp with time zone '" ); appender.appendSql( "timestamp with time zone '" );
appendAsTimestampWithMicros( appender, calendar, jdbcTimeZone ); appendAsTimestampWithMillis( appender, calendar, jdbcTimeZone );
appender.appendSql( '\'' ); appender.appendSql( '\'' );
break; break;
default: default:

View File

@ -229,6 +229,7 @@ import static org.hibernate.type.descriptor.DateTimeUtils.JDBC_ESCAPE_START_TIME
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsDate; import static org.hibernate.type.descriptor.DateTimeUtils.appendAsDate;
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTime; import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTime;
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTimestampWithMicros; import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTimestampWithMicros;
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTimestampWithMillis;
/** /**
* Represents a dialect of SQL implemented by a particular RDBMS. Every * Represents a dialect of SQL implemented by a particular RDBMS. Every
@ -4380,7 +4381,7 @@ public abstract class Dialect implements ConversionContext {
break; break;
case TIMESTAMP: case TIMESTAMP:
appender.appendSql( JDBC_ESCAPE_START_TIMESTAMP ); appender.appendSql( JDBC_ESCAPE_START_TIMESTAMP );
appendAsTimestampWithMicros( appender, calendar, jdbcTimeZone ); appendAsTimestampWithMillis( appender, calendar, jdbcTimeZone );
appender.appendSql( JDBC_ESCAPE_END ); appender.appendSql( JDBC_ESCAPE_END );
break; break;
default: default:

View File

@ -96,6 +96,7 @@ import static org.hibernate.type.descriptor.DateTimeUtils.appendAsDate;
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsLocalTime; import static org.hibernate.type.descriptor.DateTimeUtils.appendAsLocalTime;
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTime; import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTime;
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTimestampWithMicros; import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTimestampWithMicros;
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTimestampWithMillis;
/** /**
* A {@linkplain Dialect SQL dialect} for H2. * A {@linkplain Dialect SQL dialect} for H2.
@ -514,7 +515,7 @@ public class H2Dialect extends Dialect {
break; break;
case TIMESTAMP: case TIMESTAMP:
appender.appendSql( "timestamp with time zone '" ); appender.appendSql( "timestamp with time zone '" );
appendAsTimestampWithMicros( appender, calendar, jdbcTimeZone ); appendAsTimestampWithMillis( appender, calendar, jdbcTimeZone );
appender.appendSql( '\'' ); appender.appendSql( '\'' );
break; break;
default: default:

View File

@ -119,6 +119,7 @@ import static org.hibernate.type.descriptor.DateTimeUtils.appendAsDate;
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsLocalTime; import static org.hibernate.type.descriptor.DateTimeUtils.appendAsLocalTime;
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTime; import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTime;
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTimestampWithMicros; import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTimestampWithMicros;
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTimestampWithMillis;
/** /**
* A {@linkplain Dialect SQL dialect} for PostgreSQL 8 and above. * A {@linkplain Dialect SQL dialect} for PostgreSQL 8 and above.
@ -1104,7 +1105,7 @@ public class PostgreSQLDialect extends Dialect {
break; break;
case TIMESTAMP: case TIMESTAMP:
appender.appendSql( "timestamp with time zone '" ); appender.appendSql( "timestamp with time zone '" );
appendAsTimestampWithMicros( appender, calendar, jdbcTimeZone ); appendAsTimestampWithMillis( appender, calendar, jdbcTimeZone );
appender.appendSql( '\'' ); appender.appendSql( '\'' );
break; break;
default: default:

View File

@ -103,6 +103,7 @@ import static org.hibernate.type.SqlTypes.VARCHAR;
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsDate; import static org.hibernate.type.descriptor.DateTimeUtils.appendAsDate;
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTime; import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTime;
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTimestampWithMicros; import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTimestampWithMicros;
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTimestampWithMillis;
/** /**
* A dialect for Microsoft SQL Server 2008 and above * A dialect for Microsoft SQL Server 2008 and above
@ -932,7 +933,7 @@ public class SQLServerDialect extends AbstractTransactSQLDialect {
break; break;
case TIMESTAMP: case TIMESTAMP:
appender.appendSql( "cast('" ); appender.appendSql( "cast('" );
appendAsTimestampWithMicros( appender, calendar, jdbcTimeZone ); appendAsTimestampWithMillis( appender, calendar, jdbcTimeZone );
appender.appendSql( "' as datetime2)" ); appender.appendSql( "' as datetime2)" );
break; break;
default: default:

View File

@ -14,12 +14,14 @@ import java.time.LocalTime;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder; import java.time.format.DateTimeFormatterBuilder;
import java.time.temporal.ChronoField; import java.time.temporal.ChronoField;
import java.time.temporal.Temporal;
import java.time.temporal.TemporalAccessor; import java.time.temporal.TemporalAccessor;
import java.util.Calendar; import java.util.Calendar;
import java.util.Date; import java.util.Date;
import java.util.Locale; import java.util.Locale;
import java.util.TimeZone; import java.util.TimeZone;
import org.hibernate.dialect.Dialect;
import org.hibernate.sql.ast.spi.SqlAppender; import org.hibernate.sql.ast.spi.SqlAppender;
import static java.time.format.DateTimeFormatter.ISO_LOCAL_DATE; import static java.time.format.DateTimeFormatter.ISO_LOCAL_DATE;
@ -41,8 +43,10 @@ public final class DateTimeUtils {
public static final String FORMAT_STRING_TIMESTAMP = "yyyy-MM-dd HH:mm:ss"; public static final String FORMAT_STRING_TIMESTAMP = "yyyy-MM-dd HH:mm:ss";
public static final String FORMAT_STRING_TIMESTAMP_WITH_MILLIS = FORMAT_STRING_TIMESTAMP + ".SSS"; public static final String FORMAT_STRING_TIMESTAMP_WITH_MILLIS = FORMAT_STRING_TIMESTAMP + ".SSS";
public static final String FORMAT_STRING_TIMESTAMP_WITH_MICROS = FORMAT_STRING_TIMESTAMP + ".SSSSSS"; public static final String FORMAT_STRING_TIMESTAMP_WITH_MICROS = FORMAT_STRING_TIMESTAMP + ".SSSSSS";
public static final String FORMAT_STRING_TIMESTAMP_WITH_NANOS = FORMAT_STRING_TIMESTAMP + ".SSSSSSSSS";
public static final String FORMAT_STRING_TIMESTAMP_WITH_MILLIS_AND_OFFSET = FORMAT_STRING_TIMESTAMP_WITH_MILLIS + "XXX"; public static final String FORMAT_STRING_TIMESTAMP_WITH_MILLIS_AND_OFFSET = FORMAT_STRING_TIMESTAMP_WITH_MILLIS + "XXX";
public static final String FORMAT_STRING_TIMESTAMP_WITH_MICROS_AND_OFFSET = FORMAT_STRING_TIMESTAMP_WITH_MICROS + "XXX"; public static final String FORMAT_STRING_TIMESTAMP_WITH_MICROS_AND_OFFSET = FORMAT_STRING_TIMESTAMP_WITH_MICROS + "XXX";
public static final String FORMAT_STRING_TIMESTAMP_WITH_NANOS_AND_OFFSET = FORMAT_STRING_TIMESTAMP_WITH_NANOS + "XXX";
public static final DateTimeFormatter DATE_TIME_FORMATTER_DATE = DateTimeFormatter.ofPattern( FORMAT_STRING_DATE, Locale.ENGLISH ); public static final DateTimeFormatter DATE_TIME_FORMATTER_DATE = DateTimeFormatter.ofPattern( FORMAT_STRING_DATE, Locale.ENGLISH );
public static final DateTimeFormatter DATE_TIME_FORMATTER_TIME_WITH_OFFSET = DateTimeFormatter.ofPattern( FORMAT_STRING_TIME_WITH_OFFSET, Locale.ENGLISH ); public static final DateTimeFormatter DATE_TIME_FORMATTER_TIME_WITH_OFFSET = DateTimeFormatter.ofPattern( FORMAT_STRING_TIME_WITH_OFFSET, Locale.ENGLISH );
@ -55,6 +59,10 @@ public final class DateTimeUtils {
FORMAT_STRING_TIMESTAMP_WITH_MICROS, FORMAT_STRING_TIMESTAMP_WITH_MICROS,
Locale.ENGLISH Locale.ENGLISH
); );
public static final DateTimeFormatter DATE_TIME_FORMATTER_TIMESTAMP_WITH_NANOS = DateTimeFormatter.ofPattern(
FORMAT_STRING_TIMESTAMP_WITH_NANOS,
Locale.ENGLISH
);
public static final DateTimeFormatter DATE_TIME_FORMATTER_TIMESTAMP_WITH_MILLIS_AND_OFFSET = DateTimeFormatter.ofPattern( public static final DateTimeFormatter DATE_TIME_FORMATTER_TIMESTAMP_WITH_MILLIS_AND_OFFSET = DateTimeFormatter.ofPattern(
FORMAT_STRING_TIMESTAMP_WITH_MILLIS_AND_OFFSET, FORMAT_STRING_TIMESTAMP_WITH_MILLIS_AND_OFFSET,
Locale.ENGLISH Locale.ENGLISH
@ -63,6 +71,10 @@ public final class DateTimeUtils {
FORMAT_STRING_TIMESTAMP_WITH_MICROS_AND_OFFSET, FORMAT_STRING_TIMESTAMP_WITH_MICROS_AND_OFFSET,
Locale.ENGLISH Locale.ENGLISH
); );
public static final DateTimeFormatter DATE_TIME_FORMATTER_TIMESTAMP_WITH_NANOS_AND_OFFSET = DateTimeFormatter.ofPattern(
FORMAT_STRING_TIMESTAMP_WITH_NANOS_AND_OFFSET,
Locale.ENGLISH
);
public static final String JDBC_ESCAPE_START_DATE = "{d '"; public static final String JDBC_ESCAPE_START_DATE = "{d '";
public static final String JDBC_ESCAPE_START_TIME = "{t '"; public static final String JDBC_ESCAPE_START_TIME = "{t '";
@ -96,12 +108,6 @@ public final class DateTimeUtils {
Locale.ENGLISH Locale.ENGLISH
) )
); );
private static final ThreadLocal<SimpleDateFormat> TIMESTAMP_WITH_MICROS_FORMAT = ThreadLocal.withInitial(
() -> new SimpleDateFormat(
FORMAT_STRING_TIMESTAMP_WITH_MICROS,
Locale.ENGLISH
)
);
/** /**
* Pattern used for parsing literal offset datetimes in HQL. * Pattern used for parsing literal offset datetimes in HQL.
@ -120,58 +126,64 @@ public final class DateTimeUtils {
.appendOffset("+HH:mm", "+00") .appendOffset("+HH:mm", "+00")
.toFormatter(); .toFormatter();
public static void appendAsTimestampWithNanos(
SqlAppender appender,
TemporalAccessor temporalAccessor,
boolean supportsOffset,
TimeZone jdbcTimeZone) {
appendAsTimestamp(
appender,
temporalAccessor,
supportsOffset,
jdbcTimeZone,
DATE_TIME_FORMATTER_TIMESTAMP_WITH_NANOS,
DATE_TIME_FORMATTER_TIMESTAMP_WITH_NANOS_AND_OFFSET
);
}
public static void appendAsTimestampWithMicros( public static void appendAsTimestampWithMicros(
SqlAppender appender, SqlAppender appender,
TemporalAccessor temporalAccessor, TemporalAccessor temporalAccessor,
boolean supportsOffset, boolean supportsOffset,
TimeZone jdbcTimeZone) { TimeZone jdbcTimeZone) {
if ( temporalAccessor.isSupported( ChronoField.OFFSET_SECONDS ) ) { appendAsTimestamp(
if ( supportsOffset ) { appender,
DATE_TIME_FORMATTER_TIMESTAMP_WITH_MICROS_AND_OFFSET.formatTo( temporalAccessor, appender ); temporalAccessor,
} supportsOffset,
else { jdbcTimeZone,
DATE_TIME_FORMATTER_TIMESTAMP_WITH_MICROS.formatTo( DATE_TIME_FORMATTER_TIMESTAMP_WITH_MICROS,
LocalDateTime.ofInstant( DATE_TIME_FORMATTER_TIMESTAMP_WITH_MICROS_AND_OFFSET
Instant.from( temporalAccessor ),
jdbcTimeZone.toZoneId()
),
appender
); );
} }
}
else if ( temporalAccessor instanceof Instant ) {
if ( supportsOffset ) {
DATE_TIME_FORMATTER_TIMESTAMP_WITH_MICROS_AND_OFFSET.formatTo(
( (Instant) temporalAccessor ).atZone( jdbcTimeZone.toZoneId() ),
appender
);
}
else {
DATE_TIME_FORMATTER_TIMESTAMP_WITH_MICROS.formatTo(
LocalDateTime.ofInstant(
(Instant) temporalAccessor,
jdbcTimeZone.toZoneId()
),
appender
);
}
}
else {
DATE_TIME_FORMATTER_TIMESTAMP_WITH_MICROS.formatTo( temporalAccessor, appender );
}
}
public static void appendAsTimestampWithMillis( public static void appendAsTimestampWithMillis(
SqlAppender appender, SqlAppender appender,
TemporalAccessor temporalAccessor, TemporalAccessor temporalAccessor,
boolean supportsOffset, boolean supportsOffset,
TimeZone jdbcTimeZone) { TimeZone jdbcTimeZone) {
appendAsTimestamp(
appender,
temporalAccessor,
supportsOffset,
jdbcTimeZone,
DATE_TIME_FORMATTER_TIMESTAMP_WITH_MILLIS,
DATE_TIME_FORMATTER_TIMESTAMP_WITH_MILLIS_AND_OFFSET
);
}
private static void appendAsTimestamp(
SqlAppender appender,
TemporalAccessor temporalAccessor,
boolean supportsOffset,
TimeZone jdbcTimeZone,
DateTimeFormatter format,
DateTimeFormatter formatWithOffset) {
if ( temporalAccessor.isSupported( ChronoField.OFFSET_SECONDS ) ) { if ( temporalAccessor.isSupported( ChronoField.OFFSET_SECONDS ) ) {
if ( supportsOffset ) { if ( supportsOffset ) {
DATE_TIME_FORMATTER_TIMESTAMP_WITH_MILLIS_AND_OFFSET.formatTo( temporalAccessor, appender ); formatWithOffset.formatTo( temporalAccessor, appender );
} }
else { else {
DATE_TIME_FORMATTER_TIMESTAMP_WITH_MILLIS.formatTo( format.formatTo(
LocalDateTime.ofInstant( LocalDateTime.ofInstant(
Instant.from( temporalAccessor ), Instant.from( temporalAccessor ),
jdbcTimeZone.toZoneId() jdbcTimeZone.toZoneId()
@ -182,13 +194,13 @@ public final class DateTimeUtils {
} }
else if ( temporalAccessor instanceof Instant ) { else if ( temporalAccessor instanceof Instant ) {
if ( supportsOffset ) { if ( supportsOffset ) {
DATE_TIME_FORMATTER_TIMESTAMP_WITH_MILLIS_AND_OFFSET.formatTo( formatWithOffset.formatTo(
( (Instant) temporalAccessor ).atZone( jdbcTimeZone.toZoneId() ), ( (Instant) temporalAccessor ).atZone( jdbcTimeZone.toZoneId() ),
appender appender
); );
} }
else { else {
DATE_TIME_FORMATTER_TIMESTAMP_WITH_MILLIS.formatTo( format.formatTo(
LocalDateTime.ofInstant( LocalDateTime.ofInstant(
(Instant) temporalAccessor, (Instant) temporalAccessor,
jdbcTimeZone.toZoneId() jdbcTimeZone.toZoneId()
@ -198,7 +210,7 @@ public final class DateTimeUtils {
} }
} }
else { else {
DATE_TIME_FORMATTER_TIMESTAMP_WITH_MILLIS.formatTo( temporalAccessor, appender ); format.formatTo( temporalAccessor, appender );
} }
} }
@ -241,15 +253,20 @@ public final class DateTimeUtils {
} }
public static void appendAsTimestampWithMicros(SqlAppender appender, Date date, TimeZone jdbcTimeZone) { public static void appendAsTimestampWithMicros(SqlAppender appender, Date date, TimeZone jdbcTimeZone) {
final SimpleDateFormat simpleDateFormat;
if ( date instanceof Timestamp ) { if ( date instanceof Timestamp ) {
// java.sql.Timestamp supports micro sec // java.sql.Timestamp supports nano sec
simpleDateFormat = TIMESTAMP_WITH_MICROS_FORMAT.get(); appendAsTimestamp(
appender,
date.toInstant().atZone( jdbcTimeZone.toZoneId() ),
false,
jdbcTimeZone,
DATE_TIME_FORMATTER_TIMESTAMP_WITH_MICROS,
DATE_TIME_FORMATTER_TIMESTAMP_WITH_MICROS_AND_OFFSET
);
} }
else { else {
// java.util.Date supports only milli sec // java.util.Date supports only milli sec
simpleDateFormat = TIMESTAMP_WITH_MILLIS_FORMAT.get(); final SimpleDateFormat simpleDateFormat = TIMESTAMP_WITH_MILLIS_FORMAT.get();
}
final TimeZone originalTimeZone = simpleDateFormat.getTimeZone(); final TimeZone originalTimeZone = simpleDateFormat.getTimeZone();
try { try {
simpleDateFormat.setTimeZone( jdbcTimeZone ); simpleDateFormat.setTimeZone( jdbcTimeZone );
@ -259,6 +276,33 @@ public final class DateTimeUtils {
simpleDateFormat.setTimeZone( originalTimeZone ); simpleDateFormat.setTimeZone( originalTimeZone );
} }
} }
}
public static void appendAsTimestampWithNanos(SqlAppender appender, Date date, TimeZone jdbcTimeZone) {
if ( date instanceof Timestamp ) {
// java.sql.Timestamp supports nano sec
appendAsTimestamp(
appender,
date.toInstant().atZone( jdbcTimeZone.toZoneId() ),
false,
jdbcTimeZone,
DATE_TIME_FORMATTER_TIMESTAMP_WITH_NANOS,
DATE_TIME_FORMATTER_TIMESTAMP_WITH_NANOS_AND_OFFSET
);
}
else {
// java.util.Date supports only milli sec
final SimpleDateFormat simpleDateFormat = TIMESTAMP_WITH_MILLIS_FORMAT.get();
final TimeZone originalTimeZone = simpleDateFormat.getTimeZone();
try {
simpleDateFormat.setTimeZone( jdbcTimeZone );
appender.appendSql( simpleDateFormat.format( date ) );
}
finally {
simpleDateFormat.setTimeZone( originalTimeZone );
}
}
}
public static void appendAsDate(SqlAppender appender, Date date) { public static void appendAsDate(SqlAppender appender, Date date) {
appender.appendSql( LOCAL_DATE_FORMAT.get().format( date ) ); appender.appendSql( LOCAL_DATE_FORMAT.get().format( date ) );
@ -303,6 +347,12 @@ public final class DateTimeUtils {
} }
} }
/**
* Calendar has no microseconds.
*
* @deprecated use {@link #appendAsTimestampWithMillis(SqlAppender, Calendar, TimeZone)} instead
*/
@Deprecated(forRemoval = true)
public static void appendAsTimestampWithMicros(SqlAppender appender, Calendar calendar, TimeZone jdbcTimeZone) { public static void appendAsTimestampWithMicros(SqlAppender appender, Calendar calendar, TimeZone jdbcTimeZone) {
// it is possible to use micro sec resolution with java.util.Date // it is possible to use micro sec resolution with java.util.Date
final SimpleDateFormat simpleDateFormat = TIMESTAMP_WITH_MILLIS_FORMAT.get(); final SimpleDateFormat simpleDateFormat = TIMESTAMP_WITH_MILLIS_FORMAT.get();
@ -352,4 +402,45 @@ public final class DateTimeUtils {
appender.appendSql( LOCAL_TIME_FORMAT.get().format( calendar.getTime() ) ); appender.appendSql( LOCAL_TIME_FORMAT.get().format( calendar.getTime() ) );
} }
/**
* Do the same conversion that databases do when they encounter a timestamp with a higher precision
* than what is supported by a column, which is to round the excess fractions.
*/
public static <T extends Temporal> T roundToDefaultPrecision(T temporal, Dialect d) {
final int defaultTimestampPrecision = d.getDefaultTimestampPrecision();
if ( defaultTimestampPrecision >= 9 || !temporal.isSupported( ChronoField.NANO_OF_SECOND ) ) {
return temporal;
}
final int precisionMask = pow10( 9 - defaultTimestampPrecision );
final int nano = temporal.get( ChronoField.NANO_OF_SECOND );
final int nanosToRound = nano % precisionMask;
final int finalNano = nano - nanosToRound + ( nanosToRound >= ( precisionMask >> 1 ) ? precisionMask : 0 );
//noinspection unchecked
return (T) temporal.with( ChronoField.NANO_OF_SECOND, finalNano );
}
private static int pow10(int exponent) {
switch ( exponent ) {
case 0:
return 1;
case 1:
return 10;
case 2:
return 100;
case 3:
return 1000;
case 4:
return 10000;
case 5:
return 100000;
case 6:
return 1000000;
case 7:
return 10000000;
case 8:
return 100000000;
default:
return (int) Math.pow( 10, exponent );
}
}
} }

View File

@ -4,7 +4,10 @@ import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue; import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id; import jakarta.persistence.Id;
import org.hibernate.cfg.AvailableSettings; import org.hibernate.cfg.AvailableSettings;
import org.hibernate.dialect.Dialect;
import org.hibernate.dialect.SybaseDialect; import org.hibernate.dialect.SybaseDialect;
import org.hibernate.type.descriptor.DateTimeUtils;
import org.hibernate.testing.orm.junit.DomainModel; import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.ServiceRegistry; import org.hibernate.testing.orm.junit.ServiceRegistry;
import org.hibernate.testing.orm.junit.SessionFactory; import org.hibernate.testing.orm.junit.SessionFactory;
@ -37,14 +40,21 @@ public class AutoZonedTest {
}); });
scope.inSession( s -> { scope.inSession( s -> {
Zoned z = s.find(Zoned.class, id); Zoned z = s.find(Zoned.class, id);
if ( scope.getSessionFactory().getJdbcServices().getDialect() instanceof SybaseDialect) { final Dialect dialect = scope.getSessionFactory().getJdbcServices().getDialect();
if ( dialect instanceof SybaseDialect ) {
// Sybase with jTDS driver has 1/300th sec precision // Sybase with jTDS driver has 1/300th sec precision
assertEquals( nowZoned.toInstant().truncatedTo(ChronoUnit.SECONDS), z.zonedDateTime.toInstant().truncatedTo(ChronoUnit.SECONDS) ); assertEquals( nowZoned.toInstant().truncatedTo(ChronoUnit.SECONDS), z.zonedDateTime.toInstant().truncatedTo(ChronoUnit.SECONDS) );
assertEquals( nowOffset.toInstant().truncatedTo(ChronoUnit.SECONDS), z.offsetDateTime.toInstant().truncatedTo(ChronoUnit.SECONDS) ); assertEquals( nowOffset.toInstant().truncatedTo(ChronoUnit.SECONDS), z.offsetDateTime.toInstant().truncatedTo(ChronoUnit.SECONDS) );
} }
else { else {
assertEquals( nowZoned.toInstant(), z.zonedDateTime.toInstant() ); assertEquals(
assertEquals( nowOffset.toInstant(), z.offsetDateTime.toInstant() ); DateTimeUtils.roundToDefaultPrecision( nowZoned.toInstant(), dialect ),
DateTimeUtils.roundToDefaultPrecision( z.zonedDateTime.toInstant(), dialect )
);
assertEquals(
DateTimeUtils.roundToDefaultPrecision( nowOffset.toInstant(), dialect ),
DateTimeUtils.roundToDefaultPrecision( z.offsetDateTime.toInstant(), dialect )
);
} }
assertEquals( nowZoned.toOffsetDateTime().getOffset(), z.zonedDateTime.toOffsetDateTime().getOffset() ); assertEquals( nowZoned.toOffsetDateTime().getOffset(), z.zonedDateTime.toOffsetDateTime().getOffset() );
assertEquals( nowOffset.getOffset(), z.offsetDateTime.getOffset() ); assertEquals( nowOffset.getOffset(), z.offsetDateTime.getOffset() );

View File

@ -4,7 +4,10 @@ import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue; import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id; import jakarta.persistence.Id;
import org.hibernate.cfg.AvailableSettings; import org.hibernate.cfg.AvailableSettings;
import org.hibernate.dialect.Dialect;
import org.hibernate.dialect.SybaseDialect; import org.hibernate.dialect.SybaseDialect;
import org.hibernate.type.descriptor.DateTimeUtils;
import org.hibernate.testing.orm.junit.DomainModel; import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.ServiceRegistry; import org.hibernate.testing.orm.junit.ServiceRegistry;
import org.hibernate.testing.orm.junit.SessionFactory; import org.hibernate.testing.orm.junit.SessionFactory;
@ -37,14 +40,21 @@ public class ColumnZonedTest {
}); });
scope.inSession( s -> { scope.inSession( s -> {
Zoned z = s.find(Zoned.class, id); Zoned z = s.find(Zoned.class, id);
if ( scope.getSessionFactory().getJdbcServices().getDialect() instanceof SybaseDialect) { final Dialect dialect = scope.getSessionFactory().getJdbcServices().getDialect();
if ( dialect instanceof SybaseDialect) {
// Sybase with jTDS driver has 1/300th sec precision // Sybase with jTDS driver has 1/300th sec precision
assertEquals( nowZoned.toInstant().truncatedTo(ChronoUnit.SECONDS), z.zonedDateTime.toInstant().truncatedTo(ChronoUnit.SECONDS) ); assertEquals( nowZoned.toInstant().truncatedTo(ChronoUnit.SECONDS), z.zonedDateTime.toInstant().truncatedTo(ChronoUnit.SECONDS) );
assertEquals( nowOffset.toInstant().truncatedTo(ChronoUnit.SECONDS), z.offsetDateTime.toInstant().truncatedTo(ChronoUnit.SECONDS) ); assertEquals( nowOffset.toInstant().truncatedTo(ChronoUnit.SECONDS), z.offsetDateTime.toInstant().truncatedTo(ChronoUnit.SECONDS) );
} }
else { else {
assertEquals( nowZoned.toInstant(), z.zonedDateTime.toInstant() ); assertEquals(
assertEquals( nowOffset.toInstant(), z.offsetDateTime.toInstant() ); DateTimeUtils.roundToDefaultPrecision( nowZoned.toInstant(), dialect ),
DateTimeUtils.roundToDefaultPrecision( z.zonedDateTime.toInstant(), dialect )
);
assertEquals(
DateTimeUtils.roundToDefaultPrecision( nowOffset.toInstant(), dialect ),
DateTimeUtils.roundToDefaultPrecision( z.offsetDateTime.toInstant(), dialect )
);
} }
assertEquals( nowZoned.toOffsetDateTime().getOffset(), z.zonedDateTime.toOffsetDateTime().getOffset() ); assertEquals( nowZoned.toOffsetDateTime().getOffset(), z.zonedDateTime.toOffsetDateTime().getOffset() );
assertEquals( nowOffset.getOffset(), z.offsetDateTime.getOffset() ); assertEquals( nowOffset.getOffset(), z.offsetDateTime.getOffset() );

View File

@ -3,8 +3,12 @@ package org.hibernate.orm.test.timezones;
import jakarta.persistence.Entity; import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue; import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id; import jakarta.persistence.Id;
import org.hibernate.dialect.Dialect;
import org.hibernate.dialect.SybaseDialect; import org.hibernate.dialect.SybaseDialect;
import org.hibernate.dialect.TimeZoneSupport; import org.hibernate.dialect.TimeZoneSupport;
import org.hibernate.type.descriptor.DateTimeUtils;
import org.hibernate.testing.orm.junit.DomainModel; import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.SessionFactory; import org.hibernate.testing.orm.junit.SessionFactory;
import org.hibernate.testing.orm.junit.SessionFactoryScope; import org.hibernate.testing.orm.junit.SessionFactoryScope;
@ -34,16 +38,23 @@ public class DefaultZonedTest {
}); });
scope.inSession( s -> { scope.inSession( s -> {
Zoned z = s.find(Zoned.class, id); Zoned z = s.find(Zoned.class, id);
if ( scope.getSessionFactory().getJdbcServices().getDialect() instanceof SybaseDialect) { final Dialect dialect = scope.getSessionFactory().getJdbcServices().getDialect();
if ( dialect instanceof SybaseDialect) {
// Sybase with jTDS driver has 1/300th sec precision // Sybase with jTDS driver has 1/300th sec precision
assertEquals( nowZoned.toInstant().truncatedTo(ChronoUnit.SECONDS), z.zonedDateTime.toInstant().truncatedTo(ChronoUnit.SECONDS) ); assertEquals( nowZoned.toInstant().truncatedTo(ChronoUnit.SECONDS), z.zonedDateTime.toInstant().truncatedTo(ChronoUnit.SECONDS) );
assertEquals( nowOffset.toInstant().truncatedTo(ChronoUnit.SECONDS), z.offsetDateTime.toInstant().truncatedTo(ChronoUnit.SECONDS) ); assertEquals( nowOffset.toInstant().truncatedTo(ChronoUnit.SECONDS), z.offsetDateTime.toInstant().truncatedTo(ChronoUnit.SECONDS) );
} }
else { else {
assertEquals( nowZoned.toInstant(), z.zonedDateTime.toInstant() ); assertEquals(
assertEquals( nowOffset.toInstant(), z.offsetDateTime.toInstant() ); DateTimeUtils.roundToDefaultPrecision( nowZoned.toInstant(), dialect ),
DateTimeUtils.roundToDefaultPrecision( z.zonedDateTime.toInstant(), dialect )
);
assertEquals(
DateTimeUtils.roundToDefaultPrecision( nowOffset.toInstant(), dialect ),
DateTimeUtils.roundToDefaultPrecision( z.offsetDateTime.toInstant(), dialect )
);
} }
if ( scope.getSessionFactory().getJdbcServices().getDialect().getTimeZoneSupport() == TimeZoneSupport.NATIVE ) { if ( dialect.getTimeZoneSupport() == TimeZoneSupport.NATIVE ) {
assertEquals( nowZoned.toOffsetDateTime().getOffset(), z.zonedDateTime.toOffsetDateTime().getOffset() ); assertEquals( nowZoned.toOffsetDateTime().getOffset(), z.zonedDateTime.toOffsetDateTime().getOffset() );
assertEquals( nowOffset.getOffset(), z.offsetDateTime.getOffset() ); assertEquals( nowOffset.getOffset(), z.offsetDateTime.getOffset() );
} }

View File

@ -4,7 +4,10 @@ import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue; import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id; import jakarta.persistence.Id;
import org.hibernate.cfg.AvailableSettings; import org.hibernate.cfg.AvailableSettings;
import org.hibernate.dialect.Dialect;
import org.hibernate.dialect.SybaseDialect; import org.hibernate.dialect.SybaseDialect;
import org.hibernate.type.descriptor.DateTimeUtils;
import org.hibernate.testing.orm.junit.DomainModel; import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.ServiceRegistry; import org.hibernate.testing.orm.junit.ServiceRegistry;
import org.hibernate.testing.orm.junit.SessionFactory; import org.hibernate.testing.orm.junit.SessionFactory;
@ -41,14 +44,21 @@ public class JDBCTimeZoneZonedTest {
Zoned z = s.find(Zoned.class, id); Zoned z = s.find(Zoned.class, id);
ZoneId systemZone = ZoneId.systemDefault(); ZoneId systemZone = ZoneId.systemDefault();
ZoneOffset systemOffset = systemZone.getRules().getOffset( Instant.now() ); ZoneOffset systemOffset = systemZone.getRules().getOffset( Instant.now() );
if ( scope.getSessionFactory().getJdbcServices().getDialect() instanceof SybaseDialect) { final Dialect dialect = scope.getSessionFactory().getJdbcServices().getDialect();
if ( dialect instanceof SybaseDialect) {
// Sybase with jTDS driver has 1/300th sec precision // Sybase with jTDS driver has 1/300th sec precision
assertEquals( nowZoned.toInstant().truncatedTo(ChronoUnit.SECONDS), z.zonedDateTime.toInstant().truncatedTo(ChronoUnit.SECONDS)); assertEquals( nowZoned.toInstant().truncatedTo(ChronoUnit.SECONDS), z.zonedDateTime.toInstant().truncatedTo(ChronoUnit.SECONDS));
assertEquals( nowOffset.toInstant().truncatedTo(ChronoUnit.SECONDS), z.offsetDateTime.toInstant().truncatedTo(ChronoUnit.SECONDS)); assertEquals( nowOffset.toInstant().truncatedTo(ChronoUnit.SECONDS), z.offsetDateTime.toInstant().truncatedTo(ChronoUnit.SECONDS));
} }
else { else {
assertEquals( nowZoned.withZoneSameInstant(systemZone), z.zonedDateTime ); assertEquals(
assertEquals( nowOffset.withOffsetSameInstant(systemOffset), z.offsetDateTime ); DateTimeUtils.roundToDefaultPrecision( nowZoned.toInstant(), dialect ),
DateTimeUtils.roundToDefaultPrecision( z.zonedDateTime.toInstant(), dialect )
);
assertEquals(
DateTimeUtils.roundToDefaultPrecision( nowOffset.toInstant(), dialect ),
DateTimeUtils.roundToDefaultPrecision( z.offsetDateTime.toInstant(), dialect )
);
} }
assertEquals( systemZone, z.zonedDateTime.getZone() ); assertEquals( systemZone, z.zonedDateTime.getZone() );
assertEquals( systemOffset, z.offsetDateTime.getOffset() ); assertEquals( systemOffset, z.offsetDateTime.getOffset() );

View File

@ -4,7 +4,10 @@ import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue; import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id; import jakarta.persistence.Id;
import org.hibernate.cfg.AvailableSettings; import org.hibernate.cfg.AvailableSettings;
import org.hibernate.dialect.Dialect;
import org.hibernate.dialect.SybaseDialect; import org.hibernate.dialect.SybaseDialect;
import org.hibernate.type.descriptor.DateTimeUtils;
import org.hibernate.testing.orm.junit.DomainModel; import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.ServiceRegistry; import org.hibernate.testing.orm.junit.ServiceRegistry;
import org.hibernate.testing.orm.junit.SessionFactory; import org.hibernate.testing.orm.junit.SessionFactory;
@ -40,14 +43,21 @@ public class PassThruZonedTest {
Zoned z = s.find(Zoned.class, id); Zoned z = s.find(Zoned.class, id);
ZoneId systemZone = ZoneId.systemDefault(); ZoneId systemZone = ZoneId.systemDefault();
ZoneOffset systemOffset = systemZone.getRules().getOffset( Instant.now() ); ZoneOffset systemOffset = systemZone.getRules().getOffset( Instant.now() );
if ( scope.getSessionFactory().getJdbcServices().getDialect() instanceof SybaseDialect) { final Dialect dialect = scope.getSessionFactory().getJdbcServices().getDialect();
if ( dialect instanceof SybaseDialect) {
// Sybase with jTDS driver has 1/300th sec precision // Sybase with jTDS driver has 1/300th sec precision
assertEquals( nowZoned.toInstant().truncatedTo(ChronoUnit.SECONDS), z.zonedDateTime.toInstant().truncatedTo(ChronoUnit.SECONDS)); assertEquals( nowZoned.toInstant().truncatedTo(ChronoUnit.SECONDS), z.zonedDateTime.toInstant().truncatedTo(ChronoUnit.SECONDS));
assertEquals( nowOffset.toInstant().truncatedTo(ChronoUnit.SECONDS), z.offsetDateTime.toInstant().truncatedTo(ChronoUnit.SECONDS)); assertEquals( nowOffset.toInstant().truncatedTo(ChronoUnit.SECONDS), z.offsetDateTime.toInstant().truncatedTo(ChronoUnit.SECONDS));
} }
else { else {
assertEquals( nowZoned.withZoneSameInstant(systemZone), z.zonedDateTime ); assertEquals(
assertEquals( nowOffset.withOffsetSameInstant(systemOffset), z.offsetDateTime ); DateTimeUtils.roundToDefaultPrecision( nowZoned.toInstant(), dialect ),
DateTimeUtils.roundToDefaultPrecision( z.zonedDateTime.toInstant(), dialect )
);
assertEquals(
DateTimeUtils.roundToDefaultPrecision( nowOffset.toInstant(), dialect ),
DateTimeUtils.roundToDefaultPrecision( z.offsetDateTime.toInstant(), dialect )
);
} }
assertEquals( systemZone, z.zonedDateTime.getZone() ); assertEquals( systemZone, z.zonedDateTime.getZone() );
assertEquals( systemOffset, z.offsetDateTime.getOffset() ); assertEquals( systemOffset, z.offsetDateTime.getOffset() );

View File

@ -4,7 +4,10 @@ import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue; import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id; import jakarta.persistence.Id;
import org.hibernate.cfg.AvailableSettings; import org.hibernate.cfg.AvailableSettings;
import org.hibernate.dialect.Dialect;
import org.hibernate.dialect.SybaseDialect; import org.hibernate.dialect.SybaseDialect;
import org.hibernate.type.descriptor.DateTimeUtils;
import org.hibernate.testing.orm.junit.DomainModel; import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.ServiceRegistry; import org.hibernate.testing.orm.junit.ServiceRegistry;
import org.hibernate.testing.orm.junit.SessionFactory; import org.hibernate.testing.orm.junit.SessionFactory;
@ -37,14 +40,21 @@ public class UTCNormalizedZonedTest {
}); });
scope.inSession( s-> { scope.inSession( s-> {
Zoned z = s.find(Zoned.class, id); Zoned z = s.find(Zoned.class, id);
if ( scope.getSessionFactory().getJdbcServices().getDialect() instanceof SybaseDialect) { final Dialect dialect = scope.getSessionFactory().getJdbcServices().getDialect();
if ( dialect instanceof SybaseDialect) {
// Sybase with jTDS driver has 1/300th sec precision // Sybase with jTDS driver has 1/300th sec precision
assertEquals( nowZoned.toInstant().truncatedTo(ChronoUnit.SECONDS), z.zonedDateTime.toInstant().truncatedTo(ChronoUnit.SECONDS) ); assertEquals( nowZoned.toInstant().truncatedTo(ChronoUnit.SECONDS), z.zonedDateTime.toInstant().truncatedTo(ChronoUnit.SECONDS) );
assertEquals( nowOffset.toInstant().truncatedTo(ChronoUnit.SECONDS), z.offsetDateTime.toInstant().truncatedTo(ChronoUnit.SECONDS) ); assertEquals( nowOffset.toInstant().truncatedTo(ChronoUnit.SECONDS), z.offsetDateTime.toInstant().truncatedTo(ChronoUnit.SECONDS) );
} }
else { else {
assertEquals( nowZoned.toInstant(), z.zonedDateTime.toInstant() ); assertEquals(
assertEquals( nowOffset.toInstant(), z.offsetDateTime.toInstant() ); DateTimeUtils.roundToDefaultPrecision( nowZoned.toInstant(), dialect ),
DateTimeUtils.roundToDefaultPrecision( z.zonedDateTime.toInstant(), dialect )
);
assertEquals(
DateTimeUtils.roundToDefaultPrecision( nowOffset.toInstant(), dialect ),
DateTimeUtils.roundToDefaultPrecision( z.offsetDateTime.toInstant(), dialect )
);
} }
assertEquals( ZoneId.of("Z"), z.zonedDateTime.getZone() ); assertEquals( ZoneId.of("Z"), z.zonedDateTime.getZone() );
assertEquals( ZoneOffset.ofHours(0), z.offsetDateTime.getOffset() ); assertEquals( ZoneOffset.ofHours(0), z.offsetDateTime.getOffset() );