【问题标题】:Get the first Monday of a month获取一个月的第一个星期一
【发布时间】:2014-07-21 04:59:07
【问题描述】:

我想获取特定月份/年份的第一个星期一的日期。

我有什么:

我基本上有两个 int 变量,一个代表年份,一个代表月份。

我想要的:

我想知道本月的第一个星期一,最好是 int 或 Integer 值。

例如:

我有2014和1(1月),这个月的第一个星期一是6号,所以我想返回6。

问题:

我认为我可以使用 Calendar 来做到这一点,但我已经无法设置只有年和月可用的日历。此外,我不确定如何使用Calendar 实际返回每月/每年的第一个星期一。

我已经试过了:

Calendar cal = Calendar.getInstance();
cal.set(this.getYear(),getMonth(), 1);
int montag = cal.getFirstDayOfWeek();
for( int j = 0; j < 7; j++ ) {
    int calc = j - montag;
    if( calc < 0 ) {
        calc += 6;
    }
    weekDays[calc].setText(getDayString(calc));
}

【问题讨论】:

  • 不,getFirstDayOfWeek 只是一种本地化方法。请参阅文档:docs.oracle.com/javase/7/docs/api/java/util/…
  • 你在问 getFirstDayOfWeek() 是做什么的吗? The javadoc 告诉我们: 获取一周的第一天是什么;例如,美国的星期天,法国的星期一。
  • This question,虽然它要求“上周五”,但更适合您的问题;您可以轻松地按照此处显示的相同模式来解决您的问题。
  • 为了响应您的编辑,您的原始代码几乎完全正确。唯一的错误是当你应该使用不同的函数时使用了 getFirstDayOfWeek (并且可能循环需要一些调整)。检查文档,你会找到你想要的功能。

标签: java


【解决方案1】:

getFirstDayOfWeek() 方法没有帮助。引用它的javadoc:

获取一周的第一天是什么;例如,美国的星期天,法国的星期一

以下经过测试的方法使用模数运算来查找月份中的第一个星期一:

public static long getMondaysDay(int year, int month) {
    try {
        Date d = new SimpleDateFormat("d-M-yyyy").parse("1-" + month + "-" + year);
        long epochMillis = d.getTime() + TimeZone.getDefault().getOffset(d.getTime());
        return (12 - TimeUnit.MILLISECONDS.toDays(epochMillis) % 7) % 7;
    } catch (ParseException ignore) { return 0; } // Never going to happen
}

知道epoch 的第一天是星期四,这通过使用模算术来计算纪元周的哪一天,然后到下一个星期一还有多少天,然后再次取模以防第一个落在星期四之前.神奇的数字124(从星期四到星期一的天数)加上1,因为一个月中的天数从1 加上7 开始,以确保减法后得到肯定的结果。

【讨论】:

  • 考虑到时间漂移的各种方式,我认为使用Calendar 比将自纪元以来的毫秒数转换为一天更稳定。
  • @Dave 在我们有生之年没有 :) 此外,a) 我喜欢数学,b) 我原则上从不使用 Calendar 类
  • 我试过你的方法,但是对于参数 2014 和 1 它返回 -2
  • -1;为了使它工作,月份和年份必须填充为 2 和 4。
  • @JakobAbfalter 让它正常工作(现在它可以正常工作)实际上比我预期的要棘手。
【解决方案2】:

getFirstDayOfWeek() 返回当前语言环境的开始日期。有些人认为第一天是星期一,有些人认为是星期日等。

这看起来你只需要为DAY_OF_WEEK = MONDAYDAY_OF_WEEK_IN_MONTH = 1 设置它,因为这会给你这个月的第一个星期一。要在今年做同样的事情,首先将MONTH 的值设置为JANUARY,然后重复上述操作。

例子:

private static Calendar cacheCalendar;

public static int getFirstMonday(int year, int month) {
    cacheCalendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
    cacheCalendar.set(Calendar.DAY_OF_WEEK_IN_MONTH, 1);
    cacheCalendar.set(Calendar.MONTH, month);
    cacheCalendar.set(Calendar.YEAR, year);
    return cacheCalendar.get(Calendar.DATE);
}

public static int getFirstMonday(int year) {
    return getFirstMonday(year, Calendar.JANUARY);
}

这是一个测试它的简单 JUnit:http://pastebin.com/YpFUkjQG

【讨论】:

  • 不知何故,如果我尝试使用此方法,对于参数 2014 和 1,它会返回 9,这是不对的,因为一周只有 7 天。
  • 嗯,让我测试一下。它应该可以工作,但我会调试它。
  • 小提示:你不能使用1,因为那是Calendar.FEBRUARY,而不是Calendar.JANUARY。它仍然不起作用,但这是一个因素。
  • 另外,添加了一个只能在一年内获得它。
  • 太棒了!感谢您的帮助!
【解决方案3】:

首先你应该知道最新版本的java,即JAVA8 熟悉 JAVA8

中的LocalDate

那就只看下面的代码

public class Test {

    public static void main(String[] args) {
        LocalDate date=LocalDate.of(2014,1, 1);
        for(int i=0;i<date.lengthOfMonth();i++){
            if("Monday".equalsIgnoreCase(date.getDayOfWeek().toString())){

                break;
            }else{
                date=date.plusDays(1);
            }
        }

        System.out.println(date.getDayOfMonth());

    }

}

【讨论】:

  • date.lengthOfMonth()?但我们会在任何给定月份的前 7 天内找到星期一 for(int i=0;i&lt;7;i++){
【解决方案4】:

乔达时间

Joda-Time 库提供了一个类 LocalDate,当您只需要日期而不需要时间时。 getDayOfWeek 方法返回一个数字,您可以将其与常量 MONDAY 进行比较。

LocalDate localDate = new LocalDate( year, month, 1 );
while ( localDate.getDayOfWeek() != DateTimeConstants.MONDAY ) {
    localDate = localDate.plusDays( 1 );
}
int firstMonday = localDate.getDayOfMonth();

不可变语法

为了线程安全,Joda-Time 使用immutable objects。因此,我们不是在现有对象中修改字段值,而是在原始对象的基础上创建一个新实例。

java.time

正如another answer by Abhishek Mishra 所说,与Java 8 捆绑在一起的新java.time package 还提供类似于Joda-Time 的LocalDate 类。

【讨论】:

    【解决方案5】:

    Lamma Date 库非常适合这个用例。

    @Test
    public void test() {
        assertEquals(new Date(2014, 1, 6), firstMonday(2014, 1));
        assertEquals(new Date(2014, 2, 3), firstMonday(2014, 2));
        assertEquals(new Date(2014, 3, 3), firstMonday(2014, 3));
        assertEquals(new Date(2014, 4, 7), firstMonday(2014, 4));
        assertEquals(new Date(2014, 5, 5), firstMonday(2014, 5));
        assertEquals(new Date(2014, 6, 2), firstMonday(2014, 6));
    }
    
    public Date firstMonday(int year, int month) {
        Date firstDayOfMonth = new Date(year, month, 1);
        return firstDayOfMonth.nextOrSame(DayOfWeek.MONDAY);
    }
    

    【讨论】:

      【解决方案6】:

      Java.time

      使用 Java 8 中内置的 java.time 库和 TemporalAdjuster。见Tutorial

      import java.time.DayOfWeek;
      import java.time.LocalDate;
      import static java.time.temporal.TemporalAdjusters.firstInMonth;
      
      LocalDate now = LocalDate.now(); //2015-11-23
      LocalDate firstMonday = now.with(firstInMonth(DayOfWeek.MONDAY)); //2015-11-02 (Monday)
      

      如果您需要添加时间信息,您可以使用任何可用的LocalDateLocalDateTime 转换,如

      firstMonday.atStartOfDay() # 2015-11-02T00:00
      

      【讨论】:

      【解决方案7】:
              Calendar calendar = Calendar.getInstance();
              SimpleDateFormat sdf = new SimpleDateFormat("MMM/dd/YYYY");
              calendar.set(Calendar.MONTH,Calendar.JUNE);
              calendar.set(Calendar.DAY_OF_MONTH,1);          
              int day = (Calendar.TUESDAY-calendar.get(Calendar.DAY_OF_WEEK));            
              if(day<0){
                calendar.add(Calendar.DATE,7+(day));
              }else{
                  calendar.add(Calendar.DATE,day);
              }
              System.out.println("First date is "+sdf.format(calendar.getTime()));
      

      【讨论】:

        【解决方案8】:

        最简单的方法是:

        LocalDate firstSundayOfNextMonth = LocalDate
                      .now()
                      .with(firstDayOfNextMonth())
                      .with(nextOrSame(DayOfWeek.MONDAY));
        

        【讨论】:

          【解决方案9】:

          这是获取给定月份的第 n 个 DAY_OF_WEEK 的通用函数。您可以使用它来获取任何给定月份的第一个星期一。

          import java.util.Calendar;
          
          public class NthDayOfWeekOfMonth {
          
          public static void main(String[] args) {
              // get first Monday of July 2019
              Calendar cal = getNthDayOfWeekOfMonth(2019,Calendar.JULY,1,Calendar.MONDAY);
              System.out.println(cal.getTime());
          
              // get first Monday of August 2019
              cal = getNthDayOfWeekOfMonth(2019,Calendar.AUGUST,1,Calendar.MONDAY);
              System.out.println(cal.getTime());
          
              // get third Friday of September 2019
              cal = getNthDayOfWeekOfMonth(2019,Calendar.SEPTEMBER,3,Calendar.FRIDAY);
              System.out.println(cal.getTime());
          }
          
          public static Calendar getNthDayOfWeekOfMonth(int year, int month, int n, int dayOfWeek) {
              Calendar cal = Calendar.getInstance();
              cal.set(Calendar.HOUR_OF_DAY, 0);
              cal.set(Calendar.MINUTE,0);
              cal.set(Calendar.SECOND,0);
              cal.set(Calendar.YEAR,year);
              cal.set(Calendar.MONTH,month);
              cal.set(Calendar.DAY_OF_MONTH,1);
          
              int dayDiff = dayOfWeek-cal.get(Calendar.DAY_OF_WEEK);
              if (dayDiff<0) {
                  dayDiff+=7;
              }
              dayDiff+=7*(n-1);
          
              cal.add(Calendar.DATE, dayDiff); 
              return cal;
          }
          
          }
          

          输出:

          Mon Jul 01 00:00:00 EDT 2019
          Mon Aug 05 00:00:00 EDT 2019
          Fri Sep 20 00:00:00 EDT 2019
          

          【讨论】:

            【解决方案10】:
            Get the All Monday of a month
            
            
            public class AllMonday {
            public static void main(String[] args){
            
             System.out.println(weeksInCalendar(YearMonth.now()));  
            
            }
            public static List<LocalDate> weeksInCalendar(YearMonth month) {
                    List<LocalDate> firstDaysOfWeeks = new ArrayList<>();
                    for (LocalDate day = firstDayOfCalendar(month); 
                        stillInCalendar(month, day); day = day.plusWeeks(1)) {
                      firstDaysOfWeeks.add(day);
                    }
                    return firstDaysOfWeeks;
                  }
              private static LocalDate firstDayOfCalendar(YearMonth month) {
                DayOfWeek FIRST_DAY_OF_WEEK = DayOfWeek.of(1);
                System.out.println( month.atDay(1).with(FIRST_DAY_OF_WEEK));
            
                return month.atDay(1).with(TemporalAdjusters.firstInMonth(DayOfWeek.MONDAY));
              }
            
              private static boolean stillInCalendar(YearMonth yearMonth, LocalDate day) {
                  System.out.println(!day.isAfter(yearMonth.atEndOfMonth()));
                return !day.isAfter(yearMonth.atEndOfMonth());
              }
            

            }

            【讨论】:

              猜你喜欢
              • 2019-03-09
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多