Построение вечного календаря. 2
МИНИСТЕРСТВО ОБРАЗОВАНИЯ И НАУКИ УКРАИНЫ
ХАРКОВСКИЙ НАЦИОНАЛЬНЫЙ УНИВЕРСИТЕТ РАДИОЭЛЕКТРОНИКИ
Кафедра информатики
КУРСОВАЯ РАБОТА
Тема: “Построение вечного календаря”
по дисциплине «Программирование»
ПОЯСНИТЕЛЬНАЯ ЗАПИСКА
Выполнил: Руководители:
студент группы КИ-11-1 Руденко Д. А.
Литвиненко А.В.
Харьков 2009
РЕФЕРАТ
Пояснительная записка к курсовой работе: 29 с., 4 таб., 8 рис., 4 раздела, 3 приложения, 3 источника.
Объект исследования – построение вечного календаря.
Цель работы – программная реализация вечного календаря (алгоритм расчёта дня недели по заданной дате). Систематизировать навыки и знания, полученные в процессе выполнения лабораторных работ по предмету «Программирование».
Метод исследования – изучение литературы, написания и отладки программ на компьютере.
Вечный календарь имеет большое значение в повседневной жизни. Данную программу можно использовать для определения дня недели интересующей даты.
Для реализации поставленной задачи, мной был использован алгоритм вычисления дня недели по заданной дате. Было предусмотрено два варианта задания даты. В ходе выполнения курсового проекта я изучил историю календарей, особенности построения вечного календаря в среде программирования. Рассмотрел основные алгоритмы вычисления дня недели, изучил их преимущества и недостатки.
Программа должна быть реализована на языке С++ в среде Visual C++.
СОДЕРЖАНИЕ
Введение………………………………………………………. |
4 |
1 Постановка задачи и сфера её применения…..………………...... |
5 |
2 Теоретическая часть…………………………… |
6 |
2.1 История календарей……………………..…………...... |
6 |
2.2 Описание использованного алгоритма.………...…………... |
11 |
2.3 Пример реализации алгоритма……………………………… |
11 |
3 Программная реализация………………………………….………. |
13 |
3.1 Описание алгоритма и структуры программы…………….. |
13 |
3.2 Описание программных средств……………………………. |
17 |
4 Инструкция пользователя…………………………………………. |
20 |
Заключение…………………………………………………… |
21 |
Перечень ссылок……………………………………… |
22 |
Приложение А Текст программы…… |
23 |
Приложение Б Результат………..……… |
28 |
Приложение В …………………………………………… |
29 |
ВВЕДЕНИЕ
Существуют разнообразные
Как правило, каждый метод имеет
две модификации — для
Я разработал свой алгоритм вычисления дня недели введённой даты, для этого я использовал следующее:
Для удобства номер месяца преобразовывается таким образом, чтобы март был первым месяцем, а февраль — двенадцатым и относился к прошлому году (например, май 1998 > 03 1998, январь 1983 > 11 1982). Для определения сдвига используется следующая формула: a = (14-месяц) div 12 (a — вспомогательная величина). Затем определяются год и месяц с учётом поправки: y = год - a; m=месяц+12·a-2.
Далее вся дата переводится в дни, т.е. количество лет в дате умножается на 365 + количество месяцев умножается на 30 + количество дней, внесённые в дату.
Далее уравниваются недостающие
дни к определённому месяцу при учитывании
високосных лет (+(год-1)/4-(год-1)/100+(год-
Именно этот алгоритм был использован в моей курсовой работе.
1 ПОСТАНОВКА ЗАДАЧИ И СФЕРА ЕЁ ПРИМЕНЕНИЯ
Целью данного курсового проекта является программная реализация вечного календаря (алгоритм расчёта дня недели по заданной дате).
Программа должна работать следующим образом:
– пользователь вводит дату,
– после выполнения программы на экран должен выводиться день недели, на который попадает эта дата.
Программа должна быть реализована на языке С++ в среде Visual C++.
2 ТЕОРЕТИЧЕСКАЯ ЧАСТЬ
В ходе выполнения курсового проекта я изучил историю календарей, особенности построения вечного календаря с среде программирования. Рассмотрел основные алгоритмы вычисления дня недели, изучил их преимущества и недостатки.
2.1. История календарей
Календарь, хотя и примитивный, появился уже в древнейших цивилизациях, когда люди начали планировать свою хозяйственную деятельность и определяться, когда им праздновать свои религиозные праздники.
История развития календарных систем по-своему увлекательна. В ней отразился не только процесс накопления человеком знаний об окружающем мире, но также борьба политиков и религиозных идей.
Даже с объективной точки зрения построение хорошего календаря - сложная, до сих пор не вполне решенная задача. Астрономы, математики, физики бились над ней с древних времен, уточняли периоды движения небесных тел, потом умножали и делили эти числа, стараясь построить все более совершенный календарь.
Юлианский календарь
Сегодня почти во всем мире используется календарь, практически доставшийся нам от древних римлян, которые в свою очередь заимствовали его у египтян. Но произошло это не сразу.
До нас не дошло точных сведений о зарождении римского календаря. Согласно Марку Теренцию Варрону (116-27 гг. до н.э.) сначала год календаря римлян состоял из 10 месяцев и 304 дней.
Первым месяцем был март (назван в честь бога войны Марса). Следующим шел апрель (от латинского "aperire" - "раскрывать", так как в этом месяце раскрываются почки на деревьях). Третий месяц был посвящен богине Майе - матери Меркурия. Четвертый в честь богини Юноны, супруги Юпитера, покровительницы женщин, был назван июнем.
Последующие месяцы носили числовые обозначения. А начинался год с первым весенним новолунием. Оставшиеся до весны дни римляне на месяцы не делили, жили всю зиму "в безвремении" до начала следующего года.
Последним, по Макробию (V в. н.э.), был введен лунный год в 355 дней с добавлением двух новых месяцев - января и февраля.Чтобы согласовать счет времени с солнечным циклом, через год вставлялся дополнительный месяц мерцедоний. В этот месяц, между прочим, полагалось возвращать долги. Продолжительность мерцедония определяли римские понтифики.
Цицерон (106-43 гг. до н.э.) утверждал, что понтифики злоупотребляли предоставленным им правом: за взятки удлиняли сроки пребывания на общественных должностях для своих друзей и укорачивали для своих врагов, манипулировали временем уплаты налогов.
Потом они, видимо, запутались, и со счетом дней в Риме началась полная неразбериха. Вольтер писал об этом времени: "Римские полководцы всегда побеждали, но никогда не знали, в какой день это случалось".
Устранить этот беспорядок решил первый римский император Гай Юлий Цезарь (100-44 гг. до н.э.).
Побывав в Египте, Цезарь имел возможность познакомиться с особенностями здешнего солнечного календаря. Проведенная им в 46 г. до н.э. календарная реформа позже была названа юлианской. Он пригласил в Рим группу астрономов во главе с Созигеном, и они решили, что лунный календарь надо заменить солнечным.
В юлианском календаре тропический год (время между двумя зимними солнцестояниями) считается равным 365,25 дней. Такая точность достигается за счет введения високосного года (366 дней), следующего через каждые три обычные года (365 дней).
В благодарность за упорядочение календаря, а также, учитывая выдающиеся заслуги Юлия Цезаря на военном и государственном поприщах, римский сенат принял решение переименовать месяц Quintilis, в котором родился Цезарь, в июль.
Римляне не сразу научились правильно считать високосные года (они вообще больше воевать любили), и поэтому правившему за Юлием Цезарем императору Октавиану Августу пришлось снова вставлять в календарь дополнительные дни для согласования с Солнцем.
Григорианский календарь
Введение високосного года, однако, не решило проблему полностью.
Так как год юлианского календаря все-таки несколько больше его астрономического значения, то с течением времени накапливается ошибка приблизительно в один день на каждые 128 лет. Долгое время на это внимания не обращали, хотя и знали. Наверное, слишком уж хлопотное это дело - календарная реформа.
К концу XVI столетия эта погрешность составляла уже около 10 дней. Это очень обеспокоило христианских священников.
Дело в том, что по сложившейся церковной традиции, христианская Пасха должна отмечаться в первое воскресенье после первого полнолуния после весеннего равноденствия. Расчет пасхальных дней на много лет вперед был произведен в 325 году н.э. При этом днем весеннего равноденствия ошибочно принято было считать 21 марта по юлианскому календарю. С течением лет реальная дата весеннего равноденствия сдвигалась все ближе к зиме и в XVI веке уже приходилась на 11 марта. Вместе с календарной датой весеннего равноденствия сдвигалась Пасха и другие церковные праздники. За усовершенствования календаря в XV веке взялась Римская Католическая Церковь.
В 1475 году папа Сикст IV пригласил
для этого в Рим выдающегося
немецкого астронома и
Многими известными в то
время учеными выдвигались
Григорианский календарь общепризнан в настоящее время. Интересно заметить, что и он не является абсолютно точным солнечным календарем. Ошибка в один 1 день в нем набегает за 3300 лет. Это, в частности, приводит к тому, что сейчас солнце проходит через точку весеннего равноденствия почти на 3 часа раньше, чем 400 лет назад. Позже были предложены более точные календарные системы, однако они не прижились.
Календарь в Православной Церкви
В христианском мире по сегодняшний
день нет единства в использовании
календаря. Восточная Православная
Церковь сразу же отказалась принять
григорианскую календарную
Во-первых, в григорианском календаре христианская Пасха иногда приходится на один день с еврейской или даже раньше нее, что некоторые православные считают недопустимым. Во-вторых, по старому стилю церковные праздники вычислять проще, так как он согласован с движением Луны. Как утверждает Архимандрит Рафаил: "Через юлианский календарь, его математико-символическую знаковую систему, время воцерковляется в ритмах богослужения, особенно в пасхалии."
Но, наверное, основная причина, по которой Русская Православная Церковь не переходит на новый стиль - это опасение раскола.
По мнению Юрия Белановского, руководителя информационно-аналитического отдела московского Центра духовного развития молодежи, русский Патриарх не ставит ребром вопрос о переходе на новый стиль, потому что не видит для этого серьезного повода и потому что у многих верующих, к сожалению, нет правильного представления о роли календаря в церковной жизни.
Большая часть верующих за
последние десять лет не смогла получить
базовых знаний, на основании которых
строится религиозная жизнь. А некоторые
влиятельные христиане-
Конечно, существование двух календарей - государственного и церковного - создает некоторое неудобство верующим людям. Остроумный выход из этой ситуации нашли христиане Константинопольской Православной Церкви и некоторых этногреческих церквей. Они живут по так называемому новоюлианскому календарю. Этот календарь формально еще точнее юлианского, но в ближайшие 800 лет он совпадает с григорианским.
2.2. Описание использованного алгоритма
В ходе выполнения курсового проекта я использовал алгоритм построения вечного календаря. Существуют разнообразные методы вычисления дня недели. Некоторые из них основываются на заранее просчитанных таблицах сдвигов, а некоторые вычисляют все необходимые значения «с нуля» при каждом запуске.
В алгоритм входит проверка введённого значения года на высокостность: каждый год который делится без остатка на 4, кроме годов которые делятся без остатка на 100, не считая года кратные 400(эти года есть високосными)).
В программе предусмотрены 2 варианта задания формата даты: «normal» (пр. 28 ноября 2008) и «american» (пр. 28 11 2008). В случаи не корректного задания даты программа выдает соответствующие сообщение.
Пошаговая работа алгоритма описана ниже на примере.
2.3. Пример реализации алгоритма
Рассмотрим выполнение алгоритма на примере.
Первый шаг. Программа делает запрос на выбор формата задания даты: 1 – «normal», other number – «american».
Второй шаг. Ввод даты в раннее выбранном формате. В случаи если выбран «normal» формат задания даты, программа присваивает месяцу его порядковый номер от начала года.
Третий шаг. Проверка корректности задания даты. В случаи если дата введена не правильно или введена не существующая дата (напр. 32 jan), программа выводит соответствующее сообщение и алгоритм продолжает выполняться с пункта 6.
Четвертый шаг. На следующем шаге программа проводит расчёты по григорианскому календарю с учетом всех его особенностей (т.е в учет берётся високосный год : каждый год который делится без остатка на 4, кроме годов которые делятся без остатка на 100, не считаю года кратные 400(эти года есть високосными)). Далее вся дата переводится в дни, т.е. количество лет в дате умножается на 365 + количество месяцев умножается на 30 + количество дней, внесённые в дату. Полученное значение делим на 7 и берём целую часть.
Пятый шаг. В зависимости какое число получилось, программа выводит сообщение. Если 0 – «Sunday», 1 – «Monday », 2 – «Tuesday», …, 6 – «Saturday».
Шестой шаг. Программа выводит запрос на продолжения работы. Если пользователь захочет продолжить работу с программой, алгоритм повторяется с шага 2. Иначе, программа завершает свою работу.
3 ПРОГРАММНАЯ РЕАЛИЗАЦИЯ
3.1 Описание алгоритма и структуры программы
Данная программа разработана для определения дня недели заданной даты.
При запуске программы на экран выводится запрос о выборе формата задания даты. Пользователь должен выбрать каким форматом ему удобней задавать дату, либо «normal» (пр. 28 nov 2008), либо «american» (пр 28 11 2009).
Следующим этапом выполнения программы является запрос о вводе даты, в порядке: день, месяц, год, в том формате, который был выбран раннее. В случае если дата была введена не корректно, на экран выводится соответствующее сообщение. В противном случае выполняется расчёт дня недели.
Результатом программы является день недели на который попадает заданная дата. Далее идёт запрос о продолжении работы с программой, если пользователь предпочтёт продолжить – алгоритм выполнится заново, а если пользователь предпочтёт не продолжать работу с программой – программа завершается.
Ниже приведен поэтапный пример выполнения программы:
- Запрос выбора формата задания даты
Рис. 3.1 – Выбор формата задания даты
Предположим, на первом этапе был выбран «normal» формат задания даты.
2. Ввод даты: число, месяц, год.
Рис. 3.2 – Задание даты
3. Выполнения
программы и запрос на
Рис. 3.3 – Запрос на продолжение работы с программой
4. Если пользователь введёт «yes», он программа вернётся к пункту 2.
Рис. 3.4 – Продолжение работы с программой
Если пользователь введёт «no», то программа завершит своё выполнение:
Рис. 3.5 – Завершение работы программы
Полностью аналогичен алгоритм, если выбрать «american» формат задания даты:
Рис. 3.6 – Работа программы при выборе «american»
формата задания даты
3.2 Описание использованных программных средств
Таблица 4.1–Описание переменных в функции main (главная функция)
Переменная |
Тип |
Описание |
d |
int |
День |
m |
int |
Месяц |
y |
int |
Год |
x |
int |
День недели |
a |
int |
Выбор формата задания даты |
n |
int |
Счётчик |
i |
int |
Счётчик |
q1 |
char |
Объект типа char который содержит в себе сообщение «yes» |
q2 |
char |
Запрос на продолжение работы с программой |
Таблица 4.2–Описание переменных в функции fun1 (функция просчёта дня недели)
Переменная |
Тип |
Описание |
d |
int |
День |
m |
int |
Месяц |
y |
int |
Год |
a |
int |
Промежуточное значение |
b |
int |
Промежуточное значение |
c |
int |
Промежуточное значение |
Таблица 4.3–Описание переменных в функции fun2 (функция проверки корректности задания дат)
Переменная |
Тип |
Описание |
y1 |
int |
Месяц |
x1 |
int |
Промежуточное значение |
Таблица 4.4–Описание переменных в функции fun3 (функция корректировки расхождения количества дней в месяце)
Переменная |
Тип |
Описание |
м |
int |
Месяц |
у |
int |
Год |
x1 |
int |
Промежуточное значение |
Описание использованных функций:
1. void main (главная функция)
Главная функция программы. Она вызывает в себе остальные функции, проводит основные расчёты, выполняет различные преобразования, выводит результат.
2. int f1 (Функция просчёта дня недели)
Функция, которая осуществляет окончательный расчёт дня недели, основная формула.
3. int f2 (Функция проверки корректности записи месяца)
Функция, которая осуществляет проверку корректности записи месяца.
4. int f3 (Функция корректировки расхождения количества дней в месяце)
Функция, которая возвращает количество недостающих дней в пройденных месяцах, дополняя их.
4 ИНСТРУКЦИЯ ПОЛЬЗОВАТЕЛЯ
При запуске программы выводится окно со следующими запросами:
1. Выберете формат задания даты.
2. Ввод значения 1, если хотите выбрать «normal» формат (пр 28 nov 2008), ввод значения 2, если хотите выбрать «american» формат (пр 28 11 2008)
3. Ввод даты: день, месяц, год, в раннее выбранном формате.
На экран выводится день недели, на который попадает заданный день. Появляется запрос на продолжение работы с программой.
4. В случае если вы ввели «yes» программа повторит выполнение с пункта 2, в случае если вы ввели «no», то программа завершит свою работу.
ВЫВОД
В данном курсовом проекте была разработана программа, реализующая вечный календарь. Программа была написана на Microsoft Visual C++ 2006.
В ходе выполнения курсового проекта я изучил историю календарей, особенности построения вечного календаря с среде программирования. Рассмотрел основные алгоритмы вычисления дня недели, изучил их преимущества и недостатки.
Также были углублены знания, полученные в процессе выполнения лабораторных работ по предмету «Программирование».
ПЕРЕЧЕНЬ ССЫЛОК
- Х. Дейтел, П. Дейтел. Как программировать на C++: Пер. с англ. - Москва: ЗАО "Издательство БИНОМ", 1998. 1024с.
- Г. Шилдт. Самоучитель C++: Пер. с англ. - Санкт-Петербург: BHV-Санкт-Петербург, 1998. 620с.
- Конспект лекций.
Приложение А
Текст программы
#include <iostream>
#include <string.h>//работа со строками
using namespace std;
/*функция просчёта дня недели*/
int fun1(int d, int m, int y)
{
int a, b, c=0;//промежуточные значения
b = fun3(m,y);
a = (y-1)/4;
if((y/4*4 == y && y/100*100 != y) || y/400*400 == y)//проверка на високосный год
c = -1;
if(m == 2)//если февраль считать по этой формуле
return y*365+m*30+d+a+b-(y-1)/100+(y-
else
{
if(m == 4 || m == 6 || m == 9 || m == 11)//если эти месяцы – апрель, июнь, сентябрь, ноябрь, то считать по этой формуле
return y*365+m*30+d+a+b-(y-1)/100+(y-
else return y*365+m*30+d+a+b-(y-1)/100+(y-
}
}
/*функция проверки корректности задания дат*/
int fun2(int y1)
{
int x1;//промежуточная переменная
switch(y1)//переключатель
{
case 1: x1=1;
break;
case 2: x1=-2;
break;
case 3: x1=1;
break;
case 4: x1=0;
break;
case 5: x1=1;
break;
case 6: x1=0;
break;
case 7: x1=1;
break;
case 8: x1=1;
break;
case 9: x1=0;
break;
case 10: x1=1;
break;
case 11: x1=0;
break;
case 12: x1=1;
break;
}
return x1;//значение которое возвращает функция
}
int fun3(int m, int y)
{
int x1;//промежуточная переменная
if((y/4*4 == y && y/100*100 != y) || y/400*400 == y)
switch(m)//переключатель
{
case 1: x1=1;
break;
case 2: x1=0;
break;
case 3: x1=1;
break;
case 4: x1=1;
break;
case 5: x1=2;
break;
case 6: x1=2;
break;
case 7: x1=3;
break;
case 8: x1=4;
break;
case 9: x1=4;
break;
case 10: x1=5;
break;
case 11: x1=5;
break;
case 12: x1=6;
break;
}
else
switch(m)//переключатель
{
case 1: x1=1;
break;
case 2: x1=-1;
break;
case 3: x1=0;
break;
case 4: x1=0;
break;
case 5: x1=1;
break;
case 6: x1=1;
break;
case 7: x1=2;
break;
case 8: x1=3;
break;
case 9: x1=3;
break;
case 10: x1=4;
break;
case 11: x1=4;
break;
case 12: x1=5;
break;
}
return x1;//значение которое возвращает функция
}
/*главная функция*/
void main()
{
int d, m, y, x, a, n=1;//переменные которые, соответственно: день, месяц, год, день недели, выбор формата, промежуточная переменная
char q1[]= "yes", q2[4];//переменные которые проверяют продолжать работу с программой или нет
cout << "Select the format of writing dates,then: 1 - normal (ex. 01 jan 2008), other number - american (ex. 01 01 2008) \n";