由于我已经开始投票,我决定给我的问题一些更多的细节。我的时间戳在哪里变得“搞砸了”?
我的问题是,我想存储次。时间只有为了便于比较。对我来说是有意义的把它定义如下:
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 ZONE
,从LocalTime
(jodatime)映射到我的数据库,然后取回它。
抓取它从数据库返回并映射回成LocalTime
对象会给我像23 Feb 2016 08:00:00 GMT
这是 1456214400000
,这是> 24*60*60*1000
。
有3到4个选项:
- PostgreSQL的店其实整个
TIMESTAMP
并显示HH:mm:ss
只是为了演示 - jodatime的是,是不是有此发明创造。
- (非常不可能)我使用的映射器比我告诉他的要多。但这是不可能的,因为映射器不会触摸任何东西而不是。
- (可能是真的)我自己搞砸了。
更多细节:
我决定添加一些更多的细节。我创建一个记录我的表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;
}
}
我相信,在Java中'Calendar'对象还允许将分配给它的任何时间任意数量。也许这有一个共同的原因。 –
你的'CHECK'可能不会做你认为它正在做的事情......'TO_TIMESTAMP(24 * 60 * 60 * 1000)'是''1972-09-27 10:00:00''。 –
@NickBarnes好的,好点。但是这并不能解决问题,因为它似乎仍然接受“2016-09-27 10:00:00”。至少这就是我得到它的结果。 – displayname