Я подхожу против неожиданной проблемы с летним временем в коде, который, как я думал, был чисто UTC. Я использую Java 1.6, iBatis SQL mapper (2.3.3) и Oracle XE (эквивалентную версию Oracle 10.2) с тонким драйвером Oracle.Каков правильный способ обработки дат UTC с использованием Java, iBatis и Oracle?
База данных содержит таблицу, которая представляет собой расписание телевизионного вещания. Каждая «Asset» (программа) имеет время начала и окончания. Вот соответствующий фрагмент:
create table Asset
(
asset_id integer not null, -- The unique id of the Asset.
[...]
start_time timestamp, -- The start time.
end_time timestamp, -- The end time.
[...]
constraint asset_primary_key primary key (asset_id),
constraint asset_time check (end_time >= start_time)
);
Оракул asset_time
ограничения стрельбы для программ, расположенных вдоль США сберегательных центрального дневного света регулировки времени это предстоящее воскресенье утром, 11/1/2009.
У меня есть эта передача данных объекта (Даты java.util.Dates):
public class Asset
{
protected Long asset_id;
[...]
protected Date start_time;
protected Date end_time;
public Date getStart_time() { return start_time; }
public Date getEnd_time() { return end_time; }
public void setStart_time(Date start_time) { this.start_time = start_time; }
public void setEnd_time(Date end_time) { this.end_time = end_time; }
[...]
}
И на карте Ibatis SQL у меня есть это утверждение, что вставляет актив DTO в таблицу Oracle Asset:
<insert id="Asset.insert" parameterClass="com.acme.Asset">
insert into Asset
(asset_id, [...] start_time, end_time)
values
(#asset_id#, [...] #start_time#, #end_time#)
</insert>
на стороне Java я проверил, что я даю Ibatis правильного ввод даты UTC с помощью этого предварительной вставки утверждения, не брошенного:
System.err.println("Inserting asset " + program_id);
System.err.println(" "+asset.getStart_time_str()+"--"+asset.getEnd_time_str());
if (!asset.getEnd_time().after(asset.getStart_time())) {
System.err.println("Invalid datetime range in asset.");
throw new AssertionError("Invalid datetime range in asset.");
}
Просто до отказа ограничения Oracle приведенный выше код печатает:
Inserting asset EP011453960004
2009-11-01T06:30:00Z--2009-11-01T07:00:00Z
Я в центральном часовом поясе США, GMT -5: 00, так что эта программа начинается в 1:30 и заканчивается в 2:00 утра. Переход на летнее время меняется в 2 часа ночи и возвращает часы в 1:00 утра.
Ibatis сообщает отказ Oracle ограничение (отредактированный):
2009-10-30 22:58:42,238 [...] Executing Statement:
insert into Asset (asset_id, [...] start_time, end_time)
values (?, [...] ?, ?)
2009-10-30 22:58:42,238 [...] Parameters:
[EP011453960004, [...] 2009-11-01 01:30:00.0, 2009-11-01 01:00:00.0]
2009-10-30 22:58:42,238 [..] Types:
[java.lang.Long, [...] java.sql.Timestamp, java.sql.Timestamp]
2009-10-30 22:58:42,285 [...] - Failed with a SQLException:
--- The error occurred in com/acme/data/dao/Asset-Write.xml.
--- The error occurred while applying a parameter map.
--- Check the Asset.insert-InlineParameterMap.
--- Check the statement (update failed).
--- Cause: java.sql.SQLException: ORA-02290: check constraint (ACME.ASSET_TIME)
violated
Вы заметите, что на стороне Oracle, он видит start_time/END_TIME с регулировкой времени перехода на летнее, так что что-то в отображении Ibatis логика или драйвер Oracle не делают то, что я ожидал. Водитель ojdbc14.jar, тонкий водитель:
JDBCReadWrite.Driver = oracle.jdbc.OracleDriver
JDBCReadWrite.ConnectionURL = jdbc:oracle:thin:@localhost:1521:XE
Что такое правильный способ, чтобы гарантировать, что этот код чисто UTC?
Заранее благодарен!
В каком файле вы добавляете этот тег handler? Поддерживается ли она в ibaits 2.3? – DDK