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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 09.11.2006, 18:53   #1  
itfs is offline
itfs
Участник
 
277 / 43 (2) +++
Регистрация: 18.07.2005
Адрес: Moscow
08.12.2006 - 09.11.2006
Результат:
distance is 0 year(s), 1 month(s) and -1 day(s)

С уважением, itfs.
Старый 10.11.2006, 12:09   #2  
gl00mie is offline
gl00mie
Участник
MCBMSS
Most Valuable Professional
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,684 / 5813 (201) ++++++++++
Регистрация: 28.11.2005
Адрес: Москва
Записей в блоге: 3
Цитата:
Сообщение от itfs Посмотреть сообщение
08.12.2006 - 09.11.2006
Результат:
distance is 0 year(s), 1 month(s) and -1 day(s)
Да, точно все оказалось несколько сложнее... Вот чуть измененный вариант именования количества периодов
X++:
// возвращает строку "кол-во периодов"
static str PeriodSklInt(IntvScale _period, int _count)
{
    str _s;
    ;
    if (!_count) return "";
    if (_count < 0) _count = -_count;
    if ((_count mod 100<10 || _count mod 100>20) && _count mod 10==1)
        switch (_period)
        {
            case IntvScale::Day     : _s = "день"; break;
            case IntvScale::Week    : _s = "неделя"; break;
            case IntvScale::Month   : _s = "месяц"; break;
            case IntvScale::Quarter : _s = "квартал"; break;
            case IntvScale::Year    : _s = "год"; break;
            default                 : _s = "период"; break;
        }
    else if ((_count mod 100<10 || _count mod 100>20) && _count mod 10>1 && _count mod 10<=4)
        switch (_period)
        {
            case IntvScale::Day     : _s = "дня"; break;
            case IntvScale::Week    : _s = "недели"; break;
            case IntvScale::Month   : _s = "месяца"; break;
            case IntvScale::Quarter : _s = "квартала"; break;
            case IntvScale::Year    : _s = "года"; break;
            default                 : _s = "периода"; break;
        }
    else
        switch (_period)
        {
            case IntvScale::Day     : _s = "дней"; break;
            case IntvScale::Week    : _s = "недель"; break;
            case IntvScale::Month   : _s = "месяцев"; break;
            case IntvScale::Quarter : _s = "кварталов"; break;
            case IntvScale::Year    : _s = "лет"; break;
            default                 : _s = "периодов"; break;
        }
    return strfmt("%1 %2",_count, _s);
}
а вот подправленная функция расчета интервала
X++:
static str myDateDiff(date _d1, date _d2, boolean _include = false)
{
    date    m_d1, m_d2;             // m_d2 >= m_d1
    str     _s;
    int     m_year, m_mth, m_days;
    ;
    if(_d1<_d2)
    {
        m_d1 = _d1;
        m_d2 = _d2;
    } else
    {
        m_d1 = _d2;
        m_d2 = _d1;
    }
    m_year  = yearDiff(m_d2,m_d1);
    m_mth   = mthOfYr(m_d2) - mthOfYr(m_d1);
    if (m_mth < 0)
        m_mth += 12;
    m_days = dayOfMth(m_d2) - dayOfMth(m_d1);
    if (m_days < 0)
    {
        m_mth--;
        m_days += dayOfMth(dateEndMth(m_d1));
    }
    if (m_mth < 0)
        m_mth += 12;
    if (_include) m_days++;
    if (m_days == dayOfMth(dateEndMth(m_d2)))
    {
        m_mth++;
        m_days = 0;
    }
    _s = strltrim(strrtrim(strfmt("%1 %2 %3",   PeriodSklInt(IntvScale::Year,  m_year),
                                                PeriodSklInt(IntvScale::Month, m_mth),
                                                PeriodSklInt(IntvScale::Day,   m_days))));
    return _s;
}
Теперь следующий код
X++:
info("distance is " + myDateDiff(10\09\2005, 01\10\2006));
info("distance is " + myDateDiff(10\10\2005, 09\10\2006));
info("distance is " + myDateDiff(31\01\2005, 29\04\2006));
info("distance is " + myDateDiff(31\01\2005, 30\04\2006));
info("distance is " + myDateDiff(31\01\2005, 01\05\2006));
info('---------------------------');
info("distance is " + myDateDiff(31\01\2004, 27\02\2004));
info("distance is " + myDateDiff(31\01\2004, 28\02\2004));
info("distance is " + myDateDiff(31\01\2004, 29\02\2004));
info("distance is " + myDateDiff(31\01\2004, 01\03\2004));
выдает в infolog
PHP код:
distance is 1 год  21 день
distance is 11 месяцев 30 дней
distance is 1 год 2 месяца 29 дней
distance is 1 год 3 месяца
distance is 1 год 3 месяца 1 день
---------------------------
distance is 27 дней
distance is 28 дней
distance is 1 месяц
distance is 1 месяц 1 день 

Последний раз редактировалось gl00mie; 10.11.2006 в 12:20.
За это сообщение автора поблагодарили: itfs (1).
Старый 10.11.2006, 17:38   #3  
Gustav is offline
Gustav
Moderator
Аватар для Gustav
SAP
Лучший по профессии 2009
 
1,858 / 1152 (42) ++++++++
Регистрация: 24.01.2006
Адрес: Санкт-Петербург
Записей в блоге: 19
? Есть ли в Axapta функция DateAdd ?
Даа... Насколько компактнее и прозрачнее получается алгоритм на VBA при использовании функции DateAdd:
Код:
Sub VBA_TestDifferenceBetweenTwoDates()
    Dim dateBeg As Date, dateEnd As Date, dateTest As Date
    Dim y1 As Integer, m1 As Integer, y2 As Integer, m2 As Integer
    Dim ys As Integer, ms As Integer, ds As Integer
 
    dateBeg = DateSerial(2006, 1, 31)
    dateEnd = DateSerial(2006, 4, 30)
 
    y1 = Year(dateBeg): m1 = Month(dateBeg)
    y2 = Year(dateEnd): m2 = Month(dateEnd)
 
    ms = (y2 * 12 + m2) - (y1 * 12 + m1)  'предварительная разница в месяцах
    dateTest = DateAdd("m", ms, dateBeg)  'пробная дата на ms месяцев от начала
    ds = DateDiff("d", dateTest, dateEnd) 'предварит-ная разница в днях
                                          'в пределах последнего месяца (+/-)
 
    If ds < 0 Then 'ЕСЛИ предварит-но "перебрали" с целыми месяцами от начала
        ms = ms - 1                           'ТО окончат-ная разница в месяцах
        dateTest = DateAdd("m", ms, dateBeg)  'новая "пробная" дата
        ds = DateDiff("d", dateTest, dateEnd) 'окончательная разница в днях (+)
    End If
 
    ys = ms \ 12: ms = ms Mod 12 'годы - тривиально от месяцев
 
    Debug.Print ys, ms, ds '<- Годы, Месяцы, Дни разницы соответственно
 
    'или еще и недели внутри месяца :-)
    Debug.Print ys, ms, ds \ 7, ds Mod 7 '<- Годы, Месяцы, Недели, Дни разницы
End Sub
Вместо функции DateDiff для дней можно использовать и просто операцию вычитания между двумя датами.
А вот есть ли в Аксе приемлемый аналог функции DateAdd ?

P.S. 30.01.07
Как выяснилось здесь, для месяцев - есть. В Global, называется dateMthFwd.
Теги
дата

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Как сделать AND между двумя датасорсами на одном уровне в query rkorchagin DAX: Программирование 15 15.01.2009 17:42
Разница между запросами Rect DAX: Программирование 13 05.12.2006 12:44
Расчеты между компаниями Yuri Nikitenko DAX: Функционал 9 15.11.2004 08:49
дизайн отчета (как сделать его с разделителями между столбцами?) puz DAX: Программирование 7 02.09.2003 08:50
Функция "Удалить строки" Oks DAX: Функционал 1 03.07.2002 18:09

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

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

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 10:38.