Segnetics

Вернуться   Segnetics > Форум Segnetics > Вопросы о программировании

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
Старый 14.08.2019, 14:09   #1
SergVK
Новичок
 
Регистрация: Oct 2018
Сообщения: 4
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
По умолчанию Почему GetDays "спешит" на 15 дней?

Добрый день коллеги.

Столкнулся с необходимостью хранить дату и вычислять разницу с текущей, логично преобразовать ее в количество дней и хранить как одно число long.
И вот тут возникла загвоздка.

По описанию функции GetDays выдает количество дней прошедших с 01.01.0001.

Есть общепринятый алгоритм расчета дня по Юлианскому и Григорианскому календарю, например такой
wiki

Если считать по нему 01.01.0001 это 1721426 й день
Например сегодня 14.08.2019 это 2458710 й день
Разница 737284 дней.
GetDays выдает 737300. Ошибка 15 дней?

Понятно, что можно эту ошибку учесть и не париться, но хотелось бы понять, откуда она берется, где и когда ждать подвоха.
SergVK вне форума   Ответить с цитированием
Старый 14.08.2019, 14:12   #2
Arsie
Сотрудник Segnetics
 
Аватара для Arsie
 
Регистрация: Jan 2006
Адрес: Russia, SPb
Сообщения: 11 010
Благодарил(а): 3 раз(а)
Поблагодарили: 46 раз(а) в 45 сообщениях
По умолчанию Ответ: Почему GetDays "спешит" на 15 дней?

Цитата
Сообщение от SergVK Посмотреть сообщение
Добрый день коллеги.

Столкнулся с необходимостью хранить дату и вычислять разницу с текущей, логично преобразовать ее в количество дней и хранить как одно число long.
И вот тут возникла загвоздка.

По описанию функции GetDays выдает количество дней прошедших с 01.01.0001.

Есть общепринятый алгоритм расчета дня по Юлианскому и Григорианскому календарю, например такой
wiki

Если считать по нему 01.01.0001 это 1721426 й день
Например сегодня 14.08.2019 это 2458710 й день
Разница 737284 дней.
GetDays выдает 737300. Ошибка 15 дней?

Понятно, что можно эту ошибку учесть и не париться, но хотелось бы понять, откуда она берется, где и когда ждать подвоха.
Блок передаёт то, что ему отвечает стандартная функция из библиотеки C++.

Думаю, если бы в этой функции была ошибка, то за несколько десятков лет это хоть кто-то, но заметил.

Другими словами, я не проверяя ваши расчёты считаю, что скорее всего вы в чём-то ошиблись или что-то не учли. Високосные года, например.


__________________
Добро всегда побеждает зло. Кто победил - тот и добрый.
Arsie вне форума   Ответить с цитированием
Старый 14.08.2019, 14:19   #3
SergVK
Новичок
 
Регистрация: Oct 2018
Сообщения: 4
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
По умолчанию Ответ: Почему GetDays "спешит" на 15 дней?

Цитата:
Сообщение от Arsie Посмотреть сообщение
Блок передаёт то, что ему отвечает стандартная функция из библиотеки C++.
Внутрь блока не заглянешь. Какая функция конкретно можно озвучить? Полазить по описаниям.
SergVK вне форума   Ответить с цитированием
Старый 14.08.2019, 14:27   #4
SergVK
Новичок
 
Регистрация: Oct 2018
Сообщения: 4
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
По умолчанию Ответ: Почему GetDays "спешит" на 15 дней?

не один я ошибаюсь видать....
Миниатюры
Нажмите на картинку для увеличения

Название:  SMLogix - [calendar.psl].jpg
Просмотров: 33
Размер:  20.5 Кбайт   Нажмите на картинку для увеличения

Название:  joxi_screenshot_1565778259487.png
Просмотров: 33
Размер:  15.6 Кбайт  
SergVK вне форума   Ответить с цитированием
Старый 14.08.2019, 14:56   #5
Arsie
Сотрудник Segnetics
 
Аватара для Arsie
 
Регистрация: Jan 2006
Адрес: Russia, SPb
Сообщения: 11 010
Благодарил(а): 3 раз(а)
Поблагодарили: 46 раз(а) в 45 сообщениях
По умолчанию Ответ: Почему GetDays "спешит" на 15 дней?

Цитата
Сообщение от SergVK Посмотреть сообщение
Внутрь блока не заглянешь. Какая функция конкретно можно озвучить? Полазить по описаниям.
GetDays()




DWORD * ClassLogix::getDays(DWORD * cp, WORD )
struct tm * tinfo = GetLocalTime();
*(pDWORD)(*(cp++)) = DateToDays(tinfo->tm_mday, tinfo->tm_mon + 1, tinfo->tm_year + 1900);
)

static int day_tab[12] = {0,31,59,90,120,151,181,212,243,273,304,334};
static unsigned long DateToDays(signed int _day, signed int _month, signed int _year)
{
unsigned long days;
unsigned int quot;
unsigned int rem;

if(_year <= 0) _year = 2000;
if(_month <= 0) _month = 1;
if(_month > 12) _month = 12;
if(_day <= 0) _day = 1;

quot = (_year - 1) / 4;
rem = (_year - 1) - quot * 4;
days = ((unsigned long)quot * (4 * 365 + 1)) + ((unsigned long)rem * 365);

quot = 0;
if ((rem == 3) && (_month >= 2))
{
if(_month == 2)
quot = 1;
else days++;
}

rem = day_tab[_month - 1] + _day;
if(_month == 12)
quot += 365;
else quot += day_tab[_month];

if(rem > quot)
days += quot;
else days += rem;

days %= 766661L;
if(days < 730135L) days = 730135L;
return days;
}


__________________
Добро всегда побеждает зло. Кто победил - тот и добрый.

Последний раз редактировалось Arsie, 14.08.2019 в 17:29
Arsie вне форума   Ответить с цитированием
Старый 14.08.2019, 23:28   #6
SergVK
Новичок
 
Регистрация: Oct 2018
Сообщения: 4
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
По умолчанию Ответ: Почему GetDays "спешит" на 15 дней?

Цитата:
Сообщение от Arsie Посмотреть сообщение
GetDays()
quot = (_year - 1) / 4;
rem = (_year - 1) - quot * 4;
days = ((unsigned long)quot * (4 * 365 + 1)) + ((unsigned long)rem * 365);
Судя по этому куску, функция считает каждый четвертый год високосным. Однако каждый сотый не вискосный, но каждый 400 высокосный. вот и разница в 15 дней за 2000 набегает.

PS: По юлианскому календарю.... похоже в этом и трабл
SergVK вне форума   Ответить с цитированием
Ответ

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать свои сообщения

BB code is Вкл.
[IMG] код Вкл.
HTML код Выкл.


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Почему техподдержка не может ответить на мой простейший вопрос? Arsie ЧаВо - Часто задаваемые Вопросы 6 23.11.2018 11:26


Часовой пояс GMT +4, время: 07:34.


Версия vBulletin: 3.8.3
Copyright ©2000 - 2019, Jelsoft Enterprises Ltd.
Segnetics 2005 - 2019