จำนวนวันในเดือนใดเดือนหนึ่งของปีโดยเฉพาะ?


158

จะทราบได้อย่างไรว่ากี่วันในแต่ละเดือนของปีใด

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

7
ว่าอะไรคือคำถามของคุณหรือไม่
ShaMan-H_Fel

FYI, ลำบากชะมัดเก่าชั้นเรียนวันที่เวลาเช่นjava.util.Date, java.util.Calendarและjava.text.SimpleDateFormatตอนนี้มรดกแทนที่โดยjava.timeชั้นเรียนที่สร้างขึ้นใน Java 8 และต่อมา ดูการสอนโดยออราเคิล
Basil Bourque

คำตอบ:


368

Java 8 และต่อมา

@Warren M. Nocos หากคุณพยายามใช้API วันที่และเวลาของ Java 8 ใหม่คุณสามารถใช้java.time.YearMonthคลาสได้ ดูออราเคิลกวดวิชา

// 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

2
วิธีการทำเช่นนี้ใน Date and Time API ใหม่ของ Java 8?
วอร์เรนเอ็ม Nocos

2
@ WarrenM.Nocos ขอโทษสำหรับการตอบสนองปลาย แต่ผมไม่ได้ใช้งานเดือนนี้ โปรดตรวจสอบการแก้ไขสำหรับการแก้ปัญหาสำหรับ Java 8.
Hemant Metalia

ในฐานะที่เป็นก่อนที่จะ Java 8 ... มากของjava.timeการทำงานย้อนรังเพลิง Java 6 & Java 7 ในThreeTen-ย้ายกลับโครงการ ดัดแปลงเพิ่มเติมสำหรับ Android รุ่นก่อนหน้าในโครงการThreeTenABP ดูวิธีการใช้ ThreeTenABP ...
Basil Bourque

43

สำหรับ java.util.Calendar

หากคุณมีการใช้java.util.Calendarฉันสงสัยว่าคุณต้องการ:

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

สำหรับ Joda เวลา

อย่างไรก็ตามโดยส่วนตัวแล้วฉันขอแนะนำให้ใช้Joda Timeแทนที่จะjava.util.{Calendar, Date}เริ่มด้วยซึ่งในกรณีนี้คุณสามารถใช้:

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

หมายเหตุว่าแทนที่จะแยกค่าสตริงทีมันจะดีกว่าที่จะได้รับแล้วแต่ราคาใดวันที่ / เวลา API คุณกำลังใช้ที่จะแยกมัน ในjava.util.*คุณอาจใช้SimpleDateFormat; ใน Joda DateTimeFormatterเวลาที่คุณต้องการใช้


27

คุณสามารถใช้Calendar.getActualMaximumวิธีการ:

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


7
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 และ 2012 ไม่ได้เป็นระยะเวลาเดียวกัน (ปีอธิกสุรทิน)
โรส

5

นี่คือวิธีการทางคณิตศาสตร์:

สำหรับปีเดือน (1-12):

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

3

ฉันจะไปหาทางออกเช่นนี้

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();
}

หากเดือนนั้นไม่ใช่เดือนกุมภาพันธ์ (92% ของคดี) ก็ขึ้นอยู่กับเดือนเท่านั้นและมีประสิทธิภาพมากกว่าที่จะไม่เกี่ยวข้องกับปี วิธีนี้คุณจะได้ไม่ต้องโทรตรรกะที่จะรู้ว่าไม่ว่าจะเป็นปีอธิกสุรทินและคุณไม่จำเป็นต้องได้รับในปี 92% ของกรณีที่ และมันก็เป็นรหัสที่สะอาดและยังสามารถอ่านได้มาก


1
ฉันต้องการปล่อยให้ตรรกะทั้งหมดเป็นวิธีการของห้องสมุดที่ได้รับการพิสูจน์แล้ว - ฉันคิดว่าคุณเพิ่มประสิทธิภาพก่อนเวลาอันควรและวิธีการในห้องสมุดนั้นไม่มีประสิทธิภาพ ยังคงอัปโหลดสำหรับการใช้งานจาวายุคใหม่
โอเล VV

@ OleV.V ทรูในหลายกรณีที่ออกจากการเพิ่มประสิทธิภาพให้กับห้องสมุดที่พิสูจน์แล้วว่าสามารถจะดีกว่า แต่ในกรณีนี้ห้องสมุดที่มีอยู่จะต้องผ่านเดือนและปี นั่นหมายความว่าฉันต้องทำทุกอย่างเพื่อรับปีอย่างไรก็ตามวิธีนั้นจะไม่ใช้มูลค่าเป็น 92% ของคดี ดังนั้นที่เป็นส่วนหนึ่งที่จะสามารถเพิ่มประสิทธิภาพไม่ได้สำหรับฉัน เหตุผลของฉันคล้ายกับเหตุผลที่คุณไม่ควรทำการเรียกเมธอดเพื่อรับค่าที่จะส่งผ่านไปยังตัวบันทึกซึ่งอาจถูกปิดใช้งาน ไม่มีวิธีที่คนตัดไม้สามารถปรับให้เหมาะสม
Stefan Mondelaers

1

ใน Java8 คุณสามารถใช้รับค่าช่วงจากเขตข้อมูลของวันที่

LocalDateTime dateTime = LocalDateTime.now();

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

นี้ช่วยให้คุณ parameterize บนสนาม


1

ง่ายเหมือนที่ไม่จำเป็นต้องนำเข้าอะไร

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 มันจะผิด แต่ฉันเห็นด้วยในแอปพลิเคชันส่วนใหญ่สิ่งนี้จะทำและมีประสิทธิภาพ
สเตฟาน Mondelaers

1
// 1 means Sunday ,2 means Monday .... 7 means Saturday
//month starts with 0 (January)

MonthDisplayHelper monthDisplayHelper = new MonthDisplayHelper(2019,4);
int numbeOfDaysInMonth = monthDisplayHelper.getNumberOfDaysInMonth();

1
เป็นที่น่าสังเกตว่ามันเหมาะสำหรับ Android ( android.util.MonthDisplayHelper)
barbsan

0
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);


    }

}

1
คำตอบนี้ให้คุณค่าอะไรกับคำตอบที่มีอยู่และเป็นที่ยอมรับ นอกจากนี้โปรดเพิ่มคำอธิบายหรือการเล่าเรื่องพร้อมกับรหัสของคุณ StackOverflow เป็นมากกว่าส่วนย่อยของห้องสมุด
Basil Bourque

0
public class Main {

    private static LocalDate local=LocalDate.now();
    public static void main(String[] args) {

            int month=local.lengthOfMonth();
            System.out.println(month);

    }
}

6
เพิ่มคำอธิบายบางอย่างเช่นกัน
BlackBeard

1
ยินดีต้อนรับสู่ Stack Overflow! ในขณะที่ข้อมูลโค้ดนี้อาจเป็นโซลูชันรวมถึงคำอธิบายช่วยปรับปรุงคุณภาพการโพสต์ของคุณ จำไว้ว่าคุณกำลังตอบคำถามสำหรับผู้อ่านในอนาคตและคนเหล่านั้นอาจไม่ทราบสาเหตุของการแนะนำรหัสของคุณ
yivi

0

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
วลาด

0

ช่วยทำให้เป็นเรื่องง่ายหากคุณไม่ต้องการ hardcode มูลค่าของปีและเดือนและคุณต้องการที่จะรับค่าจากวันที่และเวลาปัจจุบัน:

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 );

0

คุณสามารถใช้วิธีการ Calendar.getActualMaximum:

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

และ month-1 คือเพราะเดือนใช้จำนวนเดิมของเดือนในขณะที่ในวิธีใช้อาร์กิวเมนต์ตามด้านล่างใน Calendar.class

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

และ (เขตข้อมูล) จะเป็นดังนี้

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

0

วิธีการดังต่อไปนี้จะให้คุณไม่กี่วันในเดือนใดเดือนหนึ่ง

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

0

ความแปรปรวนที่เหมาะสมและมีประสิทธิภาพ:

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;
        }
    }
}

สำหรับรายละเอียดเพิ่มเติมเกี่ยวกับอัลกอริทึมเผ่นตรวจสอบที่นี่


-1
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;
    }
}

-1

มันใช้ได้ดีสำหรับฉัน

นี่คือเอาต์พุตตัวอย่าง

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

-1
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);

ไม่จำเป็นต้องตอบคำถามที่ได้รับการยอมรับแล้วจนกว่าคำตอบนั้นจะไม่ถูกต้อง แต่อย่างใด
Deepak
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.