1 package com.vladmihalcea.hibernate.type.interval;
2
3 import com.vladmihalcea.hibernate.type.ImmutableType;
4 import org.hibernate.engine.spi.SharedSessionContractImplementor;
5 import org.postgresql.util.PGInterval;
6
7 import java.sql.PreparedStatement;
8 import java.sql.ResultSet;
9 import java.sql.SQLException;
10 import java.sql.Types;
11 import java.time.Duration;
12 import java.time.temporal.ChronoUnit;
13
14
23 public class PostgreSQLIntervalType extends ImmutableType<Duration> {
24
25 private static final double MICROS_IN_SECOND = 1000000;
26
27 public static final PostgreSQLIntervalType INSTANCE = new PostgreSQLIntervalType();
28
29 public PostgreSQLIntervalType() {
30 super(Duration.class);
31 }
32
33 @Override
34 protected Duration get(ResultSet rs, String[] names, SharedSessionContractImplementor session, Object owner) throws SQLException {
35 final PGInterval interval = (PGInterval) rs.getObject(names[0]);
36
37 if (interval == null) {
38 return null;
39 }
40
41 final int days = interval.getDays();
42 final int hours = interval.getHours();
43 final int minutes = interval.getMinutes();
44 final int seconds = (int) interval.getSeconds();
45 final int micros = (int) Math.round((interval.getSeconds() - seconds) * MICROS_IN_SECOND);
46
47 return Duration.ofDays(days)
48 .plus(hours, ChronoUnit.HOURS)
49 .plus(minutes, ChronoUnit.MINUTES)
50 .plus(seconds, ChronoUnit.SECONDS)
51 .plus(micros, ChronoUnit.MICROS);
52 }
53
54 @Override
55 protected void set(PreparedStatement st, Duration value, int index, SharedSessionContractImplementor session) throws SQLException {
56 if (value == null) {
57 st.setNull(index, Types.OTHER);
58 } else {
59 final int days = (int) value.toDays();
60 final int hours = (int) (value.toHours() % 24);
61 final int minutes = (int) (value.toMinutes() % 60);
62 final int seconds = (int) (value.getSeconds() % 60);
63 final int micros = value.getNano() / 1000;
64 final double secondsWithFraction = seconds + (micros / MICROS_IN_SECOND);
65 st.setObject(index, new PGInterval(0, 0, days, hours, minutes, secondsWithFraction));
66 }
67 }
68
69 @Override
70 public int[] sqlTypes() {
71 return new int[]{Types.OTHER};
72 }
73
74 }
75