【问题标题】:Number of days in particular month of particular year?特定年份特定月份的天数?
【发布时间】:2012-02-14 23:04:02
【问题描述】:

如何知道某年某月有多少天?

String date = "2010-01-19";
String[] ymd = date.split("-");
int year = Integer.parseInt(ymd[0]);
int month = Integer.parseInt(ymd[1]);
int day = Integer.parseInt(ymd[2]);
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.YEAR,year);
calendar.set(Calendar.MONTH,month);
int daysQty = calendar.getDaysNumber(); // Something like this

【问题讨论】:

标签: java datetime calendar


【解决方案1】:

这是数学方法:

对于年份(例如 2012 年)、月份(0 到 11):

int daysInMonth = month !== 2 ? 
  31 - (((month - 1) % 7) % 2) : 
  28 + (year % 4 == 0 ? 1 : 0) - (year % 100 == 0 ? 1 : 0) + (year % 400 == 0 ? 1 : 0)

【讨论】:

    【解决方案2】:

    另一种解决方案是使用Calendar 对象。获取当前日期并设置日期,使其成为本月的第一天。然后加一个月,去掉一天,得到当月的最后一天。最后获取天数,得到该月的天数。

    Calendar today = getInstance(TimeZone.getTimeZone("UTC"));
    
    Calendar currMonthLastDay = getInstance(TimeZone.getTimeZone("UTC"));
    currMonthLastDay.clear();
    currMonthLastDay.set(YEAR, today.get(YEAR));
    currMonthLastDay.set(MONTH, today.get(MONTH));
    currMonthLastDay.set(DAY_OF_MONTH, 1); 
    currMonthLastDay.add(MONTH, 1);
    currMonthLastDay.add(DAY_OF_MONTH, -1);
    
    Integer daysInMonth = currMonthLastDay.get(DAY_OF_MONTH);
    

    【讨论】:

      【解决方案3】:

      特定年份的天数 - Java 8+ 解决方案

      Year.now().length()
      

      【讨论】:

      • 没有解决问题。问题是关于月份的长度,而不是年份。 .length() 方法已在其他答案中多次介绍。
      【解决方案4】:

      最优的性能差异:

      public static int daysInMonth(int month, int year) {
          if (month != 2) {
              return 31 - (month - 1) % 7 % 2;
          }
          else {
              if ((year & 3) == 0 && ((year % 25) != 0 || (year & 15) == 0)) { // leap year
                  return 29;
              } else {
                  return 28;
              }
          }
      }
      

      有关跳跃算法的更多详细信息,请查看here

      【讨论】:

        【解决方案5】:
        String date = "11-02-2000";
        String[] input = date.split("-");
        int day = Integer.valueOf(input[0]);
        int month = Integer.valueOf(input[1]);
        int year = Integer.valueOf(input[2]);
        Calendar cal=Calendar.getInstance();
        cal.set(Calendar.YEAR,year);
        cal.set(Calendar.MONTH,month-1);
        cal.set(Calendar.DATE, day);
        //since month number starts from 0 (i.e jan 0, feb 1), 
        //we are subtracting original month by 1
        int days = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
        System.out.println(days);
        

        【讨论】:

        • 不需要回答已经被接受的问题,直到那个答案无论如何都无效。
        【解决方案6】:

        以下方法将为您提供特定月份的天数

        public static int getNoOfDaysInAMonth(String date) {
            Calendar cal = Calendar.getInstance();
            cal.setTime(date);
            return (cal.getActualMaximum(Calendar.DATE));
        }
        

        【讨论】:

        • 应该传递什么格式的字符串日期?
        【解决方案7】:

        您可以使用 Calendar.getActualMaximum 方法:

        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.YEAR, year);
        calendar.set(Calendar.MONTH, month-1);
        int numDays = calendar.getActualMaximum(Calendar.DATE);
        

        而第1个月是因为月份采用其原始月份数,而在方法中采用如下Calendar.class中的参数

        public int getActualMaximum(int field) {
           throw new RuntimeException("Stub!");
        }
        

        并且(int字段)如下所示。

        public static final int JANUARY = 0;
        public static final int NOVEMBER = 10;
        public static final int DECEMBER = 11;
        

        【讨论】:

          【解决方案8】:

          我会寻求这样的解决方案:

          int monthNr = getMonth();
          final Month monthEnum = Month.of(monthNr);
          int daysInMonth;
          if (monthNr == 2) {
              int year = getYear();
              final boolean leapYear = IsoChronology.INSTANCE.isLeapYear(year);
              daysInMonth = monthEnum.length(leapYear);
          } else {
              daysInMonth = monthEnum.maxLength();
          }
          

          如果月份不是 2 月(92% 的情况),则仅取决于月份,不涉及年份会更有效。这样,您不必调用逻辑来知道它是否是闰年,并且您不需要在 92% 的情况下获取年份。 而且它仍然是干净且可读性很强的代码。

          【讨论】:

          • 我宁愿把整个逻辑留给一个经过验证的库方法——我认为你过早地优化了,库方法并不是那么低效。仍然赞成使用现代 java.time。
          • @OleV.V.诚然,在许多情况下,将优化留给经过验证的库会更好。但是,在这种情况下,现有的图书馆将需要经过一个月和一年的时间。所以这意味着我无论如何都需要做任何事情来获得年份,即使该方法在 92% 的情况下都不会使用该值。所以,这是它无法为我优化的部分。我的推理类似于您不应该执行方法调用来获取要传递给可能被禁用的记录器的值的原因。记录器无法优化它。
          【解决方案9】:
          // 1 means Sunday ,2 means Monday .... 7 means Saturday
          //month starts with 0 (January)
          
          MonthDisplayHelper monthDisplayHelper = new MonthDisplayHelper(2019,4);
          int numbeOfDaysInMonth = monthDisplayHelper.getNumberOfDaysInMonth();
          

          【讨论】:

          • 值得注意的是,它适用于Android (android.util.MonthDisplayHelper)
          【解决方案10】:

          这对我来说很好。

          This is a Sample Output

          import java.util.*;
          
          public class DaysInMonth { 
          
              public static void main(String args []) { 
          
                  Scanner input = new Scanner(System.in); 
                  System.out.print("Enter a year:"); 
          
                  int year = input.nextInt(); //Moved here to get input after the question is asked 
          
                  System.out.print("Enter a month:"); 
                  int month = input.nextInt(); //Moved here to get input after the question is asked 
          
                  int days = 0; //changed so that it just initializes the variable to zero
                  boolean isLeapYear = (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0); 
          
                  switch (month) { 
                      case 1: 
                          days = 31; 
                          break; 
                      case 2: 
                          if (isLeapYear) 
                              days = 29; 
                          else 
                              days = 28; 
                          break; 
                      case 3: 
                          days = 31; 
                          break; 
                      case 4: 
                          days = 30; 
                          break; 
                      case 5: 
                          days = 31; 
                          break; 
                      case 6: 
                          days = 30; 
                          break; 
                      case 7: 
                          days = 31; 
                          break; 
                      case 8: 
                          days = 31; 
                          break; 
                      case 9: 
                          days = 30; 
                          break; 
                      case 10: 
                          days = 31; 
                          break; 
                      case 11: 
                          days = 30; 
                          break; 
                      case 12: 
                          days = 31; 
                          break; 
                      default: 
                          String response = "Have a Look at what you've done and try again";
                          System.out.println(response); 
                          System.exit(0); 
                  } 
          
                  String response = "There are " + days + " Days in Month " + month + " of Year " + year + ".\n"; 
                  System.out.println(response); // new line to show the result to the screen. 
              } 
          } //abhinavsthakur00@gmail.com
          

          【讨论】:

            【解决方案11】:

            如果您不想硬编码年份和月份的值,并且想从当前日期和时间获取值,让我们让它变得简单:

            Date d = new Date();
            String myDate = new SimpleDateFormat("dd/MM/yyyy").format(d);
            int iDayFromDate = Integer.parseInt(myDate.substring(0, 2));
            int iMonthFromDate = Integer.parseInt(myDate.substring(3, 5));
            int iYearfromDate = Integer.parseInt(myDate.substring(6, 10));
            
            YearMonth CurrentYear = YearMonth.of(iYearfromDate, iMonthFromDate);
            int lengthOfCurrentMonth = CurrentYear.lengthOfMonth();
            System.out.println("Total number of days in current month is " + lengthOfCurrentMonth );
            

            【讨论】:

              【解决方案12】:
              String  MonthOfName = "";
              int number_Of_DaysInMonth = 0;
              
              //year,month
              numberOfMonth(2018,11); // calling this method to assign values to the variables MonthOfName and number_Of_DaysInMonth 
              
              System.out.print("Number Of Days: "+number_Of_DaysInMonth+"   name of the month: "+  MonthOfName );
              
              public void numberOfMonth(int year, int month) {
                  switch (month) {
                      case 1:
                          MonthOfName = "January";
                          number_Of_DaysInMonth = 31;
                          break;
                      case 2:
                          MonthOfName = "February";
                          if ((year % 400 == 0) || ((year % 4 == 0) && (year % 100 != 0))) {
                              number_Of_DaysInMonth = 29;
                          } else {
                              number_Of_DaysInMonth = 28;
                          }
                          break;
                      case 3:
                          MonthOfName = "March";
                          number_Of_DaysInMonth = 31;
                          break;
                      case 4:
                          MonthOfName = "April";
                          number_Of_DaysInMonth = 30;
                          break;
                      case 5:
                          MonthOfName = "May";
                          number_Of_DaysInMonth = 31;
                          break;
                      case 6:
                          MonthOfName = "June";
                          number_Of_DaysInMonth = 30;
                          break;
                      case 7:
                          MonthOfName = "July";
                          number_Of_DaysInMonth = 31;
                          break;
                      case 8:
                          MonthOfName = "August";
                          number_Of_DaysInMonth = 31;
                          break;
                      case 9:
                          MonthOfName = "September";
                          number_Of_DaysInMonth = 30;
                          break;
                      case 10:
                          MonthOfName = "October";
                          number_Of_DaysInMonth = 31;
                          break;
                      case 11:
                          MonthOfName = "November";
                          number_Of_DaysInMonth = 30;
                          break;
                      case 12:
                          MonthOfName = "December";
                          number_Of_DaysInMonth = 31;
                  }
              }
              

              【讨论】:

                【解决方案13】:

                就这么简单,不用导入任何东西

                public static int getMonthDays(int month, int year) {
                    int daysInMonth ;
                    if (month == 4 || month == 6 || month == 9 || month == 11) {
                        daysInMonth = 30;
                    }
                    else {
                        if (month == 2) {
                            daysInMonth = (year % 4 == 0) ? 29 : 28;
                        } else {
                            daysInMonth = 31;
                        }
                    }
                    return daysInMonth;
                }
                

                【讨论】:

                • 这没关系,如果您不需要历史日期或遥远的未来日期。对于 100 的倍数但不是 400 的倍数的年份的 2 月,这将是错误的。但我同意,在大多数应用程序中都可以这样做,而且效率很高。
                【解决方案14】:

                Java 8 及更高版本

                @Warren M. Nocos。 如果您尝试使用 Java 8 的新 Date and Time API,则可以使用 java.time.YearMonth 类。见Oracle Tutorial

                // Get the number of days in that month
                YearMonth yearMonthObject = YearMonth.of(1999, 2);
                int daysInMonth = yearMonthObject.lengthOfMonth(); //28  
                

                测试:在闰年尝试一个月:

                yearMonthObject = YearMonth.of(2000, 2);
                daysInMonth = yearMonthObject.lengthOfMonth(); //29 
                

                Java 7 及更早版本

                创建日历,设置年月并使用getActualMaximum

                int iYear = 1999;
                int iMonth = Calendar.FEBRUARY; // 1 (months begin with 0)
                int iDay = 1;
                
                // Create a calendar object and set year and month
                Calendar mycal = new GregorianCalendar(iYear, iMonth, iDay);
                
                // Get the number of days in that month
                int daysInMonth = mycal.getActualMaximum(Calendar.DAY_OF_MONTH); // 28
                

                测试:在闰年尝试一个月:

                mycal = new GregorianCalendar(2000, Calendar.FEBRUARY, 1);
                daysInMonth= mycal.getActualMaximum(Calendar.DAY_OF_MONTH);      // 29
                

                【讨论】:

                • 如何在 Java 8 的新日期和时间 API 上做到这一点?
                • @WarrenM.Nocos 很抱歉回复晚了,但我这几个月不活跃。请检查 java 8 解决方案的编辑。
                • 至于在 Java 8 之前... java.time 的大部分功能都在 ThreeTen-Backport 项目中向后移植到 Java 6 和 Java 7。在ThreeTenABP 项目中进一步适用于早期的Android。见How to use ThreeTenABP…
                【解决方案15】:

                应避免使用过时的Calendar API。

                在Java8或更高版本中,这可以通过YearMonth来完成。

                示例代码:

                int year = 2011;
                int month = 2;
                YearMonth yearMonth = YearMonth.of(year, month);
                int lengthOfMonth = yearMonth.lengthOfMonth();
                System.out.println(lengthOfMonth);
                

                【讨论】:

                • Call requires API level 26 (current min is 21): java.time.YearMonth#lengthOfMonth
                【解决方案16】:
                public class Main {
                
                    private static LocalDate local=LocalDate.now();
                    public static void main(String[] args) {
                
                            int month=local.lengthOfMonth();
                            System.out.println(month);
                
                    }
                }
                

                【讨论】:

                • 也添加一些解释。
                • 欢迎来到 Stack Overflow!虽然此代码 sn-p 可能是解决方案,但including an explanation 确实有助于提高您的帖子质量。请记住,您是在为将来的读者回答问题,而这些人可能不知道您提出代码建议的原因。
                【解决方案17】:

                在 Java8 中,您可以使用从日期字段中获取 ValueRange。

                LocalDateTime dateTime = LocalDateTime.now();
                
                ChronoField chronoField = ChronoField.MONTH_OF_YEAR;
                long max = dateTime.range(chronoField).getMaximum();
                

                这允许您在字段上进行参数化。

                【讨论】:

                  【解决方案18】:

                  java.time.LocalDate

                  从 Java 1.8 开始,您可以在 java.time.LocalDate 上使用方法 lengthOfMonth

                  LocalDate date = LocalDate.of(2010, 1, 19);
                  int days = date.lengthOfMonth();
                  

                  【讨论】:

                    【解决方案19】:

                    java.util.Calendar 的代码

                    如果你必须使用java.util.Calendar,我怀疑你想要:

                    int days = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
                    

                    Joda Time 代码

                    不过,我个人建议使用 Joda Time 而不是 java.util.{Calendar, Date} 开始,在这种情况下您可以使用:

                    int days = chronology.dayOfMonth().getMaximumValue(date);
                    

                    请注意,与其单独解析字符串值,不如获取用于解析它的任何日期/时间 API。在java.util.* 你可以使用SimpleDateFormat;在 Joda Time 你会使用DateTimeFormatter

                    【讨论】:

                      【解决方案20】:
                      import java.text.ParseException;
                      import java.text.SimpleDateFormat;
                      import java.util.Calendar;
                      import java.util.Date;
                      
                      /*
                       * 44. Return the number of days in a month
                       * , where month and year are given as input.
                       */
                      public class ex44 {
                          public static void dateReturn(int m,int y)
                          {
                              int m1=m;
                              int y1=y;
                              String str=" "+ m1+"-"+y1;
                              System.out.println(str);
                              SimpleDateFormat sd=new SimpleDateFormat("MM-yyyy");
                      
                              try {
                                  Date d=sd.parse(str);
                                  System.out.println(d);
                                  Calendar c=Calendar.getInstance();
                                  c.setTime(d);
                                  System.out.println(c.getActualMaximum(Calendar.DAY_OF_MONTH));
                              } catch (ParseException e) {
                                  // TODO Auto-generated catch block
                                  e.printStackTrace();
                              }
                      
                          }
                          public static void main(String[] args) {
                      dateReturn(2,2012);
                      
                      
                          }
                      
                      }
                      

                      【讨论】:

                      • 这个答案比现有的和接受的答案有什么价值?另外,请在您的代码中添加一些解释或叙述。 StackOverflow 不仅仅是一个 sn-p 库。
                      【解决方案21】:
                      if (month == 4 || month == 6 || month == 9 || month == 11)
                      
                      daysInMonth = 30;
                      
                      else 
                      
                      if (month == 2) 
                      
                      daysInMonth = (leapYear) ? 29 : 28;
                      
                      else 
                      
                      daysInMonth = 31;
                      

                      【讨论】:

                      • 日历 c = Calendar.getInstance();c.set(Calendar.DAY_OF_MONTH, c.getActualMaximum(Calendar.DAY_OF_MONTH)); // 您可以在获得实际最大值之前设置年份,因为它们可能不一样。即 2011 年 2 月和 2012 年 2 月的长度不同(闰年)
                      【解决方案22】:

                      你可以使用Calendar.getActualMaximum方法:

                      Calendar calendar = Calendar.getInstance();
                      calendar.set(Calendar.YEAR, year);
                      calendar.set(Calendar.MONTH, month);
                      int numDays = calendar.getActualMaximum(Calendar.DATE);
                      

                      【讨论】:

                        猜你喜欢
                        • 2017-12-04
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 2013-02-15
                        • 1970-01-01
                        • 1970-01-01
                        相关资源
                        最近更新 更多