Java:如何获取一个月内x天的日期(例如2012年2月的第三个星期一)

Java:如何获取一个月内x天的日期(例如2012年2月的第三个星期一),java,date,calendar,Java,Date,Calendar,我对此有些挣扎 我想将日历设置为:2012年2月的第三个星期一。 我没有找到用Java做这件事的方法 例如,如果我想为2011年圣诞节设置日历,我可以通过以下方式轻松完成: Calendar when = Calendar.getInstance(); when.set (Calendar.MONTH, Calendar.DECEMBER); when.set (Calendar.DAY_OF_MONTH, 25) when.set (Calendar.YEAR, 2011); 但我不知道如何

我对此有些挣扎

我想将日历设置为:2012年2月的第三个星期一。 我没有找到用Java做这件事的方法

例如,如果我想为2011年圣诞节设置日历,我可以通过以下方式轻松完成:

Calendar when = Calendar.getInstance();
when.set (Calendar.MONTH, Calendar.DECEMBER);
when.set (Calendar.DAY_OF_MONTH, 25)
when.set (Calendar.YEAR, 2011);
但我不知道如何为2012年阵亡将士纪念日(5月的最后一个星期一)设置它。这是我的代码,但显然是错误的,因为我不能简单地假设5月的最后一个星期一将在当年5月的第4周:

Calendar when = Calendar.getInstance ();
when.set (Calendar.DAY_OF_WEEK,Calendar.MONDAY);
when.set (Calendar.MONTH, Calendar.MAY);
when.set (Calendar.WEEK_OF_MONTH, 4)
when.set (Calendar.YEAR, 2012);
关于如何通过编程找到答案的任何建议,2012年5月的哪一周(在上面的例子中)是最后一个星期一?假设我可以得到这些信息,我应该能够让我的代码在上面工作

我需要一些基本上适用于任何其他例子的东西。对于相同的场景,可以给出确切的日期。示例:

哪一天是:

  • 2015年5月第三个星期四
  • 2050年6月1日星期一
  • 2012年12月4日星期二
  • 2000年7月第二个星期三
我的项目真的需要这个,我相信它很简单,但是我在这个问题上伤了脑筋,没有任何实际的结果可以显示:)而且在网上也找不到任何东西


增加:

好的,这是我一个月内最后一个星期一的收获:

when.set (GregorianCalendar.MONTH, GregorianCalendar.MAY);
when.set (GregorianCalendar.DAY_OF_WEEK, Calendar.MONDAY);
when.set (GregorianCalendar.DAY_OF_WEEK_IN_MONTH, -1);
when.set (Calendar.YEAR, 2012);
但是我不知道我该怎么做,比如在同一个月的星期一,像这样

when.set (GregorianCalendar.DAY_OF_WEEK_IN_MONTH, 2);
有什么建议吗?

我不知道“简单”的方法,但我可以给你以下建议

  • 将日历设置为每月的第一天
  • 检索一周中的某一天
  • 计算当月第一个星期一的日期
  • 使用calendar.Add()方法添加14天。你将得到第三个星期一 你有机会吗

    此简单代码打印正确的(?)结果:

    Thu May 21 00:00:00 CEST 2015
    Mon Jun 06 00:00:00 CEST 2050
    Tue Dec 25 00:00:00 CET 2012
    Wed Jul 12 00:00:00 CEST 2000
    

    所要求的与石英的其余部分没有任何依赖关系,因此您可以考虑将其复制到项目中(注意许可证)


    旁注:
    getNextValidTimeAfter()
    的内部实现是400行代码…

    在Java中执行日期算术(通常,除了最琐碎的事情外,对日期时间执行任何操作)就是答案:

    public static LocalDate getNDayOfMonth(int dayweek,int nthweek,int month,int year)  {
       LocalDate d = new LocalDate(year, month, 1).withDayOfWeek(dayweek);
       if(d.getMonthOfYear() != month) d = d.plusWeeks(1);
       return d.plusWeeks(nthweek-1);
    }
    
    public static LocalDate getLastWeekdayOfMonth(int dayweek,int month,int year) {
       LocalDate d = new LocalDate(year, month, 1).plusMonths(1).withDayOfWeek(dayweek);
       if(d.getMonthOfYear() != month) d = d.minusWeeks(1);
      return d;
    }
    
    public static void main(String[] args) {
       // second wednesday of oct-2011
       LocalDate d = getNDayOfMonth( DateTimeConstants.WEDNESDAY, 2, 10, 2011);
       System.out.println(d);
       // last wednesday of oct-2011
       LocalDate dlast = getLastWeekdayOfMonth( DateTimeConstants.WEDNESDAY,  10, 2011);
       System.out.println(dlast);
    }
    


    编辑:自Java 8(2014)以来,新的日期API(package
    Java.time
    )受到Jodatime的启发/类似于Jodatime,。

    您只需要一个循环:

    public class CalculateDate {
    
    public static void main( String ... args ) {
    
        Calendar c = Calendar.getInstance();
        c.set( Calendar.YEAR, 2012 );
        c.set( Calendar.MONTH , Calendar.MAY);
        c.set( Calendar.DAY_OF_MONTH, 0 );
        c.add( Calendar.DAY_OF_MONTH, -1 );
    
        System.out.println( c.getTime() );
    
        int mondaysCount = 0;
    
        while ( mondaysCount != 4 ) {
            c.add( Calendar.DAY_OF_MONTH, 1 );
            if ( c.get( Calendar.DAY_OF_WEEK ) == Calendar.MONDAY ) {
                mondaysCount++; 
            }       
        }
    
        System.out.printf( "The fourth monday of may is %s", c.getTime() );     
    
    }
    
    }
    

    这里有一个替代方案。它的作用是:获取所需的周数(n)和其他参数,并返回该周的日期。由于Calendar给出上一个月的日期(例如,2月29日而不是3月7日,因为3月的第一周与2月的最后一周冲突),因此如果该日期超过7周或其每一周的倍数,该函数将计算第二周。希望有帮助

    public static int getNthWeekDay (int n, int day, int month, int year) {
        Calendar calendar = Calendar.getInstance();
    
        calendar.set(Calendar.DAY_OF_WEEK, day);
        calendar.set(Calendar.MONTH, month);
        calendar.set(Calendar.WEEK_OF_MONTH,n);
        calendar.set(Calendar.YEAR, year);
        if (calendar.get(Calendar.DATE) > n * 7) {
            calendar.set(Calendar.DAY_OF_WEEK,day);
            calendar.set(Calendar.MONTH, month);
            calendar.set(Calendar.WEEK_OF_MONTH,day+1);
    
        }
        return calendar.get(Calendar.DATE);
    }
    

    以下代码已在2013年和2014年的所有节假日成功测试。我意识到这并没有真正回答最初的问题,但我认为这可能对那些看到这篇文章希望了解如何使用日历处理假期的人有用

    public static boolean isMajorHoliday(java.util.Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
    
        // check if New Year's Day
        if (cal.get(Calendar.MONTH) == Calendar.JANUARY
            && cal.get(Calendar.DAY_OF_MONTH) == 1) {
            return true;
        }
    
        // check if Christmas
        if (cal.get(Calendar.MONTH) == Calendar.DECEMBER
            && cal.get(Calendar.DAY_OF_MONTH) == 25) {
            return true;
        }
    
        // check if 4th of July
        if (cal.get(Calendar.MONTH) == Calendar.JULY
            && cal.get(Calendar.DAY_OF_MONTH) == 4) {
            return true;
        }
    
        // check Thanksgiving (4th Thursday of November)
        if (cal.get(Calendar.MONTH) == Calendar.NOVEMBER
            && cal.get(Calendar.DAY_OF_WEEK_IN_MONTH) == 4
            && cal.get(Calendar.DAY_OF_WEEK) == Calendar.THURSDAY) {
            return true;
        }
    
        // check Memorial Day (last Monday of May)
        if (cal.get(Calendar.MONTH) == Calendar.MAY
            && cal.get(Calendar.DAY_OF_WEEK) == Calendar.MONDAY
            && cal.get(Calendar.DAY_OF_MONTH) > (31 - 7) ) {
            return true;
        }
    
        // check Labor Day (1st Monday of September)
        if (cal.get(Calendar.MONTH) == Calendar.SEPTEMBER
            && cal.get(Calendar.DAY_OF_WEEK_IN_MONTH) == 1
            && cal.get(Calendar.DAY_OF_WEEK) == Calendar.MONDAY) {
            return true;
        }
    
        // check President's Day (3rd Monday of February)
        if (cal.get(Calendar.MONTH) == Calendar.FEBRUARY
            && cal.get(Calendar.DAY_OF_WEEK_IN_MONTH) == 3
            && cal.get(Calendar.DAY_OF_WEEK) == Calendar.MONDAY) {
            return true;
        }
    
        // check Veterans Day (November 11)
        if (cal.get(Calendar.MONTH) == Calendar.NOVEMBER
            && cal.get(Calendar.DAY_OF_MONTH) == 11) {
            return true;
        }
    
        // check MLK Day (3rd Monday of January)
        if (cal.get(Calendar.MONTH) == Calendar.JANUARY
            && cal.get(Calendar.DAY_OF_WEEK_IN_MONTH) == 3
            && cal.get(Calendar.DAY_OF_WEEK) == Calendar.MONDAY) {
            return true;
        }
    
        return false;
    
    }
    
    tl;博士 ……还有

    LocalDate lastMondayInMay2012 = 
        YearMonth.of( 2012 , Month.MAY )
                 .atDay( 1 );
                 .with( TemporalAdjusters.lastInMonth( DayOfWeek.MONDAY ) );
    
    java.time 使用java.time类非常容易,它现在取代了Joda time和与java最早版本捆绑在一起的麻烦的旧日期时间类

    首先,我们需要指定所需的月份。全班同学都能做到。从那里我们得到一个
    LocalDate
    ,一个没有时间和时区的日期

    YearMonth ym = YearMonth.of( 2012 , Month.FEBRUARY ); // Or pass '2' for 'February'.
    LocalDate ld = ym.atDay( 1 );
    
    该接口用于将日期时间值调整为另一个日期时间值。类提供的实现(请注意复数“s”)。使用方便的枚举指定一周中的一天

    提示:不要只在代码库中传递年和月的整数,而要传递诸如、和之类的对象。这样做可以消除歧义,使代码更加自文档化,提供并确保有效值


    关于java.time 该框架内置于Java8及更高版本中。这些类取代了麻烦的旧日期时间类,例如,&

    该项目现已启动,建议迁移到类

    要了解更多信息,请参阅。并搜索堆栈溢出以获得许多示例和解释。规格是

    您可以直接与数据库交换java.time对象。使用兼容的或更高版本。不需要字符串,也不需要
    java.sql.*

    从哪里获得java.time类

    • ,及以后
      • 内置的
      • 标准JavaAPI的一部分,带有捆绑实现
      • Java9添加了一些次要功能和修复
      • 大部分java.time功能都在中向后移植到Java6和Java7
      • 更高版本的Android捆绑包实现了java.time类
      • 对于早期的Android(
        public String nDow(int year,int month,int nweek,int nday)
        {
        Calendar cdt=Calendar.getInstance();
        cdt.set(年、月-1、1);
        返回年份+“-”+月份+“-”+(getPosOfWeekday(cdt.get(日历日,星期日),星期日)+(nweek-1)*7);
        }
        私人int getPosOfWeekday(int startday,int nday)
        {
        nday=工作日值(nday);
        返回日期(startday).indexOf(nday)+1;
        }
        私有数组列表构造函数数组(int工作日)
        {
        ArrayList circularArray=新的ArrayList();
        对于(int i=0;i<7;i++)
        {
        add(i,weekDayValue(weekday++));
        }
        返回圆射线;
        }
        私有int weekDayValue(int x)
        {
        返回((x-1)%7)+1;
        }
        
        我非常喜欢这段代码,它实际上很有效。我只是不知道如何指定当月的最后一个星期三(在本例中)。您能帮我一下吗。我正在尝试一些类似的方法:LocalDate d=getNDayOfMonth(DateTimeConstants.周三,-2011年10月1日);但是
        LocalDate lastMondayInMay2012 = 
            YearMonth.of( 2012 , Month.MAY )
                     .atDay( 1 );
                     .with( TemporalAdjusters.lastInMonth( DayOfWeek.MONDAY ) );
        
        YearMonth ym = YearMonth.of( 2012 , Month.FEBRUARY ); // Or pass '2' for 'February'.
        LocalDate ld = ym.atDay( 1 );
        
        int ordinal = 3 ; // Use '3' for 'third occurrence in month' such as '3rd Monday'.
        LocalDate thirdMondayInFebruary2012 = ld.with( TemporalAdjusters.dayOfWeekInMonth( ordinal , DayOfWeek.MONDAY ) );
        
        public String nDow(int year, int month, int nweek, int nday)
        {
            Calendar cdt = Calendar.getInstance();
            cdt.set(year, month -1, 1);
            return year + "-" + month + "-" + (getPosOfWeekday(cdt.get(Calendar.DAY_OF_WEEK), nday) + ((nweek - 1) *7));
        }
        
        private int getPosOfWeekday(int startday, int nday)
        {
            nday = weekDayValue(nday);
            return constructCircularArray(startday).indexOf(nday) + 1;
        }
        
        private ArrayList<Integer> constructCircularArray(int weekday)
        {
            ArrayList<Integer> circularArray = new ArrayList<Integer>();
            for(int i = 0; i < 7; i++)
            {
                circularArray.add(i, weekDayValue(weekday++));
            }
            return circularArray;
        }
        
        private int weekDayValue(int x)
        {
            return ((x-1) % 7) + 1;
        }