[英]DateFormat UnitTest fails in Jenkins but not locally
I've made a unit-test of a Service, when I execute the Jenkins job, every test method pass correctly, except one. 我已经对服务进行了单元测试,当我执行Jenkins作业时,除一个测试方法外,其他所有测试方法均正确通过。
But this test method, works on my machine, both with Eclipse and using the mvn
command. 但是这种测试方法可以在我的机器上使用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));
}
The Service have mulitple methods: 该服务有多种方法:
getTodayTimestamp
give today Timestamp, this method is tested, it works on my machine and on Jenkins. getTodayTimestamp
提供今天的时间戳,此方法已经过测试,适用于我的机器和Jenkins。 dateToTimestamp
takes a date and a dateFormat as Strings, and returns the date as a Timestamp, this method is the one not working. dateToTimestamp
一个日期和一个dateFormat作为字符串,然后将日期作为时间戳返回,该方法不起作用。 The dateToTimestamp
method in the Service: 服务中的
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;
}
}
As I previously said, the test work perfectly on my pc, but not on Jenkins (adding the @Ignore
annotations to this method, makes the job successful). 就像我之前说过的那样,该测试可以在我的PC上完美运行,但不能在Jenkins上完美运行(向此方法添加
@Ignore
批注使该工作成功完成)。
When launching the job, I get this error: 启动作业时,出现以下错误:
Failed tests: dateToTimestamp(com.test.service.ServiceImplTest): expected:<2018-01-01 00:00:00.0> but was:<2017-12-31 00:00:00.0>
测试失败:dateToTimestamp(com.test.service.ServiceImplTest):预期:<2018-01-01 00:00:00.0>,但是:<2017-12-31 00:00:00.0>
What I can assure, is that even in Jenkins, the dateToTimestamp
method takes the parameters TARGET_RUN_DATE_OF_YEAR
, which is "2018-01-01"
and the dateFormart String as "YYYY-MM-dd"
. 我可以保证,是,即使在詹金斯
dateToTimestamp
方法需要的参数TARGET_RUN_DATE_OF_YEAR
,这是"2018-01-01"
和dateFormart字符串为"YYYY-MM-dd"
。 But still returns 2017-12-31 00:00:00.0
as Timestamp. 但仍会返回
2017-12-31 00:00:00.0
作为时间戳。
Any ideas? 有任何想法吗?
I am assuming that you wanted a Timestamp
for use with your SQL database. 我假设您想将
Timestamp
用于SQL数据库。 Don't use Timestamp
for that in 2019. That class is poorly designed and long outdated. 请勿在2019年使用
Timestamp
。该类的设计不佳,而且早已过时。
timestamp with time zone
(which it should be for a timestamp), use OffsetDateTime
in Java. timestamp with time zone
(应该是时间戳), OffsetDateTime
在Java中使用OffsetDateTime
。 timestamp
(without time zone), use LocalDateTime
in Java. timestamp
(无时区),请在Java中使用LocalDateTime
。 Code example: 代码示例:
String dateString = "2018-01-01";
OffsetDateTime odt = LocalDate.parse(dateString)
.atStartOfDay()
.atOffset(ZoneOffset.UTC);
System.out.println(odt);
Output is: 输出为:
2018-01-01T00:00Z
2018-01-01T00:00Z
Now you can pass your OffsetDateTime
to JDBC using something like: 现在,您可以使用以下方式将
OffsetDateTime
传递给JDBC:
yourPreparedStatement.setObject(4, odt);
I believe that you are experiencing the combination of two issues: 我相信您正在遇到两个问题的结合:
YYYY
in your format pattern string is incorrect. YYYY
是不正确的。 Uppercase Y
is for week based year and only useful with a week number. Y
用于基于周的年份,仅与星期数一起使用。 With the old and troublesome SimpleDateFormat
you would have needed lowercase y
for year. SimpleDateFormat
,则一年中需要使用小写的y
。 To demonstrate: 展示:
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));
Output on my computer (Danish locale, Europe/Copenhagen time zone): 我的计算机上的输出(丹麦语言环境,欧洲/哥本哈根时区):
Mon Jan 01 00:00:00 CET 2018
CET 2018年1月1日星期一00:00:00
However if I first do this: 但是,如果我首先这样做:
Locale.setDefault(Locale.US);
— then the output from the above snippet is different, namely: —那么以上代码段的输出是不同的,即:
Sun Dec 31 00:00:00 CET 2017
2017年12月31日星期日00:00:00 CET
What happens is that SimpleDateFormat
gives up on determining an exact date from week based year, month and day of month and instead just gives you the first date of the week based year. 发生的是,
SimpleDateFormat
放弃了从基于周的年,月和日中确定确切的日期,而只是给您基于周的年的第一个日期。 It's typical behaviour of SimpleDateFormat
to give you a result that cannot be right and nevertheless pretend that all is well. SimpleDateFormat
的典型行为是给您带来不正确的结果,但假装一切都很好。 In some locales the week begins on Monday, and you get Mon Jan 01, which coincidentally agrees with your string. 在某些地区,星期从星期一开始,您会遇到1月1日星期一,这恰好与您的字符串一致 。 In other locales, such as the US, the week starts on Sunday, so instead you get Sun Dec 31 of the previous year.
在其他地区,例如美国,一周从星期日开始,所以您将前一年的12月31日定为星期日。
Y
for year: java parsing string to date Y
相关问题: java解析日期字符串
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.