gpt4 book ai didi

java - 将 SQL Server 日期数据放入 Joda 对象的最佳方法?

转载 作者:行者123 更新时间:2023-12-04 05:57:28 25 4
gpt4 key购买 nike

TL;DR 版本:请确认(如果没有,请提供帮助)我正在获取 SQL Server datetimeoffset数据正确地导入我的 Joda Time Java 对象。

我正在计划将我们的数据库和 Java 代码移动为时区感知。为了做到这一点,我已经遍地都是this post并且正在尝试实现最佳实践。请注意,所有代码都被视为“一次性”代码,所以我并不真正关心这里的效率;只是正确。

我们的环境由 Microsoft SQL Server 2008 数据库和 Java 服务层组成,我们通过存储过程和 Spring 访问所有数据 SimpleJdbcCall的。

提到的最佳实践之一是使用 Joda Time 库。因为这对我来说是新的,所以 datetimeoffset SQL 数据类型,我想确保我正确地执行此操作(因此不会丢失任何信息。)

在 SQL Server 内部,我创建了一个表来测试所有各种 SQL Server get-time-type 函数:

CREATE TABLE MIKE_TEMP (
ID INT NOT NULL IDENTITY,
BLAH NVARCHAR(255),

DT_GET_DATE DATETIME DEFAULT GETDATE() NOT NULL,
DT_GET_UTC_DATE DATETIME DEFAULT GETUTCDATE() NOT NULL,
DT_SYS_DATE_TIME DATETIME DEFAULT sysdatetime() NOT NULL,
DT_SYS_UTC_DATE_TIME DATETIME DEFAULT sysutcdatetime() NOT NULL,
DT_SYS_DATE_TIME_OFFSET DATETIME DEFAULT sysdatetimeoffset() NOT NULL,

DTO_GET_DATE DATETIMEOFFSET DEFAULT GETDATE() NOT NULL,
DTO_GET_UTC_DATE DATETIMEOFFSET DEFAULT GETUTCDATE() NOT NULL,
DTO_SYS_DATE_TIME DATETIMEOFFSET DEFAULT sysdatetime() NOT NULL,
DTO_SYS_UTC_DATE_TIME DATETIMEOFFSET DEFAULT sysutcdatetime() NOT NULL,
DTO_SYS_DATE_TIME_OFFSET DATETIMEOFFSET DEFAULT sysdatetimeoffset() NOT NULL
);

在这张表中,我添加了一个值, blah = 'Hello World!' .结果数据为:
ID BLAH         DT_GET_DATE         DT_GET_UTC_DATE     DT_SYS_DATE_TIME    DT_SYS_UTC_DATE_TIME DT_SYS_DATE_TIME_OFFSET DTO_GET_DATE                       DTO_GET_UTC_DATE                   DTO_SYS_DATE_TIME                  DTO_SYS_UTC_DATE_TIME              DTO_SYS_DATE_TIME_OFFSET           
-- ------------ ------------------- ------------------- ------------------- -------------------- ----------------------- ---------------------------------- ---------------------------------- ---------------------------------- ---------------------------------- ----------------------------------
1 Hello World! 2012-02-15 08:58:41 2012-02-15 14:58:41 2012-02-15 08:58:41 2012-02-15 14:58:41 2012-02-15 08:58:41 2012-02-15 08:58:41.6000000 +00:00 2012-02-15 14:58:41.6000000 +00:00 2012-02-15 08:58:41.6005458 +00:00 2012-02-15 14:58:41.6005458 +00:00 2012-02-15 08:58:41.6005458 -06:00

有一个相应的存储过程可以简单地执行 select * from MIKE_TEMP并将所有数据作为输出参数返回。

访问此数据的 Java 代码是(为了清楚起见,仅包含“有趣的”导入):
import org.joda.time.DateTime;
import java.util.Date;

@Component
public class MikeTempDaoImpl {
private static final Logger logger = LoggerFactory.getLogger(MikeTempDaoImpl.class);

private DataSource dataSource;

@Autowired
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}

public DataSource getDataSource() {
return dataSource;
}

public MikeVTemp getMikeTemp() {
SimpleJdbcCall data = new SimpleJdbcCall(getDataSource());

data.withProcedureName("get_MIKE_TEMP");
data.withoutProcedureColumnMetaDataAccess();
data.declareParameters(
new SqlOutParameter("ID", Types.INTEGER),
new SqlOutParameter("BLAH", Types.NVARCHAR),
new SqlOutParameter("DT_GET_DATE", Types.TIMESTAMP),
new SqlOutParameter("DT_GET_UTC_DATE", Types.TIMESTAMP),
new SqlOutParameter("DT_SYS_DATE_TIME", Types.TIMESTAMP),
new SqlOutParameter("DT_SYS_UTC_DATE_TIME", Types.TIMESTAMP),
new SqlOutParameter("DT_SYS_DATE_TIME_OFFSET", Types.TIMESTAMP),
new SqlOutParameter("DTO_GET_DATE", Types.TIMESTAMP),
new SqlOutParameter("DTO_GET_UTC_DATE", Types.TIMESTAMP),
new SqlOutParameter("DTO_SYS_DATE_TIME", Types.TIMESTAMP),
new SqlOutParameter("DTO_SYS_UTC_DATE_TIME", Types.TIMESTAMP),
new SqlOutParameter("DTO_SYS_DATE_TIME_OFFSET", Types.TIMESTAMP)
);

Map out;

try {
out = data.execute();
} catch (Exception ex) {
logger.error(ex.getMessage());
}

int id = (Integer) out.get("ID");
String blah = (String) out.get("BLAH");
DateTime dtGetDate = new DateTime((Date) out.get("DT_GET_DATE"));
DateTime dtGetUtcDate = new DateTime((Date) out.get("DT_GET_UTC_DATE"));
DateTime dtSysDateTime = new DateTime((Date) out.get("DT_SYS_DATE_TIME"));
DateTime dtSysUtcDateTime = new DateTime((Date) out.get("DT_SYS_UTC_DATE_TIME"));
DateTime dtSysDateTimeOffset = new DateTime((Date) out.get("DT_SYS_DATE_TIME_OFFSET"));
DateTime dtoGetDate = new DateTime((Date) out.get("DTO_GET_DATE"));
DateTime dtoGetUtcDate = new DateTime((Date) out.get("DTO_GET_UTC_DATE"));
DateTime dtoSysDateTime = new DateTime((Date) out.get("DTO_SYS_DATE_TIME"));
DateTime dtoSysUtcDateTime = new DateTime((Date) out.get("DTO_SYS_UTC_DATE_TIME"));
DateTime dtoSysDateTimeOffset = new DateTime((Date) out.get("DTO_SYS_DATE_TIME_OFFSET"));

MikeTemp mt = new MikeTemp.Builder()
.id(id)
.blah(blah)
.dtGetDate(dtGetDate)
.dtGetUtcDate(dtGetUtcDate)
.dtSysDateTime(dtSysDateTime)
.dtSysUtcDateTime(dtSysUtcDateTime)
.dtSysDateTimeOffset(dtSysDateTimeOffset)
.dtoGetDate(dtoGetDate)
.dtoGetUtcDate(dtoGetUtcDate)
.dtoSysDateTime(dtoSysDateTime)
.dtoSysUtcDateTime(dtoSysUtcDateTime)
.dtoSysDateTimeOffset(dtoSysDateTimeOffset)
.build();

System.out.println("id = [" + mt.getId() + "]");
System.out.println("blah = [" + mt.getBlah() + "]");
System.out.println("dtGetDate = [" + mt.getDtGetDate() + "]");
System.out.println("dtGetUtcDate = [" + mt.getDtGetUtcDate() + "]");
System.out.println("dtSysDateTime = [" + mt.getDtSysDateTime() + "]");
System.out.println("dtSysUtcDateTime = [" + mt.getDtSysUtcDateTime() + "]");
System.out.println("dtSysDateTimeOffset = [" + mt.getDtSysDateTimeOffset() + "]");
System.out.println("dtoGetDate = [" + mt.getDtoGetDate() + "]");
System.out.println("dtoGetUtcDate = [" + mt.getDtoGetUtcDate() + "]");
System.out.println("dtoSysDateTime = [" + mt.getDtoSysDateTime() + "]");
System.out.println("dtoSysUtcDateTime = [" + mt.getDtoSysUtcDateTime() + "]");
System.out.println("dtoSysDateTimeOffset = [" + mt.getDtoSysDateTimeOffset() + "]");

return mvt;
}
}

这是由 JUnit 测试执行的:
@Test
public void testDateData() throws Exception {
MikeTemp mt = dao.getMikeTemp();

assertNotNull("MT should not be null, but it is.", mt);
assertEquals(1, mt.getId());
assertEquals("Hello World!", mt.getBlah());
}

所有 println 的结果是:
id                   = [1]
blah = [Hello World!]
dtGetDate = [2012-02-15T08:58:41.577-06:00]
dtGetUtcDate = [2012-02-15T14:58:41.577-06:00]
dtSysDateTime = [2012-02-15T08:58:41.580-06:00]
dtSysUtcDateTime = [2012-02-15T14:58:41.600-06:00]
dtSysDateTimeOffset = [2012-02-15T08:58:41.600-06:00]
dtoGetDate = [2012-02-15T08:58:41.600-06:00]
dtoGetUtcDate = [2012-02-15T14:58:41.600-06:00]
dtoSysDateTime = [2012-02-15T08:58:41.600-06:00]
dtoSysUtcDateTime = [2012-02-15T14:58:41.600-06:00]
dtoSysDateTimeOffset = [2012-02-15T08:58:41.600-06:00]

由于该服务器位于美国中部时区,因此我绝对希望看到 -06:00 的某些结果,但绝对不是所有结果。我在途中错过了什么吗?正在调用 Joda DateTime(Object) ctor 带 java.util.Date反对在这种情况下正确的做法?我还可以/应该做什么而我没有做?

谢谢!

最佳答案

不,这不是这样做的方法。您正在使用 DateTime(Object) 带有 Date 的构造函数它只知道一个瞬间,并使用系统默认时区。

正如 BalusC 所写,你可以通过 Calendar进入 ResultSet.getTimestamp()如果您想自己指定时区 - 但这与保留数据库中已经存在的信息不同。

不清楚您使用的是哪个 JDBC 驱动程序,您可能不得不远离 SimpleJdbcCall ,但微软的JDBC驱动v3.0有 SQLServerCallableStatement.getDateTimeOffset (对于 SQLServerResultSet 也是如此),这大概会做正确的事情。鉴于您的数据类型并不是真正可移植的,这意味着您的代码不能真正是:(

你肯定需要保留偏移量吗?如果没有,您可能可以专注于使用“正常”JDBC 调用获得正确的即时结果——不幸的是,目前看起来它并没有这样做。

关于java - 将 SQL Server 日期数据放入 Joda 对象的最佳方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9334689/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com