与其他机器上的SimpleDateFormat的ComparisonFailure

时间:2016-03-24 12:35:28

标签: android junit simpledateformat

在Android项目中,我创建了以下函数来输出格式化的日期字符串:

static final String INPUT_DATE_PATTERN = "yyyy-MM-dd'T'HH:mm:ssZ";

public static long getDateInMilliseconds(String text) {
    Date date = getDate(text, INPUT_DATE_PATTERN);
    return date == null ? 0 : date.getTime();
}

public static String getFormattedDate(long dateInMillisecons) {
    Date date = new Date(dateInMillisecons);
    DateFormat dateFormat = SimpleDateFormat.getDateTimeInstance(
            SimpleDateFormat.FULL, SimpleDateFormat.SHORT);
    return dateFormat.format(date);
}

private static Date getDate(String text, String pattern) {
    SimpleDateFormat dateFormat = new SimpleDateFormat(pattern, Locale.US);
    Date date = null;
    try {
        date = dateFormat.parse(text);
    } catch (ParseException e) {
        e.printStackTrace();
    }
    return date;
}

文本的示例值是:

"2016-04-02T09:00:00+02:00"

这意味着时区+02:00符合RFC 822 time zone standard。 但是,我无法依赖字符串中的时区保持不变 - 它由远程机器提供。

这是两个单元测试,用于检查所需的行为。

@Test
public void getFormattedDateWithSummerTime() {
    assertThat(DateFormatting.getFormattedDate(1459580400000L))
            .isEqualTo("Saturday, April 2, 2016 9:00 AM");
}

@Test
public void getFormattedDateWithLeapYear() {
    assertThat(DateFormatting.getFormattedDate(1456783200000L))
            .isEqualTo("Monday, February 29, 2016 11:00 PM");
}

我的机器上的测试传递。但是,当我让CI构建在云中运行时,他们失败,并出现以下错误输出:

  

org.junit.ComparisonFailure:
  预计:" 2016年4月2日星期六上午9:00"
  实际:" 2016年4月2日星期六上午7:00"

     

org.junit.ComparisonFailure:
  预计:" 2016年2月29日星期一晚上11:00"
  实际:" 2016年2月29日星期一晚上10:00"

1 个答案:

答案 0 :(得分:0)

失败的原因很简单。如果您使用DateFormatting.getFormattedDate(1459580400000L),那么您实际应用系统时区(只需设置SimpleDateFormat - 实例,而不使用任何明确的时区)。

因此,您需要根据系统时区创建格式化字符串,并将其与同一时间的硬连线固定本地表示字符串进行比较,该字符串可能适用于您当地的时区,但不适用于其他系统。 < / p>

您的JUnit测试不是普遍适用的。更好地比较全局时间戳,如“自Unix时代以来经过的毫秒数”,而不是比较本地表示。