2014-10-01 2 views
0

Я пытаюсь рассчитать количество дней в месяц с указанием номера года и месяца. Вот что я до сих пор.Расчет количества дней в месяце без календаря

public static int daysInMonth(int m, int y) { 
    int d; 
    if (m == 1 || m == 3 || m == 5 || m == 7 
      || m == 8 || m == 10 || m == 12) { 
     d = 31; 
    } else if (m == 4 || m == 6 || m == 9 || m == 11) { 
     d = 30; 
    } else if (y % 4 == 0 && m == 2) { 
     d = 29; 
    } else if (m == 2) { 
     d = 28; 
    } else {  
     d = 0;  
    } 
    return d; 
    } 

К сожалению, он не работает должным образом в течение второго месяца високоснов.

Как исправить это, не используя класс Calendar?

+0

Какой точно провал? – gtgaxiola

+0

Итак, в чем именно ваш вопрос? Если вы просто хотите, чтобы ваш код выглядел лучше или работал более эффективно, вы должны, вероятно, спросить об этом на http://codereview.stackexchange.com/ –

+0

Если вам просто нужно найти ответ о том, сколько дней в этом месяце, уже есть решение [здесь] (http://stackoverflow.com/questions/8940438/number-of-days-in-particular-month-of-particular-year) –

ответ

0

Я бы хранить дни месяца в целочисленном массиве с первым индексом как нулевое значение, чтобы уменьшить условные

public static int daysInMonth(int m, int y) { 
    int[] days = {0, 31, 28, 31, ... 31}; 
    if (m == 2 && y % 4 == 0) { 
     return 29; 

    } else { 
     return days[m]; 
    } 

}

Вы, вероятно, хотите, чтобы добавить некоторые проверки, чтобы убедитесь, что параметр т всегда меньше, чем 13 (количество месяцев плюс нулевое значение в начале)

1

http://ideone.com/H4VAvv

W с вашим случаем 2,2016 выход выходит, как ожидалось.

/* package whatever; // don't place package name! */ 

import java.util.*; 
import java.lang.*; 
import java.io.*; 

/* Name of the class has to be "Main" only if the class is public. */ 
class Ideone 
{ 
public static void main (String[] args) throws java.lang.Exception 
{ 
    System.out.println(daysInMonth(2,2016)); 
} 
public static int daysInMonth(int m, int y) { 
int d; 
if (m == 1 || m == 3 || m == 5 || m == 7 
     || m == 8 || m == 10 || m == 12) { 
    d = 31; 
} else if (m == 4 || m == 6 || m == 9 || m == 11) { 
    d = 30; 
} else if (y % 4 == 0 && m == 2) { 
    d = 29; 
} else if (m == 2) { 
    d = 28; 
} else {  
    d = 0;  
} 
return d; 
} 
} 
+0

Согласен, не видя проблемы с февралем 2016 года. Ваш метод возвращает 29 дней, как и ожидалось. – rajah9

2

Вам необходимо правильно рассчитать високосные годы:

public static int daysInMonth(int m, int y) { 
    int d; 
    if (m == 1 || m == 3 || m == 5 || m == 7 
      || m == 8 || m == 10 || m == 12) { 
     d = 31; 
    } else if (m == 4 || m == 6 || m == 9 || m == 11) { 
     d = 30; 
    } else if (isLeapYear(y) && m == 2) { 
     d = 29; 
    } else if (m == 2) { 
     d = 28; 
    } else { 
     d = 0; 
    } 
    return d; 
} 

public static boolean isLeapYear(int year) { 
    if (year % 4 != 0) { 
    return false; 
    } else if (year % 400 == 0) { 
    return true; 
    } else if (year % 100 == 0) { 
    return false; 
    } else { 
    return true; 
    } 
} 

См here.

Полное описание доступно только на английском языке и на русском языке.

import java.util.HashSet; 
import java.util.Arrays; 
import java.util.List; 

class MyClass { 

    public static void main(String[] args) { 
    List<Integer> leapYears = Arrays.asList(1804, 1808, 1812, 1816, 1820, 1824, 1828, 1832, 1836, 1840, 1844, 1848, 1852, 1856, 1860, 1864, 1868, 1872, 1876, 1880, 1884, 1888, 1892, 1896, 1904, 1908, 1912, 1916, 1920, 1924, 1928, 1932, 1936, 1940, 1944, 1948, 1952, 1956, 1960, 1964, 1968, 1972, 1976, 1980, 1984, 1988, 1992, 1996, 2000, 2004, 2008, 2012, 2016, 2020, 2024, 2028, 2032, 2036, 2040, 2044, 2048, 2052, 2056, 2060, 2064, 2068, 2072, 2076, 2080, 2084, 2088, 2092, 2096, 2104, 2108, 2112, 2116, 2120, 2124, 2128, 2132, 2136, 2140, 2144, 2148, 2152, 2156, 2160, 2164, 2168, 2172, 2176, 2180, 2184, 2188, 2192, 2196, 2204, 2208, 2212, 2216, 2220, 2224, 2228, 2232, 2236, 2240, 2244, 2248, 2252, 2256, 2260, 2264, 2268, 2272, 2276, 2280, 2284, 2288, 2292, 2296, 2304, 2308, 2312, 2316, 2320, 2324, 2328, 2332, 2336, 2340, 2344, 2348, 2352, 2356, 2360, 2364, 2368, 2372, 2376, 2380, 2384, 2388, 2392, 2396, 2400); 
    for(Integer year = 1804; year < 2400; year++) { 
     for(Integer month : Arrays.asList(1,3,5,7,8,10,12)) { 
     assert daysInMonth(month, year) == 31; 
     } 
     for(Integer month : Arrays.asList(4,6,9,11)) { 
     assert daysInMonth(month, year) == 30; 
     } 
     if(leapYears.contains(year)) { 
     assert daysInMonth(2, year) == 29; 
     } 
     else { 
     assert daysInMonth(2, year) == 28; 
     } 
    } 
    } 

    public static int daysInMonth(int m, int y) { 
    HashSet<Integer> monthsWith31Days = new HashSet<Integer>(Arrays.asList(1,3,5,7,8,10,12)); 
    HashSet<Integer> monthsWith30Days = new HashSet<Integer>(Arrays.asList(4,6,9,11)); 

    if(monthsWith31Days.contains(m)) { 
     return 31; 
    } else if(monthsWith30Days.contains(m)) { 
     return 30; 
    } 
    else if(isLeapYear(y)) { 
     return 29; 
    } 
    else { 
     return 28; 
    } 
    } 

    public static boolean isLeapYear(int year) { 
    if (year % 4 != 0) { 
     return false; 
    } else if (year % 400 == 0) { 
     return true; 
    } else if (year % 100 == 0) { 
     return false; 
    } else { 
     return true; 
    } 
    } 
} 
0

Кроме того, ради консистенции, в повторное использование Date.isLeapYear в вашем daysInMonth вместо жесткого кодирования y % 4 == 0

Смежные вопросы