Проблема с COleDateTime.
От: Avdeev  
Дата: 01.04.09 06:24
Оценка:
Доброго времени суток! Моя проблема представлена следующим кодом:

int _tmain(int argc, _TCHAR* argv[])
{
COleDateTime dt(1899,12,29,23,55,0);
COleDateTimeSpan add_dt(0,0,5,0);

dt += add_dt;

std::cout << "Year : "<< dt.GetYear() << " Month : "<< dt.GetMonth() << " Day : " << dt.GetDay() << " Hour : " << dt.GetHour() << " Minute : " << dt.GetMinute() << " Second : " << dt.GetSecond();

_getch();
return 0;
}

Иными словами к дате "29.12.1899 23:55:00" добавляем 5 минут и ожидаем увидеть "30.12.1899 00:00:00" а вместо этого нам возвращается "28.12.1899 00:00:00" — что очень уж странно!!! При этом если прибавлять нечто отличное от 5 минут то сложение происходит верно, также всё верно если вычесть 5 минут из "30.12.1899 00:00:00". Кто-нибудь сталкивался с этой проблемой? Я думаю, что это баг ребят из майкрософта. Если есть решение, подскажите пожалуйста как.(я использую VS2005)

01.04.09 12:43: Перенесено модератором из 'C/C++' — Кодт
Re: Проблема с COleDateTime.
От: Аноним  
Дата: 06.04.09 10:47
Оценка:
Здравствуйте, Avdeev, Вы писали:

A>Доброго времени суток! Моя проблема представлена следующим кодом:


A>int _tmain(int argc, _TCHAR* argv[])

A>{
A> COleDateTime dt(1899,12,29,23,55,0);
A> COleDateTimeSpan add_dt(0,0,5,0);

A> dt += add_dt;


A> std::cout << "Year : "<< dt.GetYear() << " Month : "<< dt.GetMonth() << " Day : " << dt.GetDay() << " Hour : " << dt.GetHour() << " Minute : " << dt.GetMinute() << " Second : " << dt.GetSecond();


A> _getch();

A> return 0;
A>}

A>Иными словами к дате "29.12.1899 23:55:00" добавляем 5 минут и ожидаем увидеть "30.12.1899 00:00:00" а вместо этого нам возвращается "28.12.1899 00:00:00" — что очень уж странно!!! При этом если прибавлять нечто отличное от 5 минут то сложение происходит верно, также всё верно если вычесть 5 минут из "30.12.1899 00:00:00". Кто-нибудь сталкивался с этой проблемой? Я думаю, что это баг ребят из майкрософта. Если есть решение, подскажите пожалуйста как.(я использую VS2005)



А слабо прочитать?
ms-help://MS.VSCC.v80/MS.MSDN.v80/MS.VisualStudio.v80.en/dv_vclib/html/e718f294-16ec-4649-88b6-a4dbae5178fb.htm
Re[2]: Проблема с COleDateTime.
От: Avdeev  
Дата: 08.04.09 10:31
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, Avdeev, Вы писали:


A>>Доброго времени суток! Моя проблема представлена следующим кодом:


A>>int _tmain(int argc, _TCHAR* argv[])

A>>{
A>> COleDateTime dt(1899,12,29,23,55,0);
A>> COleDateTimeSpan add_dt(0,0,5,0);

A>> dt += add_dt;


A>> std::cout << "Year : "<< dt.GetYear() << " Month : "<< dt.GetMonth() << " Day : " << dt.GetDay() << " Hour : " << dt.GetHour() << " Minute : " << dt.GetMinute() << " Second : " << dt.GetSecond();


A>> _getch();

A>> return 0;
A>>}

A>>Иными словами к дате "29.12.1899 23:55:00" добавляем 5 минут и ожидаем увидеть "30.12.1899 00:00:00" а вместо этого нам возвращается "28.12.1899 00:00:00" — что очень уж странно!!! При этом если прибавлять нечто отличное от 5 минут то сложение происходит верно, также всё верно если вычесть 5 минут из "30.12.1899 00:00:00". Кто-нибудь сталкивался с этой проблемой? Я думаю, что это баг ребят из майкрософта. Если есть решение, подскажите пожалуйста как.(я использую VS2005)



А>А слабо прочитать?

А>ms-help://MS.VSCC.v80/MS.MSDN.v80/MS.VisualStudio.v80.en/dv_vclib/html/e718f294-16ec-4649-88b6-a4dbae5178fb.htm

Интересно, где же там ответ на мой вопрос? Может у них конечно между строк написано что арифметика с ошибкой это нормально?
Re[3]: Проблема с COleDateTime.
От: Avdeev  
Дата: 08.04.09 10:34
Оценка:
Кстати, вот тут я изложил поподробней найденную проблему
http://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/aaadece6-eb96-43e7-982a-3c42bd081fba
Re[3]: Проблема с COleDateTime.
От: Аноним  
Дата: 08.04.09 13:33
Оценка:
Здравствуйте, Avdeev, Вы писали:

A>Здравствуйте, Аноним, Вы писали:


А>>Здравствуйте, Avdeev, Вы писали:


A>>>Доброго времени суток! Моя проблема представлена следующим кодом:


A>>>int _tmain(int argc, _TCHAR* argv[])

A>>>{
A>>> COleDateTime dt(1899,12,29,23,55,0);
A>>> COleDateTimeSpan add_dt(0,0,5,0);

A>>> dt += add_dt;


A>>> std::cout << "Year : "<< dt.GetYear() << " Month : "<< dt.GetMonth() << " Day : " << dt.GetDay() << " Hour : " << dt.GetHour() << " Minute : " << dt.GetMinute() << " Second : " << dt.GetSecond();


A>>> _getch();

A>>> return 0;
A>>>}

A>>>Иными словами к дате "29.12.1899 23:55:00" добавляем 5 минут и ожидаем увидеть "30.12.1899 00:00:00" а вместо этого нам возвращается "28.12.1899 00:00:00" — что очень уж странно!!! При этом если прибавлять нечто отличное от 5 минут то сложение происходит верно, также всё верно если вычесть 5 минут из "30.12.1899 00:00:00". Кто-нибудь сталкивался с этой проблемой? Я думаю, что это баг ребят из майкрософта. Если есть решение, подскажите пожалуйста как.(я использую VS2005)



А>>А слабо прочитать?

А>>ms-help://MS.VSCC.v80/MS.MSDN.v80/MS.VisualStudio.v80.en/dv_vclib/html/e718f294-16ec-4649-88b6-a4dbae5178fb.htm

A>Интересно, где же там ответ на мой вопрос? Может у них конечно между строк написано что арифметика с ошибкой это нормально?


Там написано, что интервал по разному считается.
Ну получается ошибка округления.
Достаточно добавить по секунде либо в начальную дату, либо в конечную и все становится ок.
Re[4]: Проблема с COleDateTime.
От: Avdeev  
Дата: 08.04.09 14:39
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, Avdeev, Вы писали:


A>>Здравствуйте, Аноним, Вы писали:


А>>>Здравствуйте, Avdeev, Вы писали:


A>>>>Доброго времени суток! Моя проблема представлена следующим кодом:


A>>>>int _tmain(int argc, _TCHAR* argv[])

A>>>>{
A>>>> COleDateTime dt(1899,12,29,23,55,0);
A>>>> COleDateTimeSpan add_dt(0,0,5,0);

A>>>> dt += add_dt;


A>>>> std::cout << "Year : "<< dt.GetYear() << " Month : "<< dt.GetMonth() << " Day : " << dt.GetDay() << " Hour : " << dt.GetHour() << " Minute : " << dt.GetMinute() << " Second : " << dt.GetSecond();


A>>>> _getch();

A>>>> return 0;
A>>>>}

A>>>>Иными словами к дате "29.12.1899 23:55:00" добавляем 5 минут и ожидаем увидеть "30.12.1899 00:00:00" а вместо этого нам возвращается "28.12.1899 00:00:00" — что очень уж странно!!! При этом если прибавлять нечто отличное от 5 минут то сложение происходит верно, также всё верно если вычесть 5 минут из "30.12.1899 00:00:00". Кто-нибудь сталкивался с этой проблемой? Я думаю, что это баг ребят из майкрософта. Если есть решение, подскажите пожалуйста как.(я использую VS2005)



А>>>А слабо прочитать?

А>>>ms-help://MS.VSCC.v80/MS.MSDN.v80/MS.VisualStudio.v80.en/dv_vclib/html/e718f294-16ec-4649-88b6-a4dbae5178fb.htm

A>>Интересно, где же там ответ на мой вопрос? Может у них конечно между строк написано что арифметика с ошибкой это нормально?


А>Там написано, что интервал по разному считается.

А>Ну получается ошибка округления.
А>Достаточно добавить по секунде либо в начальную дату, либо в конечную и все становится ок.

Здесь дело не в округлении, я дебажил этот код. Там как раз получается что при сложении определенных дат происходит вычитание, а не сложение. Да и как бы там ни было, если написано что они гарантируют работу от 100 года до 9999, то это баг получается из разряда тех что надо фиксить. Не проверять же мне при каждой операции сложения не получается ли там эта магическая дата. Ошибки округления проявляются при операции сравнения, где на самом деле сравниваются double'ы находящиеся внутри и сравнение происходит как раз по ним. Так что я считаю что это ошибка из другого разряда. Баг в микрософт написан, поглядим что ответят. Потом отпишусь.
Проблема с COleDateTime.
От: rus blood Россия  
Дата: 08.04.09 16:05
Оценка: 10 (2)
#Имя: FAQ.mfc.COleDateTime.trouble
Здравствуйте, Avdeev, Вы писали:

A>Иными словами к дате "29.12.1899 23:55:00" добавляем 5 минут и ожидаем увидеть "30.12.1899 00:00:00" а вместо этого нам возвращается "28.12.1899 00:00:00" — что очень уж странно!!! При этом если прибавлять нечто отличное от 5 минут то сложение происходит верно, также всё верно если вычесть 5 минут из "30.12.1899 00:00:00". Кто-нибудь сталкивался с этой проблемой? Я думаю, что это баг ребят из майкрософта.


A>Здесь дело не в округлении, я дебажил этот код.


Это ошибка в округлении, которая вместе с "вывернутой" системой счисления для "отрицательных" дат дает такой эффект.

OLE дата хранит время как double число. Целая часть — кол-во дней с 30.12.1899, дробная — часть дня. Для "отрицательных" дат используется "вывернутая" система — целые части по прежнему нумеруют дни назад в прошлое, а дробная часть определяет часть дня вперед, в будущее.

Например, — 2.5 будет 2 дня назад в прошлое от 30.12.1899, плюс полдня вперед в будущее. Т.е. в итоге получается полдень 28.12, а не 27.12.

Отображение дат DATE на "плоский" double примерно такое.


double = 2 * ceil — DATE
DATE = 2 * floor — double.

С математикой все в порядке, а ошибка в точности вычислений и округлении. При добавлении 5 минут получается "почти" ноль, но из-за неточности вычисления — маленькое отрицательное число. У меня было где-то около -10^(-17). Далее, "плоское" отрицательное double-число около нуля после конвертации соответствует значению для DATE примерно -1.999999... , что с округлением дает -2. Суть в том, что в "вывернутой" системе счисления DATE между -1.9999... и -2 действительно около 2 дней разницы, и код получается чувствительным к ошибкам округления.
Имею скафандр — готов путешествовать!
coledatetime mfc
Re: Проблема с COleDateTime.
От: Avdeev  
Дата: 09.04.09 06:18
Оценка:
Здравствуйте, rus blood, Вы писали:

RB>Здравствуйте, Avdeev, Вы писали:


A>>Иными словами к дате "29.12.1899 23:55:00" добавляем 5 минут и ожидаем увидеть "30.12.1899 00:00:00" а вместо этого нам возвращается "28.12.1899 00:00:00" — что очень уж странно!!! При этом если прибавлять нечто отличное от 5 минут то сложение происходит верно, также всё верно если вычесть 5 минут из "30.12.1899 00:00:00". Кто-нибудь сталкивался с этой проблемой? Я думаю, что это баг ребят из майкрософта.


A>>Здесь дело не в округлении, я дебажил этот код.


RB>Это ошибка в округлении, которая вместе с "вывернутой" системой счисления для "отрицательных" дат дает такой эффект.


RB>OLE дата хранит время как double число. Целая часть — кол-во дней с 30.12.1899, дробная — часть дня. Для "отрицательных" дат используется "вывернутая" система — целые части по прежнему нумеруют дни назад в прошлое, а дробная часть определяет часть дня вперед, в будущее.


RB>Например, — 2.5 будет 2 дня назад в прошлое от 30.12.1899, плюс полдня вперед в будущее. Т.е. в итоге получается полдень 28.12, а не 27.12.


RB>Отображение дат DATE на "плоский" double примерно такое.

RB>

RB>double = 2 * ceil — DATE

RB>DATE = 2 * floor — double.

RB>С математикой все в порядке, а ошибка в точности вычислений и округлении. При добавлении 5 минут получается "почти" ноль, но из-за неточности вычисления — маленькое отрицательное число. У меня было где-то около -10^(-17). Далее, "плоское" отрицательное double-число около нуля после конвертации соответствует значению для DATE примерно -1.999999... , что с округлением дает -2. Суть в том, что в "вывернутой" системе счисления DATE между -1.9999... и -2 действительно около 2 дней разницы, и код получается чувствительным к ошибкам округления.


Спасибо за аргументированный ответ. Но факт остаётся фактом — баг есть и единственный выход я пока вижу это переходить на __int64 и реализовывать всю эту арифметику самому
Re[2]: Проблема с COleDateTime.
От: Аноним  
Дата: 09.04.09 07:09
Оценка:
Здравствуйте, Avdeev, Вы писали:

A>Здравствуйте, rus blood, Вы писали:



A>Спасибо за аргументированный ответ. Но факт остаётся фактом — баг есть и единственный выход я пока вижу это переходить на __int64 и реализовывать всю эту арифметику самому


Извиняюсь за любопытство, но уж очень интересно.
Для каких целей используется такая дата?
Re[3]: Проблема с COleDateTime.
От: Аноним  
Дата: 09.04.09 07:31
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, Avdeev, Вы писали:


A>>Здравствуйте, rus blood, Вы писали:



A>>Спасибо за аргументированный ответ. Но факт остаётся фактом — баг есть и единственный выход я пока вижу это переходить на __int64 и реализовывать всю эту арифметику самому


А>Извиняюсь за любопытство, но уж очень интересно.

А>Для каких целей используется такая дата?

Скажем так, я разработчик в некой IT компании. Мне тестер написал баг, что в некой моей функциональности вот такая дурь. Не отреагировать на это я не могу, тем более что есть дотошный пользователь, который также на это наткнулся! Правда вот зачем это пользователю, вот это вообще вопрос, но он уж очень расстроился по этому поводу
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.