我想使用Java8包Java从给定的星期和年份中获取星期一日期。时间但在某种程度上,我面临着这个问题,因为它并没有返回正确的日期。
private LocalDate getDateFromWeekAndYear(final String week,final String year){
LocalDate date = LocalDate.now();
date = date.with(WeekFields.ISO.dayOfWeek(), 1);
date = date.with(WeekFields.ISO.weekOfWeekBasedYear(), Long.parseLong(week));
date = date.with(WeekFields.ISO.weekBasedYear(), Long.parseLong(year));
return date;
}
例如:
我是否有任何逻辑错误或其他问题?
YearWeek.of ( 2013 , 1 ).atDay ( DayOfWeek.MONDAY )
你的期望不正确。2015-W53
的星期一是2015-12-28
,不是2014-12-28
,而是2015年,而不是2014年。没有理由期待2014年。如果您需要更多解释,请编辑您的问题以解释您的想法。
您可能会对日历年和基于周的年份感到困惑。在ISO 8601对基于周的年份的定义中,第一周包含日历年的第一个星期四。这意味着我们在这几年之间有一些重叠。日历年的最后几天可能位于下一个基于周的年份。反之亦然,日历年的前几天可能位于前一周。
例如,您可以在下面的屏幕截图中看到,2012日历的最后一天(12月31日)是2013年第1周的第1周。在另一个屏幕截图中,我们看到了相反的情况,2016年日历的前三天(1月1日、2日、,
我建议在你的项目中添加三个额外的库,以利用YearWeek
类。与其只传递年和周的整数,不如传递此类的对象。这样做会使您的代码更加自文档化,提供类型安全性,并确保有效值。
// Pass ( week-based-year-number, week-number ). *Not* calendar year! See the ISO 8601 standard.
YearWeek yw = YearWeek.of( 2013 , 1 );
你可以从那一周的任何一天提取。
LocalDate ld = yw.atDay( DayOfWeek.MONDAY );
让我们试试这种代码。
YearWeek yw1 = YearWeek.of ( 2013 , 1 );
LocalDate ld1 = yw1.atDay ( DayOfWeek.MONDAY );
YearWeek yw2 = YearWeek.of ( 2015 , 53 );
LocalDate ld2 = yw2.atDay ( DayOfWeek.MONDAY );
System.out.println ( "yw1: " + yw1 + " Monday: " + ld1 );
System.out.println ( "yw2: " + yw2 + " Monday: " + ld2 );
yw1:2013-W01星期一:2012-12-31
yw2:2015-W53星期一:2015-12-28
提示:要在Calendar.app中的Mac上查看这些ISO 8601标准周数字,请设置System首选项
首先,你需要计算一年中第一周的第一个星期一,然后简单地加上日期的7的倍数。
public static LocalDate firstMonday(int week, int year) {
LocalDate firstMonOfFirstWeek = LocalDate.now()
.with(IsoFields.WEEK_BASED_YEAR, year) // year
.with(IsoFields.WEEK_OF_WEEK_BASED_YEAR, 1) // First week of the year
.with(ChronoField.DAY_OF_WEEK, 1); // Monday
// Plus multi of 7
return firstMonOfFirstWeek.plusDays( (week - 1) * 7);
}
public static void main(String[] args) {
System.out.println(firstMonday(1, 2013)); // 2012-12-31
System.out.println(firstMonday(53 ,2015 )); // 2015-12-28
}
这比OP和大多数答案显示的部分无效期望要困难得多。
首先说:定义基于周的操作的正确顺序是非常重要的。OP首先应用了日操纵,然后是基于年的操纵。正确的做法是反过来!我将展示正确的helper方法实现:
public static void main(String... args) {
System.out.println(
getDateFromWeekAndYear("53", "2015")); // 2015-12-28, NOT 2014-12-28
System.out.println(
getDateFromWeekAndYear("53", "2015").get(WeekFields.ISO.weekOfWeekBasedYear())); // 53
System.out.println(
getDateFromWeekAndYear("53", "2014")); // 2014-12-29
System.out.println(
getDateFromWeekAndYear("53", "2014").get(WeekFields.ISO.weekOfWeekBasedYear())); // 1
}
private static LocalDate getDateFromWeekAndYear(final String week,final String year) {
int y = Integer.parseInt(year);
LocalDate date = LocalDate.of(y, 7, 1); // safer than choosing current date
// date = date.with(WeekFields.ISO.weekBasedYear(), y); // no longer necessary
date = date.with(WeekFields.ISO.weekOfWeekBasedYear(), Long.parseLong(week));
date = date.with(WeekFields.ISO.dayOfWeek(), 1);
return date;
}
如果您不遵守此特定订单,那么您有时确实会收到输入2015-W53的2014年日期(取决于当前日期)。
第二个问题:我也避免了以当前日期开始,以避免接近日历年的开始或结束(日历年!=以周为基础的一年),而是选择年中作为起点。
第三个问题是对2014年(以周为基础)第53周的宽大处理。它不存在,因为2014年只有52周!!!严格的算法应该识别和拒绝这样的输入。因此,我建议不要使用YearWeek.of(2014,53)
(在外部库Threeten-Extra)导致2015年的第一周,也请参阅其javadoc。比如此宽大的处理要好
YearWeek yw = YearWeek.of(2014, 52);
if (yw.is53WeekYear()) {
yw = YearWeek.of(2014, 53);
}
或者使用我自己的时间库Time4J中的代码(与YearWeek
相比,其类CalendarWeek具有额外的i18n功能和额外的周算术):
CalendarWeek.of(2014, 53); // throws an exception
System.out.println(CalendarWeek.of(2014, 1).withLastWeekOfYear()); // 2014-W52
仅使用java.time
-包:
使用这样的外部库至少有助于以透明的方式解决第一个问题。如果您不愿意添加额外的依赖项,那么您可以这样做来处理第53周(如果无效):
如果表达式周末字段。应用于helper方法的结果上的ISO. ousOfBookBasedYear()
会产生值1,那么您就知道第53周是无效的。然后你可以决定是接受宽大处理还是抛出一个例外。但是无声调节这种无效的输入是恕我直言不好的设计。
问题内容: 我需要输出从当前日期开始的未来12个月的日期列表(仅星期一和星期二),如下所示: 2010年1月 星期二2010年1月12日 星期一2010 年1月18日 星期二2010 年1月19日 星期一2010 年1月25 日星期一2010年 2月2日 星期二2010 年2月8日 星期一2010年2月9日星期二2010 年 2月 15 日星期一2010年2月15日 星期二2010 年2月16日
问题内容: 我想确定一个日期并计算出其星期数。 到目前为止,我有以下内容。它应该是42时返回24。 数字反转是巧合吗?还是我快到了? 问题答案: 今天,使用PHP的对象会更好: 这是因为in中,它是这样的: 因此,您的订单是错误的。
问题内容: 如果可能的话,在以下情况下,我希望使用joda或非joda解决方案 假设我的一周从2012年5月2日开始,给定的当前日期为02/22/2011。我需要计算给定当前日期的星期开始和结束日期。因此,我的解决方案的星期应该从02/19开始,而星期在02/25结束。为简单起见,我将我的工作日设置为02/05/2011,但是可能是任何一天,我的工作日始终为7天。 我现有的代码如下,但似乎无法按预
问题内容: 如何获得当前一周的星期一和星期五的日期? 我有以下代码,但是如果当前日期是星期日或星期六,则它将失败。 问题答案: 这些strtotime输入效果很好: 您需要做的就是将逻辑包装在一些if语句中。
问题内容: 我目前有此代码: 这是Date对象的扩展。 我需要做同样的事情,但是让日历返回我从星期一开始而不是星期日的一周中的几天。 问题答案: 您只需要使用iso8601日历获取一周中的第一天,其中第一个工作日为星期一,并添加0至6天。尝试这样:
问题内容: 我有一个日期,以及如何使所有日期都落在给定日期所属的一周的Java中? 有人可以帮我这个吗。 我正在尝试获取给定日期的星期日期,我已经解释了为什么这个问题不是重复的,请在评论前阅读。 问题答案: 您可以尝试以下方式, 输出值