日期:getDisplayName 方法仅在 CI 上向 dayOfWeek 添加点字符

Date: getDisplayName method adds point character to dayOfWeek only on CI

提问人:goemic 提问时间:12/10/2020 最后编辑:goemic 更新时间:12/10/2020 访问量:546

问:

与在本地运行 UnitTest 相比,在 CircleCI 上运行的 UnitTest 中调用返回不同的值。localDate.getDayOfWeek().getDisplayName

下面是简化的示例代码:

LocalDate localDate = LocalDate.of(2019, 12, 20);
String dayOfWeek = localDate.getDayOfWeek().getDisplayName(TextStyle.SHORT, Locale.GERMANY);

assertEquals("Fr", dayOfWeek); // actual = "Fr."

dayOfWeek仅在 CI 上包含“.”,但我不明白为什么以及如何(正确)修复它。

这是 UnitTest 的错误日志:

junit.framework.ComparisonFailure: expected:<Fr[.]> but was:<Fr[]>
..

提示:我正在使用 ThreeTen Android Backport

更新正如 @OleV.V. 和 @Arvind Kumar Avinash 所提到的,不同行为(本地和 CI)的原因是 JDK 版本(本地 8.x 和 CI 11.x)的差异。

这让我的问题有一部分悬而未决:“如何正确解决这个问题? 这是更改我的 CI docker 映像上的 JDK 版本的正确/唯一方法?

java android 格式化 localdate threetenbp

评论

0赞 Arvind Kumar Avinash 12/10/2020
goemic - 有什么更新吗?
0赞 Anonymous 12/10/2020
这回答了你的问题吗?JDK dateformatter 解析德语语言环境中的 DayOfWeek,java8 与 java9
0赞 Anonymous 12/10/2020
ThreeTenABP可以在CircleCI上运行吗?只是好奇。
1赞 goemic 12/10/2020
@OleV.V.我很确定这种不当行为与不同的 java 版本(本地和 CI)有关,但这并不能回答我关于如何正确修复它的问题

答:

2赞 Arvind Kumar Avinash 12/10/2020 #1

更新:

在查看了更新的问题后,问题似乎是因为在运行 CircleCI 的机器上缺少 ThreeTen Android Backport 的库。在没有此库的情况下,可能默认为在这台机器上重新编译代码时。您应该在这台机器上检查一些内容:java.time

  1. 如果库已成功导入。
  2. 如果有任何设置,可以在缺少某些类型时自动导入最合适的类型。
  3. 如果JDK版本与本地机器的JDK版本相同。

原答案:

你可以使用TextStyle.SHORT_STANDALONE

import java.util.Locale;

import org.threeten.bp.LocalDate;
import org.threeten.bp.format.TextStyle;

class Main {
    public static void main(String[] args) {
        LocalDate localDate = LocalDate.of(2019, 12, 20);
        String dayOfWeek = localDate.getDayOfWeek().getDisplayName(TextStyle.SHORT_STANDALONE, Locale.GERMAN);
        System.out.println(dayOfWeek);
    }
}

输出:

Fr

不过,我的系统上的输出中没有一个点。不过,如果您仍然想使用并且没有点(或任何标点符号),则可以将每个标点符号替换为空白字符串。TextStyle.SHORTTextStyle.SHORT

import java.util.Locale;

import org.threeten.bp.LocalDate;
import org.threeten.bp.format.TextStyle;

class Main {
    public static void main(String[] args) {
        LocalDate localDate = LocalDate.of(2019, 12, 20);
        String dayOfWeek = localDate.getDayOfWeek().getDisplayName(TextStyle.SHORT, Locale.GERMANY);
        System.out.println(dayOfWeek);

        // Remove all punctuation mark
        dayOfWeek = dayOfWeek.replaceAll("\\p{Punct}", "");
        System.out.println(dayOfWeek);
    }
}

输出:

Fr
Fr

注意:使用 API 更改的结果如下所示:TextStyle.SHORTjava.time

import java.time.LocalDate;
import java.time.format.TextStyle;
import java.util.Locale;

class Main {
    public static void main(String[] args) {
        LocalDate localDate = LocalDate.of(2019, 12, 20);

        String dayOfWeek = localDate.getDayOfWeek().getDisplayName(TextStyle.SHORT_STANDALONE, Locale.GERMANY);
        System.out.println(dayOfWeek);

        dayOfWeek = localDate.getDayOfWeek().getDisplayName(TextStyle.SHORT, Locale.GERMANY);
        System.out.println(dayOfWeek);

        // Remove all punctuation mark
        dayOfWeek = dayOfWeek.replaceAll("\\p{Punct}", "");
        System.out.println(dayOfWeek);
    }
}

输出:

Fr
Fr.
Fr

评论

0赞 goemic 12/10/2020
不幸的是,这并不能解决问题。我仍然在 CI 上收到错误:TextStyle.SHORT_STANDALONEjunit.framework.ComparisonFailure: expected:<Fr[.]> but was:<Fr[]>
0赞 Arvind Kumar Avinash 12/10/2020
@goemic - 查看错误消息,会通过,但随后你说,这令人惊讶。assertEquals("Fr.", dayOfWeek);...running on CircleCI returns a different value compared to running the UnitTest locally.
0赞 goemic 12/10/2020
迁移到(现在)不是一种选择,因为我们仍然面临一些 r8 脱糖问题。替换这些点是我已经在做的“黑客”修复,但我正在寻找一个真正的修复程序来使代码再次干净 - 并避免项目中出现过多的黑客;)java.time
0赞 goemic 12/10/2020
这绝对令人惊讶,这就是我发布这个问题的原因:D我认为这与 CI 的 docker 映像中使用的 jdk 版本有某种关系。
0赞 Arvind Kumar Avinash 12/10/2020
@goemic - 巧合的是,当您:)发布此评论时,我也在同一时间更新了答案。问题解决后,我会等待您的更新。即使我的答案不适合您,我也建议您发布自己的工作解决方案,这将对未来的访问者有所帮助。