По порядковому номеру дня в году определить число и месяц - 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;
}

Объяснение кода листинга программы

  1. Типы данных:
    • EWeekday - перечисление (enum), представляющее дни недели
    • EMonth - перечисление (enum), представляющее месяцы года
    • char* - указатель на строку, используемый для хранения названий дней недели и месяцев
    • int - целочисленный тип данных, используемый для представления года, номера дня и месяца
    • time_t - арифметический тип данных, используемый для представления времени в Unix-системах
    • struct tm - структура, используемая для хранения информации о времени в формате ГГГГ-ММ-ДД ЧЧ:ММ:СС
  2. Переменные:
    • dayFromYearStart - номер дня с начала года
    • monthDays и monthDaysLeap - массивы, содержащие количество дней в каждом месяце для обычного и високосного года соответственно
    • year - переменная, представляющая введенный год
    • timeinfo - структура, содержащая информацию о текущем времени
    • time_t rawtime; - переменная, используемая для хранения временной метки
  3. Функции:
    • DayToString - функция, преобразующая значение переменной типа EWeekday в строку с названием дня недели
    • MonthToString - функция, преобразующая значение переменной типа EMonth в строку с названием месяца
    • IsLeapYear - функция, проверяющая, является ли год високосным
    • FindDayAndMonth - функция, определяющая номер месяца и дня с начала года для заданного количества дней
    • main - функция, являющаяся точкой входа в программу
  4. Описание работы программы:
    • Пользователю предлагается ввести год, начиная с 1970. Если год не является допустимым, программа выводит сообщение об ошибке.
    • Затем пользователю предлагается ввести номер дня с начала года. Если введенное значение не является допустимым, программа выводит сообщение об ошибке.
    • После успешного ввода года и дня программа определяет, является ли год високосным, и, исходя из этого, определяет месяц и день с начала года.
    • Наконец, программа выводит на экран дату в формате день месяц год, день недели.

Оцени полезность:

12   голосов , оценка 3.583 из 5
Похожие ответы