在JPA MySql中存储与时区无关的时间的最佳方法

sshcrbum  于 5个月前  发布在  Mysql
关注(0)|答案(1)|浏览(72)

我在JPA中找不到一个好的解决方案来在mysql数据库中存储与时区无关的时间。
我有一个轮班表,我需要存储每个轮班的开始和结束时间。

+-------------+--------------+------+-----+----------+----------------+
| Field       | Type         | Null | Key | Default  | Extra          |
+-------------+--------------+------+-----+----------+----------------+
| id          | int(11)      | NO   | PRI | NULL     | auto_increment |
| name        | varchar(64)  | NO   |     | NULL     |                |
| start_time  | time         | NO   |     | 00:00:00 |                |
| end_time    | time         | NO   |     | 00:00:00 |                |
+-------------+--------------+------+-----+----------+----------------+

字符串
因此,从mysql中检索的开始/结束时间必须被视为字符串(没有应用特定的时区)。但是如果我将它们存储为varchar(8),我就不能使用以下查询(没有应用任何从varchar到time的类型转换)。

select * from shift where ('21:30:00' BETWEEN start_time and end_time );


所以,我想保留将它们作为时间进行比较的能力。
我试着将移位表建模为如下:

@Entity
    public class Shift {
      @Id
      private Long id;

      @Column(name = "name")
      private String name;

      @Column(name = "start_time")
      private LocalTime startTime;

      @Column(name = "end_time")
      private LocalTime endTime;

...


start_time和end_time被Map为LocalTime,因为LocalTime不存储时区信息。但是,Hibernate将检索到的每个记录的java.util.Date转换为应用系统默认时区的LocalTime,如下所示:

if ( Date.class.isInstance( value ) ) {
        final Date ts = (Date) value;
        final Instant instant = Instant.ofEpochMilli( ts.getTime() );
        return LocalDateTime.ofInstant( instant, ZoneId.systemDefault() ).toLocalTime();
    }


因此,生成的开始/结束时间是相对于服务器的时区的。
一个解决方案是将它们存储为整数,并将小时从分钟中拆分出来。这样,班次表将有四列:start_hours,start_minutes,end_hours,end_minutes。但在JPA中使用它们进行查询是繁琐的。有更好的解决方案吗?

更新

我必须使用服务器的时区来获取当前的偏移。所以,如果我在DB中存储时间为UTC,然后我查询它们,将当前服务器时间转换为UTC是不起作用的,因为在夏令时(DST)期间,服务器时区增加了一个。所以,在冬季,07:00:00+01被转换为06:00:00 UTC。但是,在夏季,07:00:00+02被转换为05:00:00 UTC。

wfauudbj

wfauudbj1#

欢迎来到SO
在数据库中存储带有UTC时区的日期并在客户端进行转换总是更好的。您可以设置下面的属性来强制JPA使用UTC
第一个月
希望这个hleps
你可以看看this blog

相关问题