Работа с датой и временем

Основные функции для работы с датой и временем в языке C++ объявлены в заголовочном файле ctime (файл time.h в языке C). В этом файле объявлены также следующие типы данных:

  • clock_t — возвращается функцией clock(). Объявление типа:
typedef long clock_t;
  • time_t — используется для представления времени в виде целочисленного значения. Размер типа зависит от настроек компилятора. Объявление типа:
typedef __time32_t time_t; // В проекте Test32
typedef __time64_t time_t; // В проекте Test64

Объявления типов __time32_t и __time64_t выглядят так:

typedef long __time32_t;
typedef __int64 __time64_t;
#define __int64 long long

Некоторые функции в качестве значения возвращают указатель на структуру tm. Объявление структуры tm выглядит следующим образом:

struct tm {
   int tm_sec;   // Секунды (число от 0 до 59, изредка до 61)
   int tm_min;   // Минуты (число от 0 до 59)
   int tm_hour;  // Час (число от 0 до 23)
   int tm_mday;  // День месяца (число от 1 до 31)
   int tm_mon;   // Месяц (число от 0 (январь) до 11 (декабрь))
   int tm_year;  // Год, начиная с 1900 года
   int tm_wday;  // День недели (число от 0 до 6 (0 - это воскресенье,
                 // 1 - это понедельник, ..., 6 - это суббота))
   int tm_yday;  // День в году (число от 0 до 365)
   int tm_isdst; // Если больше 0, значит действует летнее время
                 // Если 0, значит летнее время не установлено
                 // Если меньше 0, то информации нет
};
Примечание

Получение текущей даты и времени

Получить текущую дату и время позволяют следующие функции:

  • time() — возвращает количество секунд, прошедших с начала эпохи (с 1 января 1970 г.). Прототип функции:
#include <ctime> /* или #include <time.h> */
time_t time(time_t *Time);

Функцию можно вызвать двумя способами, передавая в качестве параметра нулевой указатель или адрес переменной, в которую будет записано возвращаемое значение. Пример:

// Передаем нулевой указатель
time_t t1 = std::time(nullptr);
std::cout << t1 << std::endl;  // 1554412153
time_t t2;
std::time(&t2);                // Передаем адрес переменной
std::cout << t2 << std::endl;  // 1554412153

Вместо функции time() можно использовать функцию _time64(). Число перед открывающей круглой скобкой означает количество бит. Прототип функции:

#include <ctime> /* или #include <time.h> */
__time64_t _time64(__time64_t *Time);

Пример использования:

__time64_t t1 = _time64(nullptr);
std::cout << t1 << std::endl;  // 1554412545
  • gmtime() — возвращает указатель на структуру tm с универсальным временем (UTC) или нулевой указатель в случае ошибки. В качестве параметра указывается адрес переменной, которая содержит количество секунд, прошедших с начала эпохи. Чтобы получить текущую дату в качестве параметра следует передать результат выполнения функции time(). Прототип функции:
#include <ctime> /* или #include <time.h> */
struct tm *gmtime(const time_t *Time);

Пример использования функции:

tm *ptm = nullptr;
time_t t = std::time(nullptr);
ptm = std::gmtime(&t);
if (!ptm) {
   std::cout << "Error" << std::endl;
   exit(1);
}
std::cout << ptm->tm_mday << std::endl;  // 4
std::cout << ptm->tm_mon << std::endl;   // 3 (апрель)
std::cout << ptm->tm_year << std::endl;
// 119 (1900 + 119 = 2019 г.)
std::cout << ptm->tm_hour << std::endl;  // 21
std::cout << ptm->tm_min << std::endl;   // 22
std::cout << ptm->tm_sec << std::endl;   // 53
std::cout << ptm->tm_wday << std::endl;  // 4 (четверг)
std::cout << ptm->tm_yday << std::endl;  // 93
std::cout << ptm->tm_isdst << std::endl; // 0

Вместо функции gmtime() можно использовать функцию _gmtime64(). Число перед открывающей круглой скобкой означает количество бит. Прототип функции:

#include <ctime> /* или #include <time.h> */
struct tm *_gmtime64(const __time64_t *Time);

Вместо функции gmtime() лучше использовать функцию gmtime_s() (_gmtime64_s() вместо _gmtime64()). Прототипы функций:

#include <ctime> /* или #include <time.h> */
errno_t gmtime_s(struct tm *Tm, const time_t *Time);
errno_t _gmtime64_s(struct tm *Tm, const __time64_t *Time);

Если ошибок нет, то функции возвращают значение 0. При наличии ошибки возвращается значение макроса EINVAL (значение равно 22) и переменная errno устанавливается равной EINVAL. Пример использования функции gmtime_s():

tm Tm;
time_t t = std::time(nullptr);
errno_t err = gmtime_s(&Tm, &t);
if (err) {
   std::cout << "Error" << std::endl;
   exit(1);
}
std::cout << Tm.tm_mday << std::endl;  // 4
std::cout << Tm.tm_mon << std::endl;   // 3 (апрель)
std::cout << Tm.tm_year << std::endl;  // 119 (2019 г.)
std::cout << Tm.tm_hour << std::endl;  // 21
std::cout << Tm.tm_min << std::endl;   // 36
std::cout << Tm.tm_sec << std::endl;   // 31
std::cout << Tm.tm_wday << std::endl;  // 4 (четверг)
std::cout << Tm.tm_yday << std::endl;  // 93
std::cout << Tm.tm_isdst << std::endl; // 0
  • localtime() — возвращает указатель на структуру tm с локальным временем или нулевой указатель в случае ошибки. В качестве параметра указывается адрес переменной, которая содержит количество секунд, прошедших с начала эпохи. Чтобы получить текущую дату в качестве параметра следует передать результат выполнения функции time(). Прототип функции:
#include <ctime> /* или #include <time.h> */
struct tm *localtime(const time_t *Time);

Пример использования функции:

tm *ptm = nullptr;
time_t t = std::time(nullptr);
ptm = std::localtime(&t);
if (!ptm) {
   std::cout << "Error" << std::endl;
   exit(1);
}
std::cout << ptm->tm_mday << std::endl;  // 5
std::cout << ptm->tm_mon << std::endl;   // 3 (апрель)
std::cout << ptm->tm_year << std::endl;  // 119 (2019 г.)
std::cout << ptm->tm_hour << std::endl;  // 0
std::cout << ptm->tm_min << std::endl;   // 45
std::cout << ptm->tm_sec << std::endl;   // 40
std::cout << ptm->tm_wday << std::endl;  // 5 (пятница)
std::cout << ptm->tm_yday << std::endl;  // 94
std::cout << ptm->tm_isdst << std::endl; // 0

Вместо функции localtime() можно использовать функцию _localtime64(). Число перед открывающей круглой скобкой означает количество бит. Прототип функции:

#include <ctime> /* или #include <time.h> */
struct tm *_localtime64(const __time64_t *Time);

Вместо функции localtime() лучше использовать функцию localtime_s() (_localtime64_s() вместо _localtime64()). Прототипы функций:

#include <ctime> /* или #include <time.h> */
errno_t localtime_s(struct tm *Tm, const time_t *Time);
errno_t _localtime64_s(struct tm *Tm, const __time64_t *Time);

Если ошибок нет, то функции возвращают значение 0. При наличии ошибки возвращается значение макроса EINVAL (значение равно 22) и переменная errno устанавливается равной EINVAL. Пример использования функции localtime_s():

tm Tm;
time_t t = std::time(nullptr);
errno_t err = localtime_s(&Tm, &t);
if (err) {
   std::cout << "Error" << std::endl;
   exit(1);
}
std::cout << Tm.tm_mday << std::endl;  // 5
std::cout << Tm.tm_mon << std::endl;   // 3 (апрель)
std::cout << Tm.tm_year << std::endl;  // 119 (2019 г.)
std::cout << Tm.tm_hour << std::endl;  // 0
std::cout << Tm.tm_min << std::endl;   // 53
std::cout << Tm.tm_sec << std::endl;   // 47
std::cout << Tm.tm_wday << std::endl;  // 5 (пятница)
std::cout << Tm.tm_yday << std::endl;  // 94
std::cout << Tm.tm_isdst << std::endl; // 0
  • mktime() — возвращает количество секунд, прошедших с начала эпохи. В качестве параметра передается указатель на структуру tm с локальной датой и временем. В случае ошибки возвращается значение –1. Прототип функции:
#include <ctime> /* или #include <time.h> */
time_t mktime(struct tm *Tm);

Пример использования функции:

tm Tm;
time_t t1 = std::time(nullptr), t2 = 0;
errno_t err = localtime_s(&Tm, &t1);
if (err) {
   std::cout << "Error" << std::endl;
   exit(1);
}
t2 = std::mktime(&Tm);
std::cout << t1 << std::endl;  // 1554415328
std::cout << t2 << std::endl;  // 1554415328

Вместо функции mktime() можно использовать функцию _mktime64(). Число перед открывающей круглой скобкой означает количество бит. Прототип функции:

#include <ctime> /* или #include <time.h> */
__time64_t _mktime64(struct tm *Tm);
  • difftime() — возвращает разность между двумя датами (Time1 – Time2). В случае ошибки возвращается значение 0 и переменная errno устанавливается равной EINVAL. Прототип функции:
#include <ctime> /* или #include <time.h> */
double difftime(time_t Time1, time_t Time2);

Пример:

time_t t1 = std::time(nullptr), t2 = 1554415534LL;
double result = std::difftime(t1, t2);
std::cout << result << std::endl;

Вместо функции difftime() можно использовать функцию _difftime64(). Число перед открывающей круглой скобкой означает количество бит. Прототип функции:

#include <ctime> /* или #include <time.h> */
double _difftime64(__time64_t Time1, __time64_t Time2);

Выведем текущую дату и время таким образом, чтобы день недели и месяц были написаны по-русски (листинг 11.1).

Листинг 11.1. Вывод текущей даты и времени

#include <iostream>
#include <clocale>
#include <ctime>
#include <iomanip>     /* Для setfill() и setw() */

int main() {
   std::setlocale(LC_ALL, "Russian_Russia.1251");
   tm Tm;
   time_t t = std::time(nullptr);
   char d[][25] = {"воскресенье", "понедельник", "вторник",
                   "среда", "четверг", "пятница", "суббота"};
   char m[][25] = {"января", "февраля", "марта", "апреля", "мая",
                   "июня", "июля", "августа", "сентября", "октября",
                   "ноября", "декабря"};
   errno_t err = localtime_s(&Tm, &t); // Получаем текущее время
   if (err) {
      std::cout << "Error" << std::endl;
      return 1;
   }
   std::cout << "Сегодня:" << std::endl
             << d[Tm.tm_wday] << " " << Tm.tm_mday << " "
             << m[Tm.tm_mon] << " " << (Tm.tm_year + 1900);
   std::cout << std::setfill('0') << " " << std::setw(2)
             << Tm.tm_hour << ":" << std::setw(2) << Tm.tm_min
             << ":" << std::setw(2) << Tm.tm_sec << std::endl
             << std::setw(2) << Tm.tm_mday
             << "." << std::setw(2)<< (Tm.tm_mon + 1) << "."
             << (Tm.tm_year + 1900) << std::endl;
   return 0;
}

Результат выполнения:

Сегодня:
пятница 5 апреля 2019 01:19:21
05.04.2019

В этом примере мы использовали манипуляторы setfill() и setw(), объявленные в заголовочном файле iomanip. Манипулятор setfill() предназначен для указания символа-заполнителя, а манипулятор setw() — для указания ширины поля. Если эти манипуляторы не использовать, то время 16:01:05 будет выведено так: 16:1:5.

Учебник C++ (MinGW-W64)
Учебник C++ (MinGW-W64) в формате PDF

Помощь сайту

ЮMoney (Yandex-деньги): 410011140483022

ПАО Сбербанк:
Счет: 40817810855006152256
Реквизиты банка:
Наименование: СЕВЕРО-ЗАПАДНЫЙ БАНК ПАО СБЕРБАНК
Корреспондентский счет: 30101810500000000653
БИК: 044030653
КПП: 784243001
ОКПО: 09171401
ОКОНХ: 96130
Скриншот реквизитов