说我有以下代码:
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的特定情况。特别是因为“周”案例没有实用方法。
我理解你的困惑。不同之处在于withXx
方法与TemporalAdjusters
的工作方式不同。不同之处是:
withXx
方法或时间调整器。ChronoField.DAY_OF_WEEK
设置为1可将星期几设置为星期一。因此,withFirstDayOfWeek
方法或firstDayOfWeek
时间调整器中的任何一个都是危险的,并且会给一些用户带来惊人的结果。如果您确定只想考虑ISO周,即星期一是第一天,inputZonedDateTime.with(ChronoField.DAY_OF_WEEK, 1)
可以满足您的需求。否则,正确的解决方案是使用WeekFields
对象及其dayOfWeek()
时间字段。将此字段设置为1将根据WeekFields
对象表示的周定义设置为一周的第一天。
根据维基百科:
我试图考虑周日可能是本周的第一天,例如美国。
示例代码
// 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
的正确语言环境。与其他几个语言环境一起输出包括:
如果您质疑这是否是找到的正确方法:
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()));