当前位置: 首页 > 知识库问答 >
问题:

在Java中,对于给定的日期,检测该月的第n天,然后在接下来的6个月内确定相同的日期

元彦君
2023-03-14

对于给定的日期,例如2018-03-05,我如何检测到它是该月的第一个星期一?

在确定了这个事实之后,接下来的六个月里,我该如何计算这个月的第n天呢?例如,2018-04-02星期一和2018-05-03星期一。

就像这个问题,但使用Java。

我尝试了这段代码,但没有得到预期的结果。我期待的是:

[2018-04-02, 2018-05-07, 2018-06-04, 2018-07-02, 2018-08-06, 2018-09-03]

也许我误解了ChronoField。ALIGNED_DAY_OF_WEEK_IN_MONTH

LocalDate ld = LocalDate.parse( "2018-03-05" );
int alignedDayOfWeekInMonth = ld.get( ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH );
DayOfWeek dayOfWeek = ld.getDayOfWeek();
YearMonth ym = YearMonth.from( ld );

int countMonths = 6;
List < LocalDate > localDates = new ArrayList <>( countMonths );
TemporalAdjuster ta = TemporalAdjusters.dayOfWeekInMonth( alignedDayOfWeekInMonth , dayOfWeek );
for ( int i = 1 ; i <= countMonths ; i++ ) {
    LocalDate firstOfMonth = ym.plusMonths( i ).atDay( 1 );
    LocalDate localDate = firstOfMonth.with( ta );
    localDates.add( localDate );
}

转储到控制台。

System.out.println( "ld.toString(): " + ld );
System.out.println( "alignedDayOfWeekInMonth: " + alignedDayOfWeekInMonth );
System.out.println( "dayOfWeek.toString(): " + dayOfWeek );
System.out.println("ym.toString(): " + ym);
System.out.println( "localDates: " + localDates );

当运行。

ld.toString(): 2018-03-05
alignedDayOfWeekInMonth: 5
dayOfWeek.toString(): MONDAY
ym.toString(): 2018-03
localDates: [2018-04-30, 2018-06-04, 2018-07-02, 2018-07-30, 2018-09-03, 2018-10-01]

一个相关的问题,但使用的是遗留的日期时间类,而不是现代java。时间类:在Java中查找某个日期在一个月内发生的第n次

共有3个答案

阎晗日
2023-03-14

这段代码一点也不花哨,但很管用:)

public static void main(String[] args) {    
    LocalDate ld = LocalDate.parse( "2018-03-04" );
    DayOfWeek dayOfWeek = DayOfWeek.WEDNESDAY;

    LocalDate first = ld.withDayOfMonth(1);

    List<LocalDate> firstDays = new ArrayList<>();
    //I deliberately included the start date in the loop. 
    //Easily fixed if it shouldn't be included
    for (int i = 0; i <= 6; i++) {
        LocalDate firstDay = getFirstDay(first.plusMonths(i), dayOfWeek);
        firstDays.add(firstDay);
    }
}

static LocalDate getFirstDay(LocalDate date, DayOfWeek searchedDay) {
    LocalDate temp = date;
    int i = 0;
    while (temp.getDayOfWeek() != searchedDay) {
         temp = date.plusDays(i++);
    }
    return temp;
}
李洋
2023-03-14

您为临时调整器使用了错误的字段。dayOfWeekInMonth(int ordinal,DayOfWeek DayOfWeek)因为ordinal是一个月内的一周,但您使用了对齐的_week中的_DAY。

但是如何在java中获得每月的一周。时间
为此,您需要WeekFields,最常见的是WeekFields。ISO
现在,您可以使用WeekFields为每月的一周创建ChronoField。ISO。周月()

使用您的代码,这应该看起来像:

LocalDate ld = LocalDate.parse( "2018-03-05" );
DayOfWeek dayOfWeek = ld.getDayOfWeek();
int ordinal = ld.get(WeekFields.of(dayOfWeek, 7).weekOfMonth());
YearMonth ym = YearMonth.from( ld );

int countMonths = 6;
List < LocalDate > localDates = new ArrayList <>( countMonths );
TemporalAdjuster ta = TemporalAdjusters.dayOfWeekInMonth( ordinal, dayOfWeek );
for ( int i = 1 ; i <= countMonths ; i++ ) {
    LocalDate firstOfMonth = ym.plusMonths( i ).atDay( 1 );
    LocalDate localDate = firstOfMonth.with( ta );
    localDates.add( localDate );
}

➣:ChronoField。对齐的周中日月中日是一周中的第n天,它不是以固定的周中日(如周一)开始,而是以一个月的第一天开始。

呼延辰龙
2023-03-14

这个简单的更改可以修复您的程序:

    int alignedWeekOfMonth = ld.get(ChronoField.ALIGNED_WEEK_OF_MONTH);

不过,我已经重命名了变量alignedDayOfWeekInMonth,所以您需要将名称更改带到您使用它的两个地方。然后你的程序打印:

ld.toString(): 2018-03-05
alignedWeekOfMonth: 1
dayOfWeek.toString(): MONDAY
ym.toString(): 2018-03
localDates: [2018-04-02, 2018-05-07, 2018-06-04, 2018-07-02, 2018-08-06, 2018-09-03]

这份清单与你所说的相符。

看来你误解了ChronoField,这是对的。在月内调整周中的日。关于月份的对齐周概念,3月5日是第一个对齐周的第5天。你用的计时字段是5,不是1。要获取1,请使用ChronoField。改为每周每月调整。然后一切正常。

 类似资料:
  • 在Java中,我需要找出某个特定日期的第n个星期几。例如,今天是2016年4月20日,这是本月的第三个星期三,或者2016年10月31日,这是10月的第五个星期一。我怎样才能找到一个月中某一天发生的具体次数?

  • 问题内容: 在SQL Server中,最简单/最干净的方法是使日期时间基于另一个日期时间表示月份的第一天吗?例如,我有一个变量或具有2005年3月3日14:23的列,我想获得2005年3月1日00:00(作为日期时间,而不是varchar) 问题答案: 要在列上运行此命令,请用您的列名替换GetDate()。 此代码的技巧是使用DateDiff。DateDiff返回一个整数。第二个参数(0)表示S

  • 问题内容: 我试图获取给定月份和年份的第一个日期和最后一个日期。我使用以下代码以yyyyMMdd格式获取最后日期。但是无法获得这种格式。另外,我希望开始日期采用相同的格式。我仍在努力。任何人都可以帮助我修复以下代码。 问题答案: 获取 开始日期 ( 注意 :在开始日期中, 日期 = 1) 对于格式化

  • 问题内容: 我的输入字符串日期如下: 我得到的月份如下: 但是,如何获取给定String日期中月份的最后一个日历日? 例如:对于字符串,输出必须为。 问题答案: Java 8及更高版本。 通过使用where 是的实例。 Java 7及更低版本。 通过使用以下方法:

  • 我需要编写一个方法,以YYYY-MM-DD格式将Date作为输入参数,并返回列表中同一天的所有日期。 列表中的日期如下:2020-06-09T07:10:28.1985307Z 我是否需要使用“-”split解析参数,并将字符串的MM部分与列表日期的MM部分进行比较?这似乎太复杂了,你能给我一些建议如何更好地解决这个问题吗?

  • 问题内容: 我假设Java有一些内置的方法可以做到这一点。 给定日期,我如何确定该日期之前一天? 例如,假设给我3/1/2009。上一个日期是2009年2月28日。如果给我3/1/2008,那么以前的日期应该是2/29/2008。 问题答案: 使用日历界面。 以这种方式进行“加法”可确保您获得有效的日期。该日期也于一年的1月1日有效,例如2012年1月1日为2011年12月31日。