根据Java 8中的LocalDate.now()获取星期几的日期 |
您所在的位置:网站首页 › 美国今日星期几 › 根据Java 8中的LocalDate.now()获取星期几的日期 |
我想根据LocalDate.now()获取一周中第一天的日期。 JodaTime可以进行以下操作,但似乎已从Java 8的新Date API中删除。 12LocalDate now = LocalDate.now(); System.out.println(now.withDayOfWeek(DateTimeConstants.MONDAY));我无法调用" withDayOfWeek()",因为它不存在。 所以我的问题是:如何基于某些LocalDate获取星期几的日期? 请注意,表达式System.out.println(now.with(DayOfWeek.MONDAY))由于使用ISO-8601而与语言环境无关,因此它总是向后跳至上一个星期一(或保留在星期一,以防日期已指向星期一)。 因此,在美国或其他一些国家/地区(星期从星期日开始)可能无法正常工作-如果日期指向星期日,now.with(DayOfWeek.MONDAY)不会跳到星期一。 如果您需要解决这些问题,最好使用本地化字段WeekFields.dayOfWeek(): 123456LocalDate now = LocalDate.now(); TemporalField fieldISO = WeekFields.of(Locale.FRANCE).dayOfWeek(); System.out.println(now.with(fieldISO, 1)); // 2015-02-09 (Monday) TemporalField fieldUS = WeekFields.of(Locale.US).dayOfWeek(); System.out.println(now.with(fieldUS, 1)); // 2015-02-08 (Sunday)由于下面的评论,另一个示例: 12345678910LocalDate ld = LocalDate.of(2017, 8, 18); // Friday as original date System.out.println( ld.with(DayOfWeek.SUNDAY)); // 2017-08-20 (2 days later according to ISO) // Now let's again set the date to Sunday, but this time in a localized way... // the method dayOfWeek() uses localized numbering (Sunday = 1 in US and = 7 in France) System.out.println(ld.with(WeekFields.of(Locale.US).dayOfWeek(), 1L)); // 2017-08-13 System.out.println(ld.with(WeekFields.of(Locale.FRANCE).dayOfWeek(), 7L)); // 2017-08-20以美国为例,这很清楚地表明,居住在美国的人会期望去到下一个而不是下一个星期日,因为星期日被认为是美国一周中的第一天。基于ISO的简单表达式with(DayOfWeek.SUNDAY)忽略了此本地化问题。 相关讨论 仅供参考,WeekFields.of(Locale.getDefault()).getFirstDayOfWeek()返回当前语言环境的配置的一周的第一天(例如SUNDAY,MONDAY等)。不是日期。 @MenoHochschild为什么枚举DayOfWeek??在某些地区(例如美国)不起作用?有什么问题 @BasilBourque如果今天是星期日,并且我们在美国(星期天作为一周的第一天),则today.with(MONDAY)将转到第二天(+1),但是如果我们在欧洲,则需要返回6天(-6) 。表达式with(day-of-week)表示要在SAME日历周内进入星期几,这取决于星期几。 @BasilBourque为澄清起见,我之前的评论与WeekFields的使用有关(希望说with(day-of-week, 1))。如果您使用首选方法(基于enum-with(MONDAY)),则该操作仅基于ISO样式,假定始终将星期一作为一周的第一天。不幸的是,WeekFields不能直接用于枚举,而只能用于较长的数字(错误的设计),因此它比应使用的便捷性和秘密性更高(today.with(WeekFields.of(Locale.US).dayOfWeek(), MONDAY)无法编译)。 @MenoHochschild我对您的评论和声明now.with(DayOfWeek.MONDAY)在美国无法使用感到有些困惑。我有一个使用with(DayOfWeek.SUNDAY)的测试用例,并在今天(星期五)使用en_US区域设置和PST时区(-Duser.language=en -Duser.country=US -Duser.timezone=AmericaLos_Angeles)或欧洲区域设置和时区运行它,这给我带来了始终相同的结果-在两种情况下,我都越来越下一个星期日(8月20日),我想您要说的是美国时区(因为它是本周的一部分),所以我会在上个星期日得到。你能澄清一下吗? @barthand首先,时区在这里根本不相关,仅与语言环境相关。但是,如果仅应用with(DayOfWeek.SUNDAY),那么语言环境也会被忽略,并且日期(如果不是星期日)将始终向前跳转,因为星期日是ISO-8601中的一周的最后一天。 @MenoHochschild感谢您的回答!因此,由于with(DayOfWeek)始终使用ISO-8601并忽略语言环境,因此这意味着with(DayOfWeek.MONDAY)始终会向后跳到上一个星期一(如果是星期一以外的任何一天),或者将保留在同一天(如果日期指向已经是星期一),对吗? @barthand确实如此。 @MenoHochschild因此,也许有必要在您的答案中对其进行解释-请注意,表达式System.out.println(now.with(DayOfWeek.MONDAY));在美国或其他一些国家或地区将不起作用。有点误导,因为实际上它在美国和其他任何国家都可以以相同的方式(只是非本地化)工作。 @barthand感谢您的提示。我现在已经更新了第一句话/句子,希望现在可以更清楚。 您如何准确地获取当前语言环境的firstDayOfWeek而不是指定它? @androiddeveloper参见javadoc @MenoHochschild您的意思是:WeekFields.of(Locale.getDefault())。firstDayOfWeek吗?如果是这样,为什么不将其发布为真实答案?另外,我认为幕后的代码实际上仍然使用Calendar类,所以最好改用Calendar类... @androiddeveloper是的,根据您的评论,我的意思是WeekFields.of(Locale.getDefault()).getFirstDayOfWeek() ,但这不是OP的问题的答案,OP要求提供本周第一天的完整日历日期。 @MenoHochschild好了,所以我实际上在这里创建了一个答案:stackoverflow.com/a/48150270/878126尝试 1System.out.println(now.with(DayOfWeek.MONDAY)); 相关讨论 我只是想补充一点,并不是地球上的所有地方都具有同一周的开始日期。如果需要,可以通过Calendar#getFirstDayOfWeek获得 我们能否以某种方式将星期更改为从星期日开始,并使用相同的命令获取星期的第一天? 无法正确处理区域设置,并非所有区域设置都以星期一作为一周的第一天开始。尽管有所有先前的答案,我仍然必须深入研究Java8在做什么,所以这是我发现最直观的方法: LocalDate implements Temporal with(TemporalField field, long newValue) Returns an object of the same type as this object with the specified field altered. 因此,我们必须告诉它要更改(DAY_OF_WEEK)的日期部分并更改为哪个值。 如果您怀疑一周中的天数可能是从0到6或从1到7: 123 System.out.printf("first day of week (0 or 1) == %d ", ChronoField.DAY_OF_WEEK.range().getMinimum()); 1first day of week (0 or 1) == 1我必须弄清楚我的JDK提供的默认值-YMMV: 123456 System.out.printf("default zone offset==[%s] ", ZoneId.systemDefault()); System.out.printf("1st day of week==%s ", WeekFields.of(Locale.getDefault()).getFirstDayOfWeek()); 12default zone offset==[Europe/London] 1st day of week==MONDAY因此,如果我根据这些默认值执行一些代码,如下所示: 1234567 LocalDate localDate = LocalDate.now(); System.out.printf("localDate == %s ", localDate); System.out.printf("localdate first day of week == %s (%s) ", localDate.with(ChronoField.DAY_OF_WEEK, 1), localDate.with(ChronoField.DAY_OF_WEEK, 1).getDayOfWeek()); 12localDate == 2017-10-24 localdate first day of week == 2017-10-23 (MONDAY)然后Java使用ChronoField.DAY_OF_WEEK,它不仅定义了我们要更改日期的哪一部分,还定义了如何更改日期。 因此,如果希望我们的代码处理用户在一周的第一天指定的内容,则可以使用WeekFields.of()工厂方法来创建自己的定义,以定义基于周的计算的方式。 使用此方法,我们可以将自己的DayOfWeek参数传递给with(),以所需的方式进行日期计算: 12345 TemporalField myWeek = WeekFields.of(DayOfWeek.SUNDAY, 1).dayOfWeek(); System.out.printf("configured localdate first day of week == %s (%s) ", localDate.with(myWeek, 1), localDate.with(myWeek, 1).getDayOfWeek()); 1configured localdate first day of week == 2017-10-22 (SUNDAY)要了解更多信息,请查看LocalDate.with()中的代码,这很有趣。 感谢来自这个问题。 12345678910Calendar cal = Calendar.getInstance(); cal.set(Calendar.HOUR_OF_DAY, 0); // ! clear would not reset the hour of day ! cal.clear(Calendar.MINUTE); cal.clear(Calendar.SECOND); cal.clear(Calendar.MILLISECOND); // get start of this week in milliseconds cal.set(Calendar.DAY_OF_WEEK, cal.getFirstDayOfWeek()); System.out.println("Start of this week: " + cal.getTime()); System.out.println("... in milliseconds: " + cal.getTimeInMillis()); 相关讨论 感谢您的注意!但是,我一直在寻找使用LocalDate的Java 8方法。如果我想将星期一作为当前一周的第一天,它将对我有用: 1LocalDate mondayDate = LocalDate.now().with(WeekFields.of(Locale.FRANCE).getFirstDayOfWeek());LocalDate似乎没有此功能,但是WeekFields(来自Java-8 API)具有(此处)。因此,您可以执行以下操作: 1WeekFields.of(Locale.getDefault()).firstDayOfWeek.value这将返回一周中第一天的值,从星期一的1开始,到星期日的7结束。 使用示例(在Kotlin中),以获取设置了dayOfWeek的新LocalDate,并在时间上向后而不是向前: 1234567891011/**@param targetDayOfWeek day of week to go to, starting from 1 as Monday (and 7 is Sunday) */ fun LocalDate.minusDaysToDayOfWeek(targetDayOfWeek: Int = WeekFields.of(Locale.getDefault()).firstDayOfWeek.value): LocalDate { //conversion so that Sunday is 0, Monday is 1, etc: val diffDays = (dayOfWeek.value % 7) - (targetDayOfWeek % 7) val result = when { diffDays == 0 -> this diffDays minusDays((7 + diffDays).toLong()) else -> minusDays(diffDays.toLong()) } return result }输入输出示例: 123456789101112131415162017-12-31 -> 2017-12-31 2018-01-01 -> 2017-12-31 2018-01-02 -> 2017-12-31 2018-01-03 -> 2017-12-31 2018-01-04 -> 2017-12-31 2018-01-05 -> 2017-12-31 2018-01-06 -> 2017-12-31 2018-01-07 -> 2018-01-07 2018-01-08 -> 2018-01-07 2018-01-09 -> 2018-01-07 2018-01-10 -> 2018-01-07 2018-01-11 -> 2018-01-07 2018-01-12 -> 2018-01-07 2018-01-13 -> 2018-01-07 2018-01-14 -> 2018-01-14 2018-01-15 -> 2018-01-14这是一个示例函数,可以及时转到目标星期几: 123456789101112131415161718fun LocalDate.plusDaysToDayOfWeek(targetDayOfWeek: Int = getLastDayOfWeek()): LocalDate { val diffDays = (targetDayOfWeek % 7) - (dayOfWeek.value % 7) val result = when { diffDays == 0 -> this diffDays plusDays((7 + diffDays).toLong()) else -> plusDays(diffDays.toLong()) } return result } /**@return the last day of week, when 1 is Monday ... 7 is Sunday) */ @JvmStatic fun getLastDayOfWeek(firstDayOfWeek: DayOfWeek = WeekFields.of(Locale.getDefault()).firstDayOfWeek): Int { return when (firstDayOfWeek) { DayOfWeek.MONDAY -> DayOfWeek.SUNDAY.value else -> firstDayOfWeek.value - 1 } }顺便说一句,奇怪的是我认为新API幕后的代码实际上仍然使用Calendar类。 如果您讨厌使用LocalDate的dayOfWeek(就像我一样),并且更喜欢使用Calendar的日历,则可以使用以下简单的转换器: 12345678910111213141516171819202122fun DayOfWeek.toCalendarDayOfWeek(): Int { return when (this) { DayOfWeek.SATURDAY -> Calendar.SATURDAY else -> (this.value + 1) % 7 } } @JvmStatic fun convertLocalDateDayOfWeekToCalendarDayOfWeek(localDateDayOfWeek: Int): Int { return when (localDateDayOfWeek) { DayOfWeek.SATURDAY.value -> Calendar.SATURDAY else -> (localDateDayOfWeek + 1) % 7 } } @JvmStatic fun convertFromCalendarDayOfWeekToLocalDateDayOfWeek(calendarDayOfWeek: Int): Int { return when (calendarDayOfWeek) { Calendar.SUNDAY -> DayOfWeek.SUNDAY.value else -> calendarDayOfWeek - 1 } }正如Ray的正确答案所说,您可以调用with并传递DayOfWeek枚举。 时区 请注意,时区对于确定"今天"的日期至关重要。在任何时候,日期都会因您在地球上的位置而异。 12ZoneId zoneId = ZoneId.of ("America/Montreal" ); LocalDate firstDayOfThisWeek = LocalDate.now ( zoneId ).with ( DayOfWeek.MONDAY );如果您未指定时区,则将静默应用JVM的当前默认时区。当心:该默认值可以在运行时随时更改!最好指定您想要的/预期的时区。 ZonedDateTime 您可以将时区(a ZoneId)应用于LocalDate,以获得表示一周中第一时刻的ZonedDateTime。 1ZonedDateTime thisWeekStart = firstDayOfThisWeek.atStartOfDay ( zoneId ); 12345678910111213141516public void getWeekFromADateOfAMonth(){ String date ="2019-01-02T18:25:43.511Z"; TemporalField fieldISO = WeekFields.of(Locale.US).dayOfWeek(); ZonedDateTime dateTime = ZonedDateTime.parse(date); int week = dateTime.get ( IsoFields.WEEK_OF_WEEK_BASED_YEAR ); int weekYear = dateTime.get ( IsoFields.WEEK_BASED_YEAR ); System.out.println ("now:" + dateTime +" is week:" + week +" of weekYear:" + weekYear ); int startDate = dateTime.with(fieldISO,1).getDayOfMonth(); int endDate = dateTime.with(fieldISO,7).getDayOfMonth(); String startMonth = String.valueOf(dateTime.with(fieldISO,1).getMonth()); String endMonth = String.valueOf(dateTime.with(fieldISO,7).getMonth()); }有了Joda Time,您如何看待 1now.toString("EEEE", locale) 相关讨论 我在javadoc中没有看到这样的方法。 docs.oracle.com/javase/8/docs/api/java/time/ 我不好的是,这是一个乔达时间方法,我应该精确 |
今日新闻 |
点击排行 |
|
推荐新闻 |
图片新闻 |
|
专题文章 |
CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭 |