БлогNot. C++: формула Сакамото и дата через system_clock::now

C++: формула Сакамото и дата через system_clock::now

Я не раз вычислял на различных языках день недели по дате ДД.ММ.ГГГГ с помощью формулы Целлера (Зеллера), а для определения самой сегодняшней даты ограничивался на C/C++ возможностями библиотеки ctime.

Сегодня, возможно, лучше применять совсем простой алгоритм Сакамото для определения дня недели, а текущую дату можно брать и из system_clock::now (библиотека chrono).

Вот реализация определения дня недели по Сакамото, проверенная в консоли Visual Studui 2019 для текущей даты, полученной как классическим способом, так и через chrono. Правда, Studio всё равно ругается на localtime как "небезопасную функцию", поэтому в исходнике есть специфичный для Studio код (windows.h, _CRT_SECURE_NO_WARNINGS).

В последних версиях QT тоже должно работать с точностью до кодировки консоли.

#define _CRT_SECURE_NO_WARNINGS /* localtime, sprintf */
#include <iostream>
#include <cstdio>
#include <string>
#include <sstream> /* stringstream */
#include <clocale> /* setlocale */
#include <ctime> /* time */
#include <chrono> /* system_clock::now */
#include <iomanip> /* put_time */
#include <windows.h> /* SetConsoleCP, SetConsoleOutputCP */

using namespace std;

int day_of_the_week (int d, int m, int y) { 
 //День недели по формуле Сакамото. Вернёт 0=Вс, ..., 6=Сб
 int t[] = { 0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4 };
 if (m < 3) y--;
 return ((y + y / 4 - y / 100 + y / 400 + t[m - 1] + d) % 7);
}

/*-----------------------------------------------*/
struct dmy { int y, m, d; }; //структура "год-месяц-день"

dmy today() { //Сегодняшняя дата dmy через time/localtime
 dmy now;
 time_t t = time (0);
 tm *tm_now = localtime (&t);
 now.y = tm_now->tm_year + 1900;
 now.m = tm_now->tm_mon + 1;
 now.d = tm_now->tm_mday;
 return now;
}

dmy today_chrono() { //Сегодняшняя дата dmy через chrono (нужна поддержка C++ 11)
 using namespace std::chrono;
 system_clock::time_point today = system_clock::now();
 time_t mytime = system_clock::to_time_t(today);
 dmy now;
 stringstream ss;
 ss << put_time (localtime(&mytime), "%Y") << " ";
 ss << put_time (localtime(&mytime), "%m") << " ";
 ss << put_time (localtime(&mytime), "%d");
 ss >> now.y; 
 ss >> now.m; 
 ss >> now.d;
 return now;
}
/*-----------------------------------------------*/


int main() {
 setlocale(LC_ALL, "Rus");
 SetConsoleCP(1251); SetConsoleOutputCP(1251);

 char buf[12];
 char wd[][7] = { "вс", "пн", "вт", "ср", "чт", "пт", "сб" };

 //Проверка способа 1
 dmy d = today();
 sprintf(buf, "%02d.%02d.%04d", d.d, d.m, d.y); //форматирование даты ДД.ММ.ГГГГ
 cout << "Сегодня " << buf << ", " << wd[day_of_the_week(d.d,d.m,d.y)] << endl;

 //Проверка способа 2
 d = today_chrono();
 sprintf(buf, "%02d.%02d.%04d", d.d, d.m, d.y); //форматирование даты ДД.ММ.ГГГГ
 cout << "Сегодня " << buf << ", " << wd[day_of_the_week(d.d, d.m, d.y)];

 cin.get(); return 0;
}

теги: программирование c++ studio дата

25.06.2020, 23:58; рейтинг: 26