В настоящей статье приводится программа на языке С (компилятор Borland C++ ver. 3.1) для работы с календарем. Программа имеет три режима работы. Получения наименования дня для указанной даты, вывод календаря на указанный год и вычисления промежутка в днях для двух указанных дат.
Если Вы хотите научиться программировать на языках C, C++, C#, PASCAL, DELPHI, BASIC, PYTHON, FORTRAN или ASSEMBLER, то можете позвонить мне по тел. 8-916-579-85-49 или написать на почту michail123@bk.ru. Михаил Львович. Кроме того, я обучаю математике, физике и информатике.
// ***************************************************************** // Программа работы с календарём. // Имеет три режима работы: // 0 - при задании ГОД МЕСЯЦ ДАТА получаем ДЕНЬ_НЕДЕЛИ. REG=0. // 1 - при задании ГОД выдает на экран/в файл календарь // на указанный год. REG=1. Файл при этом имеет имя ГОД.TXT. // 2 - количество дней, прошедших между двумя введенными датами // в формате ГОД МЕСЯЦ ДАТА. REG=2. // Календарь Григорианский. Допустим год, начиная с 1582. // ***************************************************************** #include <stdio.h> #include <conio.h> #include <stdlib.h> #include <math.h> // Прототипы используемых функций int pgw(int ); void fwp(int ); void fwim(int ); long fodn(int , int , int ); FILE *in; // текстовый файл int mdg[6*7*12]; // массив дней года char dn[]={"ПОНЕДЕЛЬНИК ВТОРНИК СРЕДА ЧЕТВЕРГ ПЯТНИЦА СУББОТА ВОСКРЕСЕНЬЕ"}; char mnm[]={" ЯНВАРЬ ФЕВРАЛЬ МАРТ АПРЕЛЬ МАЙ ИЮНЬ ИЮЛЬ АВГУСТ СЕНТЯБРЬ ОКТЯБРЬ НОЯБРЬ ДЕКАБРЬ"}; char mndn[]={"ПНВТСРЧТПТСБВС"}; int pw; int md[12]={31,28,31,30,31,30,31,31,30,31,30,31}; int main(void) { int d,m,g,i,j,k,kd,id,jmn; int dn1,mn1,gn1,dk1,mk1,gk1; int ms,nm,jm,reg; clrscr(); kd=0; puts("Определить день года (0), календарь на год (1) или кол-во дней между датами (2)"); scanf("%d",®); if (reg==1) { puts("nВведите ГОД и устр-во вывода 1/0 экран/файл "); scanf("%d%d",&g,&pw); if(!pw) { char fname [9]={" .txt"}; // имя файла itoa(g,fname,10); fname[4]='.'; fname[8]=0; // Открыть файл в режиме записи (w) текста (t) if (!(in=fopen(fname,"wt"))) { printf("Ошибка при обращении к файлу %sn", fname); getch(); return 0; } } fprintf(in,"КАЛЕНДАРЬ НА %d ГОД",g); } else { if (reg==0) { puts("nВведите nГОД МЕСЯЦ ДАТУ"); scanf("%d%d%d",&g,&m,&d); } else { if (reg==2) { // Введение анализируемых дат. puts("Введите анализируемые даты в формате ГОД МЕСЯЦ ДАТУn"); scanf("%d%d%d%d%d%d",&gn1,&mn1,&dn1,&gk1,&mk1,&dk1); printf("nМежду указанными датами прошло %ld дней ", labs(fodn(dn1,mn1,gn1)-fodn(dk1,mk1,gk1))); getch(); return 1; } } } // если текущий год високосный, то корректирую число дней в ФЕВРАЛЕ md[1]+=pgw(g); // За ОСНОВУ беру 1 января 1582 года - вторник (=2) = 01 01 1582 2. // подсчет кол-ва дней от ОСНОВЫ до требуемой. // В обычном годе 365=52*7+1 дней, т.е. каждый обычный год дает сдвиг // на один день вперед. Т.е. от ОСНОВЫ сдвиг вперед по обычным годам // в днях = ГОД-1582. Каждый високосный год дает ещё +1 день. // Таким образом общий сдвиг от ОСНОВЫ к первому дню нужного года= for(i=1582,kd=g-i; i<g; kd+=pgw(i++)); if(!reg) { // подсчет дополнительных дней, прошедших от начала нужного года // до первого дня нужного месяца for (i=0;i<m-1;i++) kd+=md[i]; // до требуемого дня нужного месяца kd+=d; } // пересчитываю все эти сдвиги в номер текущего дня. // В зависимости от режима REG 0/1 +01. id=((kd+4+reg)%7); if (!id) id=7; if (!reg) { printf("Днем недели для даты %d %d %d является ",d,m,g); for(i=(id-1)*11,j=1;j<=11;i++,j++) printf("%c",dn[i]); getch(); return 1; } // Заполнение всего массива ДАТ. // На каждый месяц отвожу 42 позиций, внутри которых свободно // (с учетом первого дня месяца) подряд располагаются дни месяца. // Цикл по месяцам ГОДА. // Первый день очередного месяца выпадает на день номер k внутри // 42-х дней, отведенных месяцу. for(i=0,id--;i<12;i++) { // цикл по дням очередного месяца. Заполняю его массив // подряд днями. for(j=1,k=i*42+id;j<=md[i];) { // отслеживаю текущий день недели id++; id=((id<=7)?(id):(id-7)); mdg[k++]=j++; // после заполнения массива надо подготовиться к следующему месяцу. // Его (следующего месяца) первый день будет отстоять от его начала // так, чтобы он был следующим днем недели по отношению к последнему // дню предыдущего месяца. } } // Вывод полученного календаря do { puts("Укажите формат вывода - 2/3/4/6 месяцев в строку "); scanf("%d",&ms); } while(!((ms==2) || (ms==3) || (ms==4) || (ms==6))); int npmg=-ms; // номер первого месяца группы // Цикл по выводимым горизонтально группам месяцов nm=1; for(i=1;i<=12/ms;i++) { npmg+=ms; // вывод в верхней строке названий месяцев fwp(6); // вызов функции вывода пробелов (pw)?(printf("n")):(fprintf(in,"n")); for(j=1;j<=ms;j++) { // вывод пробелов ПЕРЕД именем массива fwp(5); // вывод самого имени массив fwim(nm++); // вывод пробелов ПОСЛЕ имени массива fwp(5); } int jmn1=npmg*42-1; // Вывожу сами строки дат месяцев. Цикл по дням недели. for(k=0;k<7;k++) { jmn1++; (pw)?(printf("n%c%c",mndn[k*2],mndn[k*2+1])): (fprintf(in,"n%c%c",mndn[k*2],mndn[k*2+1])); // цикл по дням месяцев, выводимым в строку for(jm=1,jmn=jmn1;jm<=6*ms;jm++) { (!mdg[jmn])? ((pw)?(printf(" ")):(fprintf(in," "))): ((pw)?(printf("%3d",mdg[jmn])): (fprintf(in,"%3d",mdg[jmn]))); jmn+=7; } } } if(!pw) { fclose(in); puts("Календарь выведен в файл"); } getch(); return 1; } // Функция проверки года на високосность ДА/НЕТ 1/0. // Високосный год тот, номер готорого нацело делится на 4, // кроме тех, номер которых кончается на 00 и не делится // нацело на 400 (например 1800). int pgw(int g) { return ((g%4==0)&&(!((g%400!=0)&&(g%100)==0))); } // функция вывода пробелов на экран или в файл void fwp(int n) { for(int i=1;i<=n;((pw)?(printf(" ")):(fprintf(in," "))),i++); // 1 02 2 3 4 43 5 6 650 1 } // функция вывода имени массива void fwim(int n) { for(int i=1;i<=8;(pw)?(printf("%c",mnm[(n-1)*8+i++])): (fprintf(in,"%c",mnm[(n-1)*8+i++]))); } // Функция определения числа дней, прошедших от введения // Григорианского календаря до указанной даты. long fodn(int d, int m, int g) { int i; // подсчет общего кол-ва дней, прошедших от ОСНОВЫ до первого // января искомого года. long kd=(g-1582)*365; // За ОСНОВУ беру 1 января 1582 года - пятница (=5) = 01 01 1582 5. // подсчет кол-ва дней от ОСНОВЫ до требуемой. // Вначале считаю сколько високосных годов будет от ОСНОВЫ // до года непосредственно предшествующего нужному for(i=1582; i<g; kd+=pgw(i++)); // подсчет дополнительных дней, прошедших от начала нужного года // до первого дня нужного месяца for (i=0;i<m-1;kd+=md[i++]); // до требуемого дня нужного месяца kd+=d; // если текущий год високосный и месяц позже февраля, то +1 if (m>1) kd+=pgw(g); return kd; }