我的时间戳从哪里获得 "messed up"?

Where are my timestamps getting "messed up"?

因为我已经被否决了,所以我决定提供更多关于我的问题的细节。

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

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

PostgreSQL documentation 关于 TIME 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

但出于某种原因,从我的数据库到我的 Web 应用程序的某个地方,时间戳变得一团糟。

在下文中,我想向您展示我正在将 TIME WITHOUT TIME ZONELocalTime (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. (可能是真的)我自己搞砸了。

更多详情:

我决定添加更多详细信息。我正在为我的 table 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

这是我用来存储计时信息的 table 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;
    }

}

对不起 - 不相信你。

=> 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;

您正在创建一个完整的 DateTime:

.toDateTimeToday()

http://joda-time.sourceforge.net/api-release/org/joda/time/TimeOfDay.html#toDateTimeToday%28%29