使用with *函数,TemporalAdjusters或设置TemporalFields调整ZonedDateTimes之间有什么区别吗?

问题描述 投票:1回答:2

说我有以下代码:

java.time.ZonedDateTime inputZonedDateTime = inputDate.toInstant().atZone(zoneId);
ZonedDateTime flattenedDateTime = inputZonedDateTime.withDayOfYear(1);

奇怪的是,这种实用方法几周都不存在,所以几周来我实现了这样:

flattenedDateTime = inputZonedDateTime.with(java.time.temporal.ChronoField.DAY_OF_WEEK, 1);

然后你也可以这样做:

flattenedDateTime = inputZonedDateTime.with(TemporalAdjusters.firstDayOfMonth());

(几周内也没有)

调整日期的这三种方式之间是否有任何区别?我想确保它们在功能上始终等效,以便我确信我可以互换使用它们,以便将ChronoUnit调整为1的特定情况。特别是因为“周”案例没有实用方法。

java datetime java-8 dayofweek
2个回答
2
投票

我理解你的困惑。不同之处在于withXx方法与TemporalAdjusters的工作方式不同。不同之处是:

  • 一年中的第一天和当月的第一天是明确定义的,因此很容易构建为withXx方法或时间调整器。
  • 一周的第一天因文化而异。在某些地方,一周从周日或其他日子开始。将ChronoField.DAY_OF_WEEK设置为1可将星期几设置为星期一。因此,withFirstDayOfWeek方法或firstDayOfWeek时间调整器中的任何一个都是危险的,并且会给一些用户带来惊人的结果。

如果您确定只想考虑ISO周,即星期一是第一天,inputZonedDateTime.with(ChronoField.DAY_OF_WEEK, 1)可以满足您的需求。否则,正确的解决方案是使用WeekFields对象及其dayOfWeek​()时间字段。将此字段设置为1将根据WeekFields对象表示的周定义设置为一周的第一天。

根据维基百科:

  • 在中东的大部分地区,本周从星期六开始。
  • 它在周日开始在加拿大,美国,印度,日本,台湾,香港,澳门,以色列,埃及,南非,菲律宾以及大部分拉丁美洲。
  • 欧盟和大多数其他欧洲国家,大多数亚洲和大洋洲使用星期一(与ISO协议)。

我试图考虑周日可能是本周的第一天,例如美国。

示例代码

    // Don’t set default locale from production code, it’s for demonstration only
    Locale.setDefault(Locale.forLanguageTag("ar-SD"));

    WeekFields wf = WeekFields.of(Locale.getDefault());
    DateTimeFormatter formatter = DateTimeFormatter
            .ofLocalizedDateTime(FormatStyle.FULL, FormatStyle.MEDIUM)
            .withLocale(Locale.ENGLISH);

    ZonedDateTime inputZonedDateTime
            = ZonedDateTime.of(2019, 3, 3, 12, 0, 0, 0, ZoneId.of("Asia/Amman"));
    ZonedDateTime flattenedDateTime = inputZonedDateTime.with(wf.dayOfWeek(), 1);
    System.out.println("First day of week in "
            + Locale.getDefault().getDisplayCountry(Locale.ENGLISH)
            + " is " + flattenedDateTime.format(formatter));

苏丹的第一天是2019年3月2日星期六,中午12:00:00

当然,您可以通过其他方式获得WeekFields.of的正确语言环境。与其他几个语言环境一起输出包括:

  • ES-PY: 巴拉圭的第一天是2019年3月3日星期日,中午12:00:00
  • MG-MG: 马达加斯加的第一天是2019年2月25日星期一,中午12:00:00

链接:Wikipedia article: week


0
投票

如果您质疑这是否是找到的正确方法:

  1. 给我划区日期时间,日期为星期几,适合作为星期一。 示例:05-03-2019 .... - > 04-03-2019 ....
  2. 给我划区日期时间,日期适合作为一个月的第一天! 示例:05-03-2019 .... - > 01-03-2019 ....

然后答案是肯定的。

        ZoneId zoneID = ZoneId.of( "Europe/Belgrade" ) ;
        ZonedDateTime zoneDateTime = ZonedDateTime.now(zoneID) ;

        System.out.println(zoneDateTime.withDayOfMonth(1));
        System.out.println(zoneDateTime.withMonth(1));
        System.out.println(zoneDateTime.with(ChronoField.DAY_OF_WEEK,1));
        System.out.println(zoneDateTime.with(TemporalAdjusters.firstDayOfMonth()));
© www.soinside.com 2019 - 2024. All rights reserved.