§ 16. Тип данных структура (struct)

16.3. Использование структур для описания даты и времени

Пример 16.12. Текущее время задано в часах, минутах и секундах. Который час будет через k секунд?

Этапы выполнения задания

I. Исходные данные: v — структура, описывающая время, k — число секунд.

II. Результат: новое время.

III. Алгоритм решения задачи.

1. Ввод исходных данных.
2. 
Создадим две функции: tm_to_sek и sek_to_tm для перевода времени в секунды и секунд в формат времени (часы, минуты, секунды).

2.1. Переведем текущее время в секунды. Для этого просуммируем количество часов, умноженное на 3600 (количество секунд в часе), количество минут, умноженное на 60, и количество секунд. 
2.2. Увеличим секунды. 
2.3. Переведем секунды в формат времени. Секунды — это остаток от деления на 60 общего количества секунд. Минуты — это остаток от деления количества минут на 60.

3. Вывод результата.

IV. Описание переменных: k – int, v – struct.

Пример 16.13. Заданы две даты. Определить количество дней между ними.

Этапы выполнения задания

I. Исходные данные: d1, d2 — структуры, описывающие даты.

II. Результат: число дней между двумя датами.

III. Алгоритм решения задачи.

1. Ввод исходных данных.
2. 
Во многих программах (например, в Excel) дата хранится в виде числа. Это число — количество дней, прошедших от какой-то начальной даты. Часто за начало отсчета берется дата 01.01.1900. Переведем каждую дату в целое число. Расчет будем вести от 01.01.1900. Тогда порядковый номер дня (d.m.g) можно посчитать по формуле:

begin mathsize 18px style straight N space equals space straight d space plus space straight d subscript 1 space plus space straight d subscript 2 space plus space... space plus space straight d subscript straight m space minus space 1 end subscript space plus space left parenthesis straight g space minus space 1900 right parenthesis space asterisk times space 365 space plus space left parenthesis straight g space – space 1900 right parenthesis divided by 4 comma end style

где d  — номер дня в дате, d1, d2, ... dm - 1 — количество дней в месяцах, предшествующих заданному, (y – 1900) * 365 — количество дней за полный прошедший год до текущей даты, (g – 1900)/4  — количество дней, которые нужно добавить за прошедшие високосные годы. Формула буде верной для дат от 01.01.1900 до 28.02.2100. (2100 год не является високосным, поскольку 2100 делится на 100, но не делится на 400).

3. Создадим функцию date_to_int.
4. 
Вычислим порядковые номера для каждой даты.
5. 
Найдем разность между двумя порядковыми номерами.
6. 
Вывод результата.

IV. Описание переменных: d1, d2 – struct.

Пример 16.12.

V. Программа:

#include <iostream>

 

using namespace std;

 

struct vremja

{

  int ch, m, s;

};

 

int vr_to_sek(vremja t)

{

  int N;

  N = t.ch * 3600 +t.*60 + t.s;

  return N;

}

 

vremja sek_to_vr (int N)

{

  vremja t;

  t.= N % 60;

  t.= N / 60 %60;

  t.ch = N / 3600 % 24;

  return t;

}

 

int main()

{

  vremja v;

  cout << "vremja" << endl;

  cin >> v.ch >> v.>> v.s;

  int k;

  cout << "k = ";

  cin >> k;

  int sek = vr_to_sek(v);

  sek += k;

  vremja v1 = sek_to_vr(sek);

  cout << v1.ch << ":";

  cout << v1.<< ":";

  cout << v1.<< endl;

  return 0;

}

 VI. Тестирование.

Пример 16.13.

V. Программа:

#include <iostream>

#include <vector>

 

using namespace std;

 

struct date

{

  int d, m ,g;

};

int date_to_int(date t)

{

  vector <int> d = {31, 28, 31, 30, 
     31, 30, 31, 31, 30, 31, 30, 31};

  int N = t.;

  for (int i = 0; i < t.- 1; i++)

    N += d[i];

  N += (t.- 1900) * 365; 

  N += (t.- 1900) / 4;

  if (t.!= 1900 && t.% 4 == 0 &&

   (t.== 1 || t.==2 && t.< 29))

    N--;

  return N;

}

 

int main()

{

  date d1, d2;

  cout << "1 data" << endl;

  cin >> d1.>> d1.>> d1.g;

  cout << "2 data" << endl;

  cin >> d2.>> d2.>> d2.g;

  int n_d1 = date_to_int(d1);

  int n_d2 = date_to_int(d2);

  int k = abs(n_d1 - n_d2);

  cout << " mezdu datami " ;

  cout << k <<  " dnei" << endl;

  return 0;

}

 VI. Тестирование.

В функции преобразования необходима дополнительная проверка для случая, если текущий год является високосным. Тогда дополнительный номер должен быть добавлен только к датам после 28 февраля. 1900 г. исключается, поскольку он не является високосным.