AXForum  
Вернуться   AXForum > Microsoft Dynamics AX > DAX: Программирование
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 09.03.2011, 12:21   #1  
kair84 is offline
kair84
Участник
 
47 / 58 (2) ++++
Регистрация: 15.04.2010
Адрес: Belarus
Lightbulb Баг или "пророчество"
Функция WeekOfYear(31\12\2012) возвращает 2
наверное после дня апокалипсиса нумерация недель начинается заново.
Старый 09.03.2011, 12:29   #2  
kair84 is offline
kair84
Участник
 
47 / 58 (2) ++++
Регистрация: 15.04.2010
Адрес: Belarus
красота:
X++:
print(weekofYear(30\12\2012)); // 53
print(weekofYear(31\12\2012)); // 2
print(weekofYear(01\01\2013)); // 1
Старый 09.03.2011, 12:38   #3  
George Nordic is offline
George Nordic
Модератор
Аватар для George Nordic
Злыдни
 
4,479 / 1250 (50) ++++++++
Регистрация: 17.12.2003
Адрес: Moscow
Записей в блоге: 9
Еще интереснее:
X++:
    info(strfmt("d3:%1",WeekOfYear(21\12\2012))); //52
    info(strfmt("d4:%1",WeekOfYear(30\12\2012))); //53
Хотя между 21 и 30 явно больше 7 дней

Вау! Да класс global рулит! static int weekOfYear(date _curDate)

Цитата:
// The dayofwk function used above returns
// the ISO-8601 day of week, where Monday is 1
// and recall that the 1 was subtracted from the result
// to get a value between (0 - 6).
//
// If the locale settings (firstDayOfWeek) is
// not Monay (i.e. > 0) then the caclulated
// day of week results need to be adjusted
// so they align with the locale setting.
Там комментариев больше чем кода Рефакторинг блин...
А толку-то...

С Уважением,
Георгий
За это сообщение автора поблагодарили: mifi (-1).
Старый 09.03.2011, 12:54   #4  
mifi is offline
mifi
Microsoft Dynamics
Сотрудники Microsoft Dynamics
 
173 / 89 (3) ++++
Регистрация: 24.07.2002
Цитата:
Сообщение от George Nordic Посмотреть сообщение
Еще интереснее:
X++:
    info(strfmt("d3:%1",WeekOfYear(21\12\2012))); //52
    info(strfmt("d4:%1",WeekOfYear(30\12\2012))); //53
Хотя между 21 и 30 явно больше 7 дней

С Уважением,
Георгий
Хотя между 21 и 30 и больше 7 дней, но 21.12.2012 - пятница, 30.12.2012 - воскресенье. Что не так-то? Вроде бы нормально, что между одним днем одной недели и другим днем следующей недели не 7 дней..
Старый 09.03.2011, 13:03   #5  
Bober is offline
Bober
Участник
 
311 / 104 (4) +++++
Регистрация: 29.05.2007
Цитата:
Сообщение от kair84 Посмотреть сообщение
красота:
X++:
print(weekofYear(30\12\2012)); // 53
print(weekofYear(31\12\2012)); // 2
print(weekofYear(01\01\2013)); // 1
Это майя дали человечеству еще один день, чтобы оттянуться напоследок на Новый год. Чтобы президент в своей последней речи попросил у всех прощения. И т.п.
Старый 09.03.2011, 13:59   #6  
ice is offline
ice
Участник
Аватар для ice
Лучший по профессии 2014
 
1,689 / 405 (17) +++++++
Регистрация: 23.03.2006
Цитата:
Сообщение от kair84 Посмотреть сообщение
Функция WeekOfYear(31\12\2012) возвращает 2
наверное после дня апокалипсиса нумерация недель начинается заново.
в AX2009 возвращает 1
Старый 09.03.2011, 13:59   #7  
Poleax is offline
Poleax
Модератор
Аватар для Poleax
MCP
MCBMSS
Злыдни
 
1,353 / 595 (22) +++++++
Регистрация: 17.02.2005
Адрес: msk
Записей в блоге: 34
:)
Цитата:
Сообщение от kair84 Посмотреть сообщение
Функция WeekOfYear(31\12\2012) возвращает 2
наверное после дня апокалипсиса нумерация недель начинается заново.
2 не наблюдается (Ax 2009 SP1 EE RU6 5.0.1500.3761)

X++:
static void Job17(Args _args)
{
    ;
    info(strfmt("25.12.2011 - %1",WeekOfYear(25\12\2011)));  //52
    info(strfmt("30.12.2011 - %1",WeekOfYear(30\12\2011)));  //1
    info(strfmt("31.12.2011 - %1",WeekOfYear(31\12\2011)));  //1
    info(strfmt("01.01.2012 - %1",WeekOfYear(01\01\2012)));  //1

    info(strfmt("29.12.2012 - %1",WeekOfYear(29\12\2012)));  //53
    info(strfmt("30.12.2012 - %1",WeekOfYear(30\12\2012)));  //53
    info(strfmt("31.12.2012 - %1",WeekOfYear(31\12\2012)));  //1
    info(strfmt("01.01.2013 - %1",WeekOfYear(01\01\2013)));  //1
}
Код:
Info	Сообщение (13:48:46)	25.12.2011 - 52
Info	Сообщение (13:48:46)	30.12.2011 - 1
Info	Сообщение (13:48:46)	31.12.2011 - 1
Info	Сообщение (13:48:46)	01.01.2012 - 1
Info	Сообщение (13:48:46)	29.12.2012 - 53
Info	Сообщение (13:48:46)	30.12.2012 - 53
Info	Сообщение (13:48:46)	31.12.2012 - 1
Info	Сообщение (13:48:46)	01.01.2013 - 1

но, есть разночтения с SQL:

PHP код:
SET DATEFORMAT dmy
SELECT DATEPART(ww'25/12/2011') as '25/12/2011'
      
,DATEPART(ww'30/12/2011') as '30/12/2011'
      
,DATEPART(ww'31/12/2011') as '31/12/2011'
      
,DATEPART(ww'01/01/2012') as '01/01/2012';
    
SELECT DATEPART(ww'30/12/2012') as '30/12/2012'
      
,DATEPART(ww'31/12/2012') as '31/12/2012'
      
,DATEPART(ww'01/01/2013') as '01/01/2013';

select @@version 
Код:
25/12/2011  30/12/2011  31/12/2011  01/01/2012
----------- ----------- ----------- -----------
52          53          53          1

(1 row(s) affected)

30/12/2012  31/12/2012  01/01/2013
----------- ----------- -----------
53          54          1

(1 row(s) affected)


--------------------------------------------------------------------------------------------------------------------------------
Microsoft SQL Server 2008 R2 (RTM) - 10.50.1600.1 (Intel X86) 
	Apr  2 2010 15:53:02 
	Copyright (c) Microsoft Corporation
	Enterprise Edition on Windows NT 5.2 <X86> (Build 3790: Service Pack 2) (Hypervisor)
__________________

This posting is provided "AS IS" with no warranties, and confers no rights.
Старый 09.03.2011, 14:01   #8  
George Nordic is offline
George Nordic
Модератор
Аватар для George Nordic
Злыдни
 
4,479 / 1250 (50) ++++++++
Регистрация: 17.12.2003
Адрес: Moscow
Записей в блоге: 9
Да, в 2009 возвращает 1. Я свои примеры тоже с 2009 брал.

С Уважением,
Георгий
Старый 09.03.2011, 14:13   #9  
George Nordic is offline
George Nordic
Модератор
Аватар для George Nordic
Злыдни
 
4,479 / 1250 (50) ++++++++
Регистрация: 17.12.2003
Адрес: Moscow
Записей в блоге: 9
Цитата:
Сообщение от mifi Посмотреть сообщение
Хотя между 21 и 30 и больше 7 дней, но 21.12.2012 - пятница, 30.12.2012 - воскресенье. Что не так-то? Вроде бы нормально, что между одним днем одной недели и другим днем следующей недели не 7 дней..
Да, именно поэтому в самой последней версии DAX 31.12.2012 - это 1я рабочая неделя.
Старый 09.03.2011, 14:21   #10  
nix0root is offline
nix0root
Участник
 
67 / 16 (1) ++
Регистрация: 17.03.2009
Адрес: МО
Не верно отрабатывает функция wkofyr(_date), которая вызывается из weekofyear.
__________________
В подводной охоте главное вдох ...
Старый 09.03.2011, 14:34   #11  
oip is offline
oip
Axapta
Лучший по профессии 2014
 
2,564 / 1416 (53) ++++++++
Регистрация: 28.11.2005
Записей в блоге: 1
Цитата:
Сообщение от kair84 Посмотреть сообщение
наверное после дня апокалипсиса нумерация недель начинается заново.
Майя тут ни при чем. Например:

X++:
info(strfmt("%1",WeekOfYear(31\12\1928))); // Ax 3.0, 4.0: 2. Ax 2009: 1
info(strfmt("%1",WeekOfYear(31\12\1956))); // Ax 3.0, 4.0: 2. Ax 2009: 1
info(strfmt("%1",WeekOfYear(31\12\1984))); // Ax 3.0, 4.0: 2. Ax 2009: 1
info(strfmt("%1",WeekOfYear(31\12\2040))); // Ax 3.0, 4.0: 2. Ax 2009: 1

info(strfmt("%1",WeekOfYear(31\12\2001))); //1
info(strfmt("%1",WeekOfYear(30\12\2003))); //1
info(strfmt("%1",WeekOfYear(29\12\2008))); //1
__________________
С уважением,
Олег.
Старый 10.03.2011, 12:28   #12  
George Nordic is offline
George Nordic
Модератор
Аватар для George Nordic
Злыдни
 
4,479 / 1250 (50) ++++++++
Регистрация: 17.12.2003
Адрес: Moscow
Записей в блоге: 9
Несмотря на все протесты Mifi, функция работает некорректно. Никакие это ни майя - очередная бага, вернее, их скопище, которые лежат еще с 3ки, если не раньше.

Да, wkofyr(_date) - работает некорректно. Но для этого и был написан пафосный класс-обертка weekOfYear(), который учитывает локальные настройки, в частности, с какого дня начинается неделя, но при этом при формировании тестовой даты не учитывает, что год может быть високосным

Ошибка возникает здесь, как я говорил:
X++:
            if (week > 52)
            {
                // Look at the last day of the week and compare it
                // to the target date.  If the year is different
                // then the target date is part of week 1 for next year.
                testDate = _curDate + ((#DaysPerWeek - 1) - dowCurDate); //Ошибка
Непонятна необходимость данной проверки. В России 31.12.2012 является 54 неделей, а не 1й.
Ладно, хорошо. Может, в мире и не так. Тогда надо учитывать, что каждый 4й год происходит такая беда как високосный год, и testDate формируется некорректно.

С Уважением,
Георгий
Старый 10.03.2011, 12:58   #13  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,429 / 1772 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Цитата:
Сообщение от George Nordic Посмотреть сообщение
надо учитывать, что каждый 4й год происходит такая беда как високосный год, и testDate формируется некорректно.
А при чём тут високосный год? testDate формируется с одной лишь целью - узнать на какой год попадает конец недели. В случае если неделя начинается в одном году а коньчается в другом, то ей присваивают первый номер! Зачем это сделано? Наверное для того чтобы дни одной и той же недели с понедельника по воскресенье всегда оказывались в одном номере недели.
Старый 10.03.2011, 13:07   #14  
George Nordic is offline
George Nordic
Модератор
Аватар для George Nordic
Злыдни
 
4,479 / 1250 (50) ++++++++
Регистрация: 17.12.2003
Адрес: Moscow
Записей в блоге: 9
Цитата:
Сообщение от S.Kuskov Посмотреть сообщение
А при чём тут високосный год? testDate формируется с одной лишь целью - узнать на какой год попадает конец недели. В случае если неделя начинается в одном году а коньчается в другом, то ей присваивают первый номер!
Честно - я не помню уже. Давно разбирал, году в 2004 столкнулся с этой проблемой. Но давайте разберем вместе. Так вот, поставьте брекпоинт на эту строчку и проверьте, корректно ли формируется testDate в обычном и високосном году. В обычном году была ошибка на 2 дня, кажется, в високосный - тоже ошибка была.
Цитата:
Сообщение от S.Kuskov Посмотреть сообщение
Зачем это сделано?
Да вот сам в шоке. Наверное, что бы понять, если последняя неделя года приходится с переходом на другой год, то дать ей номер 1?
Цитата:
Сообщение от S.Kuskov Посмотреть сообщение
Наверное для того чтобы дни одной и той же недели с понедельника по воскресенье всегда оказывались в одном номере недели.
Угу. А вот с переходом через год этот фокус не срабатывает.

С Уважением,
Георгий
Старый 10.03.2011, 13:35   #15  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,429 / 1772 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Цитата:
Сообщение от George Nordic Посмотреть сообщение
давайте разберем вместе. Так вот, поставьте брекпоинт на эту строчку и проверьте, корректно ли формируется testDate в обычном и високосном году.
Давайте ещё раз посмотрим на строчку которую вы привели
X++:
testDate = _curDate + ((#DaysPerWeek - 1) - dowCurDate);
Здесь testDate получается смещением даты в перёд на количество дней оставшееся до конца недели. Т.е. так чтобы попасть на воскресенье. Единственное место где здесь может быть засада - это функция dayofwk (используется для расчёта dowCurDate), возвращающая номер дня недели. Но она работает корректоно и в високосный год и в не високосный.

Цитата:
Сообщение от George Nordic Посмотреть сообщение
В обычном году была ошибка на 2 дня, кажется, в високосный - тоже ошибка была.
Т.е. дата testDate не попадала на воскресенье? Мне это воспроизвести не удалось.
Старый 10.03.2011, 14:10   #16  
George Nordic is offline
George Nordic
Модератор
Аватар для George Nordic
Злыдни
 
4,479 / 1250 (50) ++++++++
Регистрация: 17.12.2003
Адрес: Moscow
Записей в блоге: 9
Так. Стоп.

1. Вы согласны, что приведенная функция работает некорректно?
Или Вы считаете, что 27.12.10 - , 26.12.11 - , 24-30.12.12 - это 1 рабочая неделя??
2. Если Вы согласны, что это не так, что это 53 недели в году, тогда идем дальше.
Вы согласны, что ошибка возникает именно в методе WeekOfYear?
3. Вы согласны, что они возникает именно при первой проверке if (week > 52)?

Итак, если Вы согласны, то осталось понять, а как исправить функцию, что бы она возвращала корректные значения для России.

Этого можно добиться, исключив данную проверку (для России). Рассматривать расчет testDate, как Вы уже указали, некорректно, так как цель данного расчет - это посмотреть, не переходит ли неделя через год и сбросить счетчик текущей недели.

Согласны? Или есть какие-либо подводные камни, которые я не учел?

С Уважением,
Георгий
Старый 10.03.2011, 14:31   #17  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,429 / 1772 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Цитата:
Сообщение от George Nordic Посмотреть сообщение
1. Вы согласны, что приведенная функция работает некорректно?
Или Вы считаете, что 27.12.10 - , 26.12.11 - , 24-30.12.12 - это 1 рабочая неделя??
Не знаю. Никогда не приходилось сталкиваться с этой функцией, а тут нужно смотреть именно на контекст применения этой функции. Теоретически оба варианты имеют право на существование.

Цитата:
Сообщение от George Nordic Посмотреть сообщение
Итак, если Вы согласны, то осталось понять, а как исправить функцию, что бы она возвращала корректные значения для России.
Этого можно добиться, исключив данную проверку (для России).
Да, если убрать данную проверку, то результат будет другим, возможно для кого-то более ожидаемым.

P.S.: И ещё, чтобы не вводить никого в заблуждение, мы же говорим не о рабочих неделях, а о календарных. В том смысле, что праздничные дни никак на результат не влияют

Последний раз редактировалось S.Kuskov; 10.03.2011 в 14:33.
Старый 10.03.2011, 14:47   #18  
oip is offline
oip
Axapta
Лучший по профессии 2014
 
2,564 / 1416 (53) ++++++++
Регистрация: 28.11.2005
Записей в блоге: 1
Цитата:
Сообщение от George Nordic Посмотреть сообщение
1. Вы согласны, что приведенная функция работает некорректно?
Не согласен. Некорректно в каком случае? В стандартной Аксапте она используется только для отображения номера недели в форме SysDateLookUp. И в этом контексте выглядит все логично.

А если кто-то будет использовать данную функцию в ином контексте, не разобравшись в принципе ее работы, посмотрев только на название, то он сам себе злобный буратино. Хотя да, могли бы в методе сверху написать об "особенности" определения номера недели в конце года, чтобы не было соблазна воспользоваться ей в неподобающем месте.
__________________
С уважением,
Олег.
За это сообщение автора поблагодарили: George Nordic (1), S.Kuskov (1).
Старый 10.03.2011, 16:21   #19  
George Nordic is offline
George Nordic
Модератор
Аватар для George Nordic
Злыдни
 
4,479 / 1250 (50) ++++++++
Регистрация: 17.12.2003
Адрес: Moscow
Записей в блоге: 9
Цитата:
Сообщение от S.Kuskov Посмотреть сообщение
P.S.: И ещё, чтобы не вводить никого в заблуждение, мы же говорим не о рабочих неделях, а о календарных. В том смысле, что праздничные дни никак на результат не влияют
Рабочая неделя - это продолжительность работы в течение календарной недели в часах. Так что это немного не то... Я понял, о чем Вы говорите. Да, для этих целей необходимо использовать функциональность календарей. Нумерация рабочих недель совпадает с нумерацией календарных недель. 1 рабочая неделя начинается 1 января, а не 11 января.
Цитата:
Сообщение от oip Посмотреть сообщение
В стандартной Аксапте она используется только для отображения номера недели в форме SysDateLookUp. И в этом контексте выглядит все логично.
Ох же ты! Надо же, не ожидал, спасибо. Не ожидал, что в Sys используется функция куда высшего слоя..
Цитата:
Сообщение от oip Посмотреть сообщение
А если кто-то будет использовать данную функцию в ином контексте, не разобравшись в принципе ее работы, посмотрев только на название, то он сам себе злобный буратино. Хотя да, могли бы в методе сверху написать об "особенности" определения номера недели в конце года, чтобы не было соблазна воспользоваться ей в неподобающем месте.
Хм. а что еще ожидать от функции с таким названием? Или предлагаешь под каждый чих свою функцию писать? Неразумно. Стандарт - он на то и стандарт, что ждешь от него стандартного предсказуемого поведения, а не кренделей.

С Уважением,
Георгий
Старый 12.03.2011, 22:27   #20  
Raven Melancholic is offline
Raven Melancholic
Участник
Аватар для Raven Melancholic
Самостоятельные клиенты AX
Лучший по профессии 2015
 
2,158 / 1286 (47) ++++++++
Регистрация: 21.03.2005
Адрес: Москва-Петушки
Если учитывать, что в DAX2009 серьезно переписали подсистему работы с датами, то удивляться различию между DAX4 (и Ax3.0) и DAX2009 в результатах в общем-то не стоит (например, метод firstWeekOfYear класса Global полностью переписан на использование NET, поэтому в DAX2009 работает общая логика Win, а не особенности Ax).
Ну, и тем более, влияет серьезное изменение метода weekOfYear того же класса Global.

Последний раз редактировалось Raven Melancholic; 12.03.2011 в 22:40.
Теги
weekofyear

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Баг на форме "Проводки по сопоставлению" S.Kuskov DAX: Программирование 12 29.04.2009 19:19
Тендер на внедрение модуля "Управление персоналом" и "Расчеты с персоналом" Oxsana DAX: Прочие вопросы 5 02.05.2006 19:47
Галка "Закрыто" на таблице "В наличии" sev DAX: Функционал 1 11.04.2006 10:19
баг в 2.5. Будьте осторожнее с символом "_" подчеркивание levsha DAX: Программирование 5 07.12.2004 12:26
"LIKE" и "OR" в "qbds" @x DAX: Программирование 14 20.01.2004 13:20

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

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 19:55.
Powered by vBulletin® v3.8.5. Перевод: zCarot
Контактная информация, Реклама.