Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.75/4: Рейтинг темы: голосов - 4, средняя оценка - 4.75
 Аватар для SomniPhobia
602 / 439 / 137
Регистрация: 22.11.2017
Сообщений: 1,408

Класс по работе с датой

22.08.2023, 12:30. Показов 907. Ответов 16
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Всем привет!
Разрабатываю класс по работе с датой
Нашёл алгоритмы перевода даты как дня, месяца и года в количество дней
И обратный алгоритм - из количества дней в день, месяц и год
Сделал туда (из 22.08.2023) в количество дней. Получил 739 059
Сделал обратно (из 739 059) в дату. Получил 15.05.2017. А должна была та же дата получиться
Как исправить это?
Алгоритмы нужны для последующей реализации смещений дат на указанные периоды

date.cpp
Кликните здесь для просмотра всего текста

C++
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
uint InSomnia::Date::get_count_days_null_year() const
{
    const int32_t M = (m_month + 9) % 12; //5
    std::cout << "M = " << M << "\n";
    const int32_t Y = m_year - M / 10; //2023
    std::cout << "Y = " << Y << "\n";
    //738 395 + 505 - 20 + 5 + 153 + 21 = 739 059
    const int32_t count_days_null_year = 365 * Y + Y / 4 - Y / 100 + Y / 400 + (M * 306 + 5) / 10 + (m_day - 1);
    
    std::cout << "365 * Y = " << 365 * Y << "\n";
    std::cout << "Y / 4 = " << Y / 4 << "\n";
    std::cout << "Y / 100 = " << Y / 100 << "\n";
    std::cout << "Y / 400 = " << Y / 400 << "\n";
    std::cout << "(M * 306 + 5) / 10 = " << (M * 306 + 5) / 10 << "\n";
    std::cout << "(m_day - 1) = " << (m_day - 1) << "\n";
    std::cout << "count_days_null_year = " << count_days_null_year << "\n";
 
    return count_days_null_year;
}
 
void InSomnia::Date::set_date_from_count_days_null_year(const uint count)
{
    int64_t Y = (10000 * count + 14780) / 3652425;
    std::cout << "Y: " << Y << "\n";
    int64_t D = count - (365 * Y + Y / 4 - Y / 100 + Y / 400);
    if (D < 0)
    {
        --Y;
        D = count - (365 * Y + Y / 4 - Y / 100 + Y / 400);
    }
    const int64_t mi = (100 * D + 52) / 3060;
    m_month = (mi + 2) % 12 + 1;
    m_year = Y + (mi + 2) / 12;
    m_day = D - (mi * 306 + 5) / 10 + 1;
}
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
22.08.2023, 12:30
Ответы с готовыми решениями:

Пишу свой класс по работе с датой и временем
Вот код &lt;?php class TimePassed extends DateTime{ //класс объявляем и наследуем public function...

Ексепшен при работе з датой!
Здраствуйте! Я заношу в базу данных дату ы даёт такой ексепшен: The conversion of a varchar data type to a datetime data type...

Ошибка при работе с датой sql/delphi
Разрабатываю приложение к базе данных на delphi и вот такая ошибка, не пойму в чем дело Ошибка на скриншоте procedure...

16
фрилансер
 Аватар для Алексей1153
6450 / 5651 / 1129
Регистрация: 11.10.2019
Сообщений: 15,047
22.08.2023, 12:40
SomniPhobia, приложи компилируемый пример, чтобы была возможность в отладчике протестировать.

Цитата Сообщение от SomniPhobia Посмотреть сообщение
Разрабатываю класс по работе с датой
а какая цель? Задача непростая. Чем std::chrono не устроил?
1
 Аватар для SomniPhobia
602 / 439 / 137
Регистрация: 22.11.2017
Сообщений: 1,408
22.08.2023, 12:45  [ТС]
Алексей1153,
Цитата Сообщение от Алексей1153 Посмотреть сообщение
а какая цель?
Просто хочу иметь у себя такой класс
Цитата Сообщение от Алексей1153 Посмотреть сообщение
Чем std::chrono не устроил?
Не нравится std::chrono
А нравится из Qt: QDate, QTime, QDateTime - очень удобные классы
0
фрилансер
 Аватар для Алексей1153
6450 / 5651 / 1129
Регистрация: 11.10.2019
Сообщений: 15,047
22.08.2023, 12:48
SomniPhobia, ну так возьми исходники QDate, QTime, QDateTime

Если там будет много зависимостей, то оставь только их интерфейс, в внутри сделай на хроно
1
 Аватар для SmallEvil
4086 / 2975 / 813
Регистрация: 29.06.2020
Сообщений: 11,000
22.08.2023, 17:53
Лучший ответ Сообщение было отмечено SomniPhobia как решение

Решение

Цитата Сообщение от SomniPhobia Посмотреть сообщение
Сделал обратно (из 739 059) в дату.
Как создать Классы Date ?
Date& Date::assign(int day)
Получить дни из даты :
int Date::calc_days(const Date & date)
Самоклёп.

Добавлено через 7 минут
По сегодняшней дате, где то косяк.
Слишком сыроват.

Добавлено через 4 минуты
Исправил.
В Date::assign(int day) цикле вычета готовых месяцев использовал не тот массив.
C++
1
        if (dd < Month[leap][i])
Добавлено через 5 минут
Цитата Сообщение от Алексей1153 Посмотреть сообщение
а какая цель? Задача непростая.
А вот тут я согласен.
Время от времени, отсчет дней менялся. Даже начиная с Н.Э.
Что бы понять как считать всё это чудо, нужно прогрызть гранитную пластину с этим вот всем ...

Добавлено через 4 часа 33 минуты
SomniPhobia,
Еще не большая ремарка.
Мой класс даты, это по Григорианскому календарю.
И почему день недели совпадает, для меня пока вопрос.
Видимо в конце 15 века, астрономы решили что можно положить на это(погрешность) болт (болт на это).
Что бы дальше считать дни как можно точнее.
1
 Аватар для SomniPhobia
602 / 439 / 137
Регистрация: 22.11.2017
Сообщений: 1,408
23.08.2023, 12:56  [ТС]
Цитата Сообщение от SmallEvil Посмотреть сообщение
if (dd < Month[leap][i])
То есть, как я понимаю, правильный вариант без "D"
Month вместо MonthD
0
 Аватар для SmallEvil
4086 / 2975 / 813
Регистрация: 29.06.2020
Сообщений: 11,000
23.08.2023, 17:57
Цитата Сообщение от SomniPhobia Посмотреть сообщение
То есть, как я понимаю, правильный вариант без "D"
Yep
Мог бы применить бинарный поиск но 12 элементах это как давить блоху салфеткой ?
Хотя для меня это странный вопрос, почему мой класс дает правильный день вам не интересно. или вы знаете ответ на этот вопрос ? ))
0
 Аватар для SomniPhobia
602 / 439 / 137
Регистрация: 22.11.2017
Сообщений: 1,408
24.08.2023, 10:06  [ТС]
SmallEvil, интересно
int nl_y = date.year - 1 - l_y;
что здесь "- 1" означает?

Добавлено через 3 минуты
В методе
int Date::calc_days(const Date & date)
В методе
int Date::leap_years(int year)
Что означает "- 1" в строке
int years = year - 1;
0
 Аватар для SmallEvil
4086 / 2975 / 813
Регистрация: 29.06.2020
Сообщений: 11,000
24.08.2023, 10:22
Цитата Сообщение от SomniPhobia Посмотреть сообщение
int nl_y = date.year - 1 - l_y;
что здесь "- 1" означает?
Счет лет начинается с 1.
Это нужно учитывать при арифметических операциях.
Начнем с подсчета количества високосных годов.
C++
1
2
3
4
5
6
7
int Date::leap_years(int year)
{
    if (year<1)
        throw std::invalid_argument("leap_years");
    int years = year - 1; 
    return (years / 4 - years / 100 + years / 400);
}
Поле year номер года.
Что бы получить количество прошедших годов, придется отнять текущий.
int years - уже не номер года, а их количество (полных прошедших лет начиная с 1.1.1).
C++
1
2
3
4
5
6
int Date::calc_days(const Date & date)
{
    int l_y = leap_years(date.year); // получаем количество високосных годов
    int nl_y = date.year - 1 - l_y; // получаем количество невисокосных годов
    return date.day + days_by_monthes(date.month, date.year) + l_y*366 + nl_y*365;
}
C++
1
 date.year - 1 - l_y; // получаем количество невисокосных годов
Опять же превращаем НОМЕР года в количество.
Как то так, кажется )

Добавлено через 4 минуты
Цитата Сообщение от SmallEvil Посмотреть сообщение
int Date::calc_days(const Date & date)
Кстати, название этой функции не соответствует её результату.
По хорошему нужно отнять еще 1 день, что бы получить именно количество прошедших дней.
Но у меня это означает какой день по счету.
То есть, название могло бы быть Date::calc_days().
Хотя хрен редьки не слаще.

В тестовом примере я эту единицу отнимаю уже вне класса.

C++
12
int day = (SE::Date::calc_days(data) - 1) % 7;
1
 Аватар для SomniPhobia
602 / 439 / 137
Регистрация: 22.11.2017
Сообщений: 1,408
24.08.2023, 10:31  [ТС]
Для сверки создал метод расчёта количества дней во всех предшествующих годах в лоб
Кликните здесь для просмотра всего текста

C++
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
void InSomnia::Date::calc_days(const int32_t year)
{
    int32_t count_l  = 0;
    int32_t count_nl = 0;
 
    const int32_t start = 0;
    for (int32_t y = start; y < year; ++y)
    {
        if (is_leap_year(y))
        {
            ++count_l;
        }
        else
        {
            ++count_nl;
        }
    }
 
    const int32_t count = count_l + count_nl;
    const int32_t count_days = count_l * 366 + count_nl * 365;
 
    std::cout << "count_l: " << count_l << "\n";
    std::cout << "count_nl: " << count_nl << "\n";
    std::cout << "count: " << count << "\n";
    std::cout << "count_days: " << count_days << "\n";
}


Результат
Название: Снимок экрана 2023-08-24 123021.png
Просмотров: 87

Размер: 4.4 Кб
0
 Аватар для SmallEvil
4086 / 2975 / 813
Регистрация: 29.06.2020
Сообщений: 11,000
24.08.2023, 11:27
SomniPhobia, у тебя на год больше.
Ведь 2023 года пройдет только к 2024
А у меня по прежнему баги в assign-ах ...

Добавлено через 51 секунду
Цитата Сообщение от SomniPhobia Посмотреть сообщение
const int32_t start = 0;
И почему ноль ???
Нет такого года.

Добавлено через 49 минут
У меня еще и в месяцах косяк :
const int NLMonth[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; // 365
const int LMonth[12] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; // 366
Позор мне.
Наверное всё же придётся дописать этот класс до работоспособности.
0
 Аватар для SomniPhobia
602 / 439 / 137
Регистрация: 22.11.2017
Сообщений: 1,408
24.08.2023, 11:34  [ТС]
Цитата Сообщение от SmallEvil Посмотреть сообщение
У меня еще и в месяцах косяк :
Что не так здесь?

Добавлено через 47 секунд
В июле и августе по 31 дню. Эти месяцы стоят рядом. Поэтому 31 и 31
0
 Аватар для SmallEvil
4086 / 2975 / 813
Регистрация: 29.06.2020
Сообщений: 11,000
24.08.2023, 11:46
Цитата Сообщение от SomniPhobia Посмотреть сообщение
У меня еще и в месяцах косяк :
Что не так здесь?
Это я привел уже правильный вариант. А в коде у меня ошибочный.
0
Эксперт функциональных языков программированияЭксперт С++
 Аватар для Royal_X
6162 / 2853 / 1042
Регистрация: 01.06.2021
Сообщений: 10,418
24.08.2023, 12:02
Цитата Сообщение от SomniPhobia Посмотреть сообщение
Алгоритмы нужны для последующей реализации смещений дат на указанные периоды
предлагаю такой код, основанный на переводе даты григорианского календаря в номер юлианского дня (JDN) и обратно:

C++
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
#include <iostream>
 
int toJDN(int day, int month, int year)
{
    int a = (14 - month) / 12;
    int y = year + 4800 - a;
    int m = month + 12 * a - 3;
    return day + (153 * m + 2) / 5 + 365 * y + y / 4 - y / 100 + y / 400 - 32045;
}
 
int* fromJDN(int jdn)
{
    int a = jdn + 32044;
    int b = (4 * a + 3) / 146097;
    int c = a - (146097 * b) / 4;
    int d = (4 * c + 3) / 1461;
    int e = c - (1461 * d) / 4;
    int m = (5 * e + 2) / 153;
    int* date = new int[3];
    date[0] = e - (153 * m + 2) / 5 + 1;
    date[1] = m + 3 - 12 * (m / 10);
    date[2] = 100 * b + d - 4800 + m / 10;
    return date;
}
 
int main()
{
    int jdn = toJDN(24, 8, 2023);
    int* date = fromJDN(jdn + 10); // добавляем 10 дней
    std::cout << date[0] << '.' << date[1] << '.' << date[2] << std::endl;
    delete[] date;
}
В данном примере мы добавляем 10 дней к сегодняшней дате.

Такой код работает для дат после 23 ноября −4713 года (4714 года до н. э.).

SomniPhobia, JDN измеряется днями, поэтому вы можете к нему добавить или отнять нужное количество дней, а потом перевести его в обычную дату. Также вы можете вычислить разность JDN двух разных дат и узнать количество дней между ними.
1
 Аватар для SmallEvil
4086 / 2975 / 813
Регистрация: 29.06.2020
Сообщений: 11,000
24.08.2023, 12:11
Цитата Сообщение от Royal_X Посмотреть сообщение
предлагаю такой код, основанный на переводе даты григорианского календаря в номер юлианского дня (JDN) и обратно:
Ух, сколько много маг. циферок.

Цитата Сообщение от SmallEvil Посмотреть сообщение
Наверное всё же придётся дописать этот класс до работоспособности.
Поправил, сегодня туго всё дается...
Как создать Классы Date ?
0
 Аватар для SomniPhobia
602 / 439 / 137
Регистрация: 22.11.2017
Сообщений: 1,408
25.08.2023, 04:43  [ТС]
SmallEvil, как сделать чтобы у меня был на протяжении всей работы программы один объект Date со значениями 1 день, 1 меся, 1970 год? Это синглтон нужно делать или как-то по-другому можно?
И как потом хранить на протяжении всей работы программы количество дней от 1 года до 01.01.1970? Как посоветуете сделать?
0
фрилансер
 Аватар для Алексей1153
6450 / 5651 / 1129
Регистрация: 11.10.2019
Сообщений: 15,047
25.08.2023, 09:54
SomniPhobia, глобальная переменная типа constexpr Date, инициализированная нужными значениями. Для этого нужен будет constexpr конструктор

Добавлено через 1 минуту
хотя, можно и просто const. Но я бы сделал constexpr, ничего этому не мешает
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
25.08.2023, 09:54
Помогаю со студенческими работами здесь

Есть ли какая нибудь стандартная функция по работе с датой
Есть ли какая нибудь стандартная функция по работе с датой с Си? У меня задача, при решении я из файла дергаю строку вида имя, срок...

Создать класс для работы с датой
Доброго времени суток всем! В программировании я не силён,поэтому у меня возникла данная проблема В университете задали задание : ...

Построить класс для работы с датой
Добрый день товарищи, очень нужна помощь, буду благодарен каждому ответу. Задание: Постpоить класс для работы с датой. Класс должен...

Создать класс для работы с датой
Здравствуйте, помогите пожалуйста кому не сложно. Тип данный DateTime, данный класс должен содержать следующие члены класса: 1) Поле: ...

Создать класс для работы с датой.
Создать класс для работы с датой. Разработать следующие элементы класса: a. Поле DataTime data. b. Конструкторы, позволяющие...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
17
Ответ Создать тему
Новые блоги и статьи
http://iceja.net/ математические сервисы
iceja 20.01.2026
Обновила свой сайт http:/ / iceja. net/ , приделала Fast Fourier Transform экстраполяцию сигналов. Однако предсказывает далеко не каждый сигнал (см ограничения http:/ / iceja. net/ fourier/ docs ). Также. . .
http://iceja.net/ сервер решения полиномов
iceja 18.01.2026
Выкатила http:/ / iceja. net/ сервер решения полиномов (находит действительные корни полиномов методом Штурма). На сайте документация по API, но скажу прямо VPS слабенький и 200 000 полиномов. . .
Расчёт переходных процессов в цепи постоянного тока
igorrr37 16.01.2026
/ * Дана цепь постоянного тока с R, L, C, k(ключ), U, E, J. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа, решает её и находит переходные токи и напряжения на элементах схемы. . . .
Восстановить юзерскрипты Greasemonkey из бэкапа браузера
damix 15.01.2026
Если восстановить из бэкапа профиль Firefox после переустановки винды, то список юзерскриптов в Greasemonkey будет пустым. Но восстановить их можно так. Для этого понадобится консольная утилита. . .
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru