По порядковому номеру дня в году определить число и месяц - C (СИ)
Формулировка задачи:
прога на С
нужно чтобы программа по порядковому номеру дня в году определяла его число и месяц, год должны задавать с клавиатуры, и должно считываться к примеру 1 января -это понедельник значит 2 января-вторник
как это сделать?
помогите пожалуйста)
Решение задачи: «По порядковому номеру дня в году определить число и месяц»
textual
Листинг программы
#include <stdio.h>
#include <time.h>
#include <locale.h>
typedef enum _EWeekday
{ Sunday,
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday
} EWeekday;
typedef enum _EMonth
{ January,
February,
March,
April,
May,
June,
July,
August,
September,
October,
November,
December
} EMonth;
char *DayToString (EWeekday day)
{ switch (day)
{ case Sunday: return "воскресенье";
case Monday: return "понедельник";
case Tuesday: return "вторник";
case Wednesday: return "среда";
case Thursday: return "четверг";
case Friday: return "пятница";
case Saturday: return "суббота";
}
}
char *MonthToString (EMonth month)
{ switch (month)
{ case January: return "января";
case February: return "февраля";
case March: return "марта";
case April: return "апреля";
case May: return "мая";
case June: return "июня";
case July: return "июля";
case August: return "августа";
case September: return "сентября";
case October: return "октября";
case November: return "ноября";
case December: return "декабря";
}
}
int IsLeapYear (int year)
{ return (year & 3) == 0 && ((year % 25) != 0 || (year & 15) == 0);
}
void FindDayAndMonth (int daysFrom1January, int monthDays[], int *mday, int *month)
{ int i, sum;
for (i = 0, sum = 0; i<12; i++)
{ sum += monthDays[i];
if (daysFrom1January <= sum)
{ *month = i;
*mday = daysFrom1January - sum + monthDays[i];
return;
}
}
}
int main()
{ setlocale(LC_CTYPE, "Russian");
int monthDays[] = {31,28,31,30,31,30,31,31,30,31,30,31};
int monthDaysLeap[] = {31,29,31,30,31,30,31,31,30,31,30,31};
time_t rawtime;
struct tm * timeinfo;
int year, dayFromYearStart, enterCheck = 0, leapCheck, totalDays;
do
{ printf ("Введите год Y >= 1970\n\tY = ");
enterCheck = scanf("%d", &year) == 1 && year >= 1970;
fflush (stdin);
} while (enterCheck != 1);
if (!IsLeapYear (year))
{ printf("Этот год невисокосный\n\n");
totalDays = 365;
}
else
{ printf("Этот год високосный\n\n");
totalDays = 366;
}
enterCheck = 0;
do
{ printf ("Введите номер дня с начала года 1<=N<=%d\n\tN = ", totalDays);
enterCheck = scanf("%d", &dayFromYearStart) == 1 && dayFromYearStart >= 1 && dayFromYearStart <= totalDays;
fflush (stdin);
} while (enterCheck != 1);
time (&rawtime);
timeinfo = localtime (&rawtime);
timeinfo->tm_year = year - 1900;
if (!IsLeapYear (year))
FindDayAndMonth (dayFromYearStart, monthDays, &timeinfo->tm_mday, &timeinfo->tm_mon);
else
FindDayAndMonth (dayFromYearStart, monthDaysLeap, &timeinfo->tm_mday, &timeinfo->tm_mon);
mktime (timeinfo);
printf ("\n\nЭтот день: %02d %s %d года, %s", timeinfo->tm_mday, MonthToString ((EMonth) timeinfo->tm_mon), year, DayToString((EWeekday) timeinfo->tm_wday));
getchar();
return 0;
}
Объяснение кода листинга программы
- Типы данных:
EWeekday- перечисление (enum), представляющее дни неделиEMonth- перечисление (enum), представляющее месяцы годаchar*- указатель на строку, используемый для хранения названий дней недели и месяцевint- целочисленный тип данных, используемый для представления года, номера дня и месяцаtime_t- арифметический тип данных, используемый для представления времени в Unix-системахstruct tm- структура, используемая для хранения информации о времени в формате ГГГГ-ММ-ДД ЧЧ:ММ:СС
- Переменные:
dayFromYearStart- номер дня с начала годаmonthDaysиmonthDaysLeap- массивы, содержащие количество дней в каждом месяце для обычного и високосного года соответственноyear- переменная, представляющая введенный годtimeinfo- структура, содержащая информацию о текущем времениtime_t rawtime;- переменная, используемая для хранения временной метки
- Функции:
DayToString- функция, преобразующая значение переменной типаEWeekdayв строку с названием дня неделиMonthToString- функция, преобразующая значение переменной типаEMonthв строку с названием месяцаIsLeapYear- функция, проверяющая, является ли год високоснымFindDayAndMonth- функция, определяющая номер месяца и дня с начала года для заданного количества днейmain- функция, являющаяся точкой входа в программу
- Описание работы программы:
- Пользователю предлагается ввести год, начиная с 1970. Если год не является допустимым, программа выводит сообщение об ошибке.
- Затем пользователю предлагается ввести номер дня с начала года. Если введенное значение не является допустимым, программа выводит сообщение об ошибке.
- После успешного ввода года и дня программа определяет, является ли год високосным, и, исходя из этого, определяет месяц и день с начала года.
- Наконец, программа выводит на экран дату в формате
день месяц год, день недели.