2014-11-30 2 views
1

Я пытаюсь создать функцию, в которой задан год, где year > 1999, и возвращает значение 0-6, где Sunday = 0, Monday = 1 ... Saturday = 6, что соответствует дню недели, когда первый день ноября включен. Поскольку я знаю 1 ноября 2000 года 3 (среда), я использую это как NOV1. Я знаю, что мне нужно помнить годы високосного поведения, поэтому я должен сделать заявление if, которое поможет. Я не знаю, почему он не работает должным образом в течение лет, превышающих 2100. Помогите!Функция дня недели не работает

public static int firstOfMonth(int year) 
{ 
    int raw = year - 2000; 
    int leapYears = raw/4; 
    int nonLeapYears = 0; 
    if (raw >= 100) 
    { 
    nonLeapYears = raw/100; 
    leapYears = leapYears - (nonLeapYears - (nonLeapYears/4)); 
    } 
    else 
    { 
    nonLeapYears = 0; 
    } 
    return (((NOV1 + (raw * 365) - leapYears)) % 7); 
} 

снова, Nov1 = 3

+4

Даты и время - невероятно сложные конструкции для программирования. Как правило, лучше использовать API Java «Календарь». – christopher

+0

Как правило, лучше использовать что-то вроде времени в стиле Joda, чем невероятно плохо спроектированный календарь api. –

+0

@christopher Это никогда не рекомендуется использовать API «Календарь», это ужасный API. Java8 получил 'java.time', и есть также joda-время, которое вы можете использовать, если вы запускаете более ранний jre – amit

ответ

3

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


Часть причины ошибки, подобные этому, могут возникать, и их так трудно заметить, когда окружающий код становится чрезмерно сложным. Легче понять, что происходит, когда вы упрощаете код.

Например, весь этот блок кода:

int leapYears = raw/4; 
int nonLeapYears = 0;  
if (raw >= 100) 
    { 
    nonLeapYears = raw/100; 
    leapYears = leapYears - (nonLeapYears - (nonLeapYears/4)); 
    } 
    else 
    { 
    nonLeapYears = 0; 
    } 

все это может быть упрощено до:

int leapYears = int(raw/4) - int(raw/100) + int(raw/400); 

Это каждый четвертый год минус лет делится на 100, за исключением лет и делится на 400. Марка смысл? После того, как у вас есть число високосных лет, которые прошли, вычисляя количество дней с 1 ноября 2000 года должно быть простым, как:

365 * raw + leapYears; 

Вы должны добавить как многие дополнительные дни есть високосные года, поскольку високосный год имеет 366 дней. Таким образом, ваше возвращение заявление должно быть:

return (NOV1 + 365 * raw + leapYears) % 7; 

В конце концов, вы должны иметь что-то вроде этого:

public static int firstOfMonth(int year) 
{ 
    int raw = year - 2000; 
    int leapYears = int(raw/4) - int(raw/100) + int(raw/400); 
    return (NOV1 + 365 * raw + leapYears) % 7; 
} 
+0

Ответит ли это на вопрос? Решает ли она фактическую проблему, поднятую ОП? Если да - пожалуйста, уточните, где и как. Или это просто «украшение кода»? – amit

+0

И в примечании «благоустройство кода»: Меньше строк кода! = Более чистый/более читаемый/лучший код во всех случаях. – drewmoore

+0

Спасибо! Мой код, как правило, ужасно неясен, и это помогло тонну! – SuperCoder99

0

Я думаю, что ваш код работает до 2400. года Вам нужно проверить, если год делится на 400 - тогда это високосный год ...

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