我的时间戳在哪里搞砸了#34;?

时间:2016-02-23 00:32:29

标签: postgresql jodatime jooq

由于我已经投了票,我决定给我的问题提供更多细节。

我的问题是我想存储。时间以便于比较。对我而言,将其定义如下:

00:00:00 = (long) 0L
24:00:00 = (long) 24*60*60*1000L

PostgreSQL documentationTIME WITHOUT TIME ZONE这个:

time [ (p) ] [ without time zone ] 
   8 bytes | time of day (no date) | 00:00:00 - 24:00:00 | 1 microsecond / 14 digits

但出于某种原因,从我的数据库到我的网络应用程序的某个地方,时间戳都搞砸了。

在下文中,我想向您展示我正在存储TIME WITHOUT TIME ZONE,从LocalTime(jodatime)映射到我的数据库中,之后将其取回。

从数据库中取回它并将其映射回LocalTime对象会给我一些像23 Feb 2016 08:00:00 GMT这样的东西。 1456214400000> 24*60*60*1000

有3到4个选项:

  1. PostgresSQL实际存储整个TIMESTAMP并仅显示HH:mm:ss
  2. jodatime正在发明这里没有的东西。
  3. (非常不可能)我使用的映射器比我告诉他的更多。但这不太可能,因为映射器触摸任何东西。
  4. (可能是真的)我自己搞砸了。
  5. 更多详情:

    我决定添加一些细节。我正在为我的表shop_times

    创建一条记录
    private Long createShopTimes(Long shopId, DateTime dayFrom, DateTime dayTo, LocalTime timeFrom, LocalTime timeTo, DayOfWeek dayOfWeek, ShopTimesType shopTimesType) {
    
        Long timePeriodId = this.ctx.insertInto(SHOP_TIMES)
                .set(SHOP_TIMES.SHOP_ID, shopId)
                .set(SHOP_TIMES.DAY_OF_WEEK_ID, dayOfWeek)
                .set(SHOP_TIMES.SHOP_TIMES_TYPE_ID, shopTimesType)
                .set(SHOP_TIMES.DAY_FROM, dayFrom)
                .set(SHOP_TIMES.DAY_TO, dayTo)
                .set(SHOP_TIMES.TIME_FROM, timeFrom)
                .set(SHOP_TIMES.TIME_TO, timeTo)
                .returning(SHOP_TIMES.ID)
                .fetchOne().getValue(SHOP_TIMES.ID);
    
        List<ShopTimesRecord> fetchInto = this.ctx.select(
                SHOP_TIMES.TIME_FROM,
                SHOP_TIMES.TIME_TO
                )
                .from(SHOP_TIMES)
                .fetchInto(ShopTimesRecord.class);
    
        for (ShopTimesRecord shopTimesRecord : fetchInto) {
    
            if(shopTimesRecord.getTimeFrom().toDateTimeToday().getMillis() > 24*60*60*1000L) {
                System.err.println("This should not happen..");
            }
    
            Date from = new Date(shopTimesRecord.getTimeFrom().toDateTimeToday().getMillis());
            Date to = new Date(shopTimesRecord.getTimeTo().toDateTimeToday().getMillis());
    
            System.out.println(from.toGMTString());
            System.out.println(shopTimesRecord.getTimeFrom().toDateTimeToday().getMillis());
    
            System.out.println(to.toGMTString());
            System.out.println(shopTimesRecord.getTimeTo().toDateTimeToday().getMillis());
        }
    
        return timePeriodId;
    }
    

    正如你所看到的,我现在得到了一些我不会想到的东西:

    This should not happen..
    23 Feb 2016 08:00:00 GMT
    1456214400000
    23 Feb 2016 20:00:00 GMT
    1456257600000
    

    这是我用来存储时间信息的表shop_times

    CREATE TABLE shop_times (
    
        -- PRIMARY KEY
    
        id BIGSERIAL PRIMARY KEY,
    
        -- FOREIGN KEYS
    
        shop_id BIGINT NOT NULL,
    
        CONSTRAINT fk__shop_times__shop
            FOREIGN KEY (shop_id)
            REFERENCES shop(id),
    
        shop_times_type_id BIGINT NOT NULL,
    
        CONSTRAINT fk_shop_times__shop_times_type
            FOREIGN KEY (shop_times_type_id)
            REFERENCES shop_times_type(id),
    
        day_of_week_id BIGINT NOT NULL,
    
        CONSTRAINT fk__shop_times__day_of_week
            FOREIGN KEY (day_of_week_id)
            REFERENCES day_of_week(id),
    
        -- ATTRIBUTES
    
        day_from TIMESTAMP WITH TIME ZONE NOT NULL, 
        day_to TIMESTAMP WITH TIME ZONE NOT NULL,
    
        time_from TIME WITHOUT TIME ZONE NOT NULL,
        time_to TIME WITHOUT TIME ZONE NOT NULL,
    
        -- CONSTRAINTS
    
        CHECK(day_from < day_to),
    
        CHECK(time_from < time_to)
    
    );
    

    我正在使用的映射器。但正如你所看到的那样,它只是花费时间并将其传递出去;

    public class TimeWithoutTzToJodaLocalTimeConverter implements Converter<Time, LocalTime> {
        private static final long serialVersionUID = -2736422625956918206L;
    
        @Override
        public LocalTime from(Time timestamp) {
            LocalTime dateTime = new LocalTime(timestamp.getTime());
            return dateTime;
        }
    
        @Override
        public Time to(LocalTime localTime) {
            Time time = new Time(localTime.toDateTimeToday().getMillis());
            return time;
        }
    
        @Override
        public Class<Time> fromType() {
            return Time.class;
        }
    
        @Override
        public Class<LocalTime> toType() {
            return LocalTime.class;
        }
    
    }
    

2 个答案:

答案 0 :(得分:1)

抱歉 - 不要相信你。

=> SELECT '24:00:00'::time without time zone;
   time   
----------
 24:00:00
(1 row)

=> SELECT '24:00:01'::time without time zone;
ERROR:  date/time field value out of range: "24:00:01"
LINE 1: SELECT '24:00:01'::time without time zone;

答案 1 :(得分:0)