gpt4 book ai didi

java - DateFormat UnitTest 在 Jenkins 中失败,但在本地失败

转载 作者:行者123 更新时间:2023-11-30 01:46:09 26 4
gpt4 key购买 nike

我已经对服务进行了单元测试,当我执行 Jenkins 作业时,每个测试方法都正确通过,除了一个。
但这个测试方法可以在我的机器上运行,无论是使用 Eclipse 还是使用 mvn 命令。

    // TARGET_RUN_DATE_OF_YEAR = "2018-01-01"
@Test
public void dateToTimestamp() {
Service service = getService();

String df = "YYYY-MM-dd";
String invalid = "INVALID";

// Check success
Timestamp timestamp = service.dateToTimestamp(TARGET_RUN_DATE_OF_YEAR, df);
Assert.assertEquals(service.getTodayTimestamp(), timestamp); // <-- Fail here
// Check failure
Assert.assertNull(service.dateToTimestamp(TARGET_RUN_DATE_OF_YEAR, invalid));
Assert.assertNull(service.dateToTimestamp(invalid, df));
}

该服务有多种方法:

  • getTodayTimestamp 给出今天的时间戳,此方法经过测试,在我的机器和 Jenkins 上都有效。
  • dateToTimestamp 将日期和 dateFormat 作为字符串,并将日期作为时间戳返回,此方法不起作用。

服务中的dateToTimestamp方法:

    private Timestamp dateToTimestamp(String date, DateFormat df) throws ParseException {
return new Timestamp(df.parse(date).getTime());
}

@Override
public Timestamp dateToTimestamp(String date, String dateFormatString) {
try {
DateFormat df = new SimpleDateFormat(dateFormatString);
return dateToTimestamp(date, df);
} catch (Exception e) {
log.warn("Exception during conversion of date to timestamp, exception : {}", e);
return null;
}
}

正如我之前所说,测试在我的电脑上完美运行,但在 Jenkins 上却不行(向此方法添加 @Ignore 注释,使工作成功)。
启 Action 业时,我收到此错误:

Failed tests: dateToTimestamp(com.test.service.ServiceImplTest): expected:<2018-01-01 00:00:00.0> but was:<2017-12-31 00:00:00.0>

我可以保证的是,即使在 Jenkins 中,dateToTimestamp 方法也会采用参数TARGET_RUN_DATE_OF_YEAR,即“2018-01-01” code> 和 dateFormat 字符串为 "YYYY-MM-dd"。但仍返回 2017-12-31 00:00:00.0 作为时间戳。

有什么想法吗?

最佳答案

java.time

我假设您想要一个用于 SQL 数据库的时间戳。 2019 年不要使用 Timestamp。该类设计不佳且早已过时。

  • 如果 SQL 端的数据类型是timestamp with time zone(它应该是时间戳),请在 Java 中使用 OffsetDateTime
  • 如果在 SQL 端您只需要一个时间戳(不含时区),请在 Java 中使用 LocalDateTime

代码示例:

    String dateString = "2018-01-01";
OffsetDateTime odt = LocalDate.parse(dateString)
.atStartOfDay()
.atOffset(ZoneOffset.UTC);

System.out.println(odt);

输出是:

2018-01-01T00:00Z

现在您可以使用以下方法将 OffsetDateTime 传递给 JDBC:

    yourPreparedStatement.setObject(4, odt);

您的代码出了什么问题?

我相信您同时遇到了两个问题:

  • 在格式模式字符串中使用大写的 YYYY 是不正确的。大写的 Y 表示基于周的年份,并且仅对周数有用。使用旧的且麻烦的 SimpleDateFormat,您需要小写的 y 来表示年份。
  • 您的计算机(上的 JVM)和 Jenkins 服务器具有不同的默认区域设置。

演示:

    String dateString = "2018-01-01";
String dateFormatString = "YYYY-MM-dd"; // Incorrect format pattern string
DateFormat df = new SimpleDateFormat(dateFormatString);
System.out.println(df.parseObject(dateString));

我的计算机上的输出(丹麦语言环境、欧洲/哥本哈根时区):

Mon Jan 01 00:00:00 CET 2018

但是如果我首先这样做:

    Locale.setDefault(Locale.US);

——那么上面代码片段的输出是不同的,即:

Sun Dec 31 00:00:00 CET 2017

所发生的情况是,SimpleDateFormat 放弃根据基于周的年、月和月中的日来确定确切的日期,而是只为您提供基于周的年份的第一个日期。 SimpleDateFormat 的典型行为是给您一个不可能正确的结果,但又假装一切正常。在某些区域设置中,一周从星期一开始,您会得到 Mon Jan 01,这恰好与您的字符串一致。在其他地区(例如美国),一周从星期日开始,因此您会看到前一年的 12 月 31 日星期日。

链接

关于java - DateFormat UnitTest 在 Jenkins 中失败,但在本地失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57867886/

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