Функции работы с датой и временем, временная задержка

Функции работы с датой и временем

Для работы с системной датой и временем используется библиотека time.h.

Типы, определенные в библиотеке time.h

Тип Описание
size_t Целочисленный тип, возвращаемый операцией sizeof.
clock_t Арифметический тип, подходящий для представления времени.
time_t Арифметический тип, подходящий для представления времени.
struct tm Структурный тип, содержащий компоненты календарного времени.

Для определения текущего календарного времени используется функция

 
time_t time(NULL);

Данная функция возвращает время в секундах начиная с 1 января 1970 г.

Например,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <time.h>
char * settime(struct tm *u)
{
  char s[40];
  char *tmp;
  for (int i = 0; i<40; i++) s[i] = 0;
  int length = strftime(s, 40, "%d.%m.%Y %H:%M:%S, %A", u);
  tmp = (char*)malloc(sizeof(s));
  strcpy(tmp, s);
  return(tmp);
}
int main() 
{
  struct tm *u;
  char *f;
  system("chcp 1251");
  system("cls");
  const time_t timer = time(NULL);
  u = localtime(&timer);
  f = settime(u);
  printf("%ld соответствует ", timer);
  puts(f);
  getchar();
  return 0;
}

Дата и время

Структура tm имеет вид

 
 
 
 
 
 
 
 
 
 
 
 
struct tm
{
  int tm_sec;     // секунды после минут [0,59]
  int tm_min;     // минуты после часов [0,59]
  int tm_hour;    // часы после полуночи [0,23]
  int tm_mday;    // день месяца [1,31]
  int tm_mon;     // месяц года (январь = 0) [0,11]
  int tm_year;    // год (1900 год = 0)
  int tm_wday;    // день недели (вс = 0) [0,6]
  int tm_yday;    // день года (1 января = 0) [0,365]
  int tm_isdst;   // флаг перехода на летнее время (>0- вкл.)
};

Функция

 
struct tm *localtime(const time_t *ptm);

преобразует календарное время, указанное ptm, сохраняет его в структуре tm и возвращает указатель на нее.

Функция

 
time_t mktime(struct tm *timeptr);

осуществляет обратное преобразование.

Функция

 
clock_t clock (void);

возвращает наилучшее приближение процессорного времени, прошедшего с момента запуска программы; для получения времени в секундах значение необходимо разделить на константу, определенную в библиотеке time.h:

 
#define CLOCKS_PER_SEC 1000

Если время не доступно или не может быть представлено, возвращает (clock_t) (-1).

Функция

 
 
 
 
 
size_t strftime(
char *restrict s, // указатель на выходную строку
size_t max,    // максимальный размер выходной строки
const char *restrict fmt, // указатель на строку формата
const struct tm *restrict tmpt); // указатель на структуру tm

копирует строку fmt в строку s, заменяя спецификаторы формата в fmt соответствующими данными, взятыми из содержимого структуры времени, на которое указывает tmpt; в строку s помещается не более max символов.

Функция возвращает количество символов (исключая нулевой) в результирующей строке. Если результирующая строка (включая нулевой символ) содержит больше, чем max символов, функция возвращает 0, а содержимое s не определено.

Спец. назначение
%a Локальное сокращенное название дня недели
%A Локальное полное название дня недели
%b Локальное сокращенное название месяца
%B Локальное полное название месяца
%c Локальный разделитель даты и времени
%d День месяца в виде десятичного числа (01-31)
%D Эквивалент %m%d%y
%e День месяца (десятичное число): однозначные числа дополнены пробелом
%F Эквивалент %Y-%m-%d
%g Последние два разряда года (00-99)
%G Год в виде десятичного числа
%H Часы (по 24-часовой шкале) в виде десятичного числа (00-23)
%I Часы (по 12-часовой шкале) в виде десятичного числа (01-12)
%j День года в виде десятичного числа (001-366)
%m Месяц в виде десятичного числа (01-12)
%n Символ новой строки
%M Минуты в виде десятичного числа (00-59)
%p Локальный эквивалент a.m./p.m. для 12-часовой временной шкалы
%r Локальное 12-часовое время
%R Эквивалент %H:%M
%S Секунды в виде десятичного числа (00-61)
%t Символ горизонтальной табуляции
%T Эквивалент %H:%M:%S
%u Номер дня недели (1-7), где 1 соответствует понедельнику
%U Номер недели в году, считая воскресенье первым днем недели (00-53)
%w Номер дня недели в виде десятичного числа, начиная с воскресенья (0-6)
%W Номер недели в году, считая понедельник первым днем недели (00-53)
%y Год без века в виде десятичного числа (00-99)
%Y Год с веком в виде десятичного числа
%z Смещение от UTC ("-800" означает на 8 ч по Гринвичу западнее).
%Z Наименование часового пояса (если доступно)
%% % (то есть знак процента).

Функция, позволяющая вывести день недели на русском языке

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <time.h>
char * settime(struct tm *u)
{
  char s[40];
  char *tmp;
  for (int i = 0; i<40; i++) s[i] = 0;
  int length = strftime(s, 40, "%d.%m.%Y %H:%M:%S ", u);
  switch (u->tm_wday)
  {
    case 0: strcpy(s + length, " воскресенье"); break;
    case 1: strcpy(s + length, " понедельник"); break;
    case 2: strcpy(s + length, " вторник");     break;
    case 3: strcpy(s + length, " среда");       break;
    case 4: strcpy(s + length, " четверг");     break;
    case 5: strcpy(s + length, " пятница");     break;
    case 6: strcpy(s + length, " суббота");     break;
  }
  tmp = (char*)malloc(sizeof(s));
  strcpy(tmp, s);
  return(tmp);
}
int main() 
{
  struct tm *u;
  char *f;
  system("chcp 1251");
  system("cls");
  const time_t timer = time(NULL);
  u = localtime(&timer);
  f = settime(u);
  printf("%ld соответствует ", timer);
  puts(f);
  getchar();
  return 0;
}

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

Добавление нескольких дней к текущему времени

Рассмотрим еще один пример. Допустим, требуется добавить несколько дней к текущей дате.

Реализация на Си

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <time.h>
#define ADD_DAYS 300
int main()
{
  struct tm *u;
  char s1[40] = { 0 }, s2[40] = { 0 };
  const time_t timer = time(NULL);
  u = localtime(&timer);
  strftime(s1, 80, "%d.%m.%Y %H:%M:%S ", u);
  printf("%s\n", s1);
  u->tm_mday += ADD_DAYS;
  time_t next = mktime(u);
  u = localtime(&next);
  strftime(s2, 80, "%d.%m.%Y %H:%M:%S ", u);
  printf("%s\n", s2);
  getchar();
  return 0;
}

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

Добавление нескольких дней к текущей дате

Реализация функции задержки

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>
#include <time.h>
void delay(int ms) // аргумент - требуемое время задержки в миллисекундах
{
  int c = clock() + ms;
  while (clock() < c);
}
int main() 
{
  printf("clock = %d\n", clock());
  delay(1000);
  printf("clock = %d\n", clock());
  getchar();
  return 0;
}

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

Функция задержки

9 комментариев к “Функции работы с датой и временем”

  1. Спасибо за ответ. Но я нашел в Интернете формулу расчета разности дат (спасибо опубликовавшему эту формулу). К сожалению, это формула, а не функция C++. Меня удивляет, что нет функции, т.к. по-моему, она должна быть довольно востребована (определение периода, возраста, средних величин за период и т.п.)…

  2. Здравствуйте, ищу способ определения разницы в днях между двумя датами на C++ в Win32 GUI. Есть два поля DateTimePicker, вот и хочу знать разницу между ними. Думаю, что должна быть какая-то функция, но найти нигде не смог. Искал во многих форумах, везде объяснения для консольных программ.
    С помощью определения количества дней в годах и вычислении смог получить нужный результат для любых дат, но это заняло у меня примерно 140 строк. Функция difftime()дает какой-то странный, отличный от моего, результат, постоянный независимо от дат. Пишут, что получаются секунды, но не может быть в разнице в 6 лет около 10000 секунд. Можете помочь функцией, примером или ссылкой?

    1. Елена Вставская

      Не приходилось работать с DateTimePicker в Win32 GUI на C++.
      Знаю только, как сделать в C#.

  3. Не подскажите а как получить доступ к дню недели?

    Мне надо что бы при понедельнике у меня значение принималось 1, при вторнике 2 и тд.

    1. Елена Вставская

      Не поняла вопроса. В примере так и есть: понедельник — 1, вторник — 2.

      1. как можно сделать вывод похожий на этот:
        cout<<(tm->tm_wday);
        Нужен только день недели без секунд часов и т.д.

        1. Елена Вставская

          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          21
          #include <time.h>
          #include <iostream>
          int main()
          {
            const time_t SEC_IN_GOD = 31536000;
            using namespace std;
            const time_t timer = time(NULL);
            time_t t = timer — (SEC_IN_GOD * 47);

            cout << endl;
            cout << ((t / 60) / 60) % 24;
            cout << ":";
            cout << ((t / 60) % 60) / 10;
            cout << ((t / 60) % 60) % 10;
            cout << ":";
            cout << (t % 60) / 10;
            cout << (t % 60) % 10;

            getchar();
            return 0;
          }

          Формат %u выводит номер дня недели, %A — название.

        2. И почему нижеприведенный код не правильно показывает время в часах?
          Влияние високосного дня должен же влиять только на дату, но не на время же

          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          21
          #include <time.h>
          #include <iostream>
          int main()
          {
            const time_t SEC_IN_GOD = 31536000;
            using namespace std;
            const time_t timer = time(NULL);
            time_t t = timer — (SEC_IN_GOD * 47);

            cout << endl;
            cout << ((t / 60) / 60) % 24;
            cout << ":";
            cout << ((t / 60) % 60) / 10;
            cout << ((t / 60) % 60) % 10;
            cout << ":";
            cout << (t % 60) / 10;
            cout << (t % 60) % 10;

            getchar();
            return 0;
          }

          1. Елена Вставская

            Проблем не вижу. Время выводится для часового пояса GMT+0 корректно. Отличается от того, что на компьютере ровно на столько часов, сколько соответствуют часовому поясу.

Оставьте комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Прокрутить вверх