首页 文章

在给定日期范围的情况下生成工作日日期的算法[关闭]

提问于
浏览
2

我希望能够计算两个日期d1和d2的营业日期(周一至周五) . 然而,在某些地方,工作日是坐着或晒太阳 .

STL或C中是否有设施可以进行这样的计算?

3 回答

  • 5

    Quantlib有很多日期处理功能,比如调整到下一个工作日或前一个,复活节假期,日本帝国日历,计算两个日期之间的天数...

  • 2

    不可以 . 营业日数据不是C中可用的区域设置信息的一部分 . 您必须构建一个数据库,其中包含所有感兴趣区域的“营业日” .

  • 1

    由于每个行业都有自己的bday版本,因此该工作区在工作日甚至更复杂一些 . 在我的行业(金融服务)中,债券交易日历与美国股票交易日历不同,后者与亚洲商品日历不同 .

    为了找出日期所在的星期几,有一个提升date_time库,http://www.boost.org/doc/libs/1_42_0/doc/html/date_time.html有助于过滤掉一些明显的非工作日,但不考虑假期和其他奇怪的事情 . 这些只需要以特殊的方式保存 .

    这就是我在C中的做法(减去所有的错误检查)

    typedef unsigned Date_t;//for this example, uints work fine
    typedef std::vector<Date_t> datevec_t;//we need random access iterators
    datevec_t dates;//one vector per locale
    //add data in sorted order, one for each bday in the locale
    dates.push_back(20090104); 
    dates.push_back(20090105);
    dates.push_back(20090106);
    dates.push_back(20090107);
    

    计算日期是通过使用一些常规的格里高利历图书库加上我的特殊拘留和其他结算数据来完成的 . 但实际上我并不是每次计算日期,而是从一些数据存储区加载计算结果,因为它几乎不会发生变化,并且通常至少提前一年知道 . (在我的例子中,我在一些脚本语言中执行此操作,并从SQL数据库中读取结果)

    现在做一个存在查询

    bool is_bday=std::binary_search(dates.begin(),dates.end(),20091225);
    

    在20091225之前找到第3个bday proir到最后一个bday

    Date_t myday=*(std::lower_bound(dates.begin(),dates.end(),20091225)-3);
    

    查找两个日历日期之间的工作日数

    int numdays=std::upper_bound(dates.begin(),dates.end(),20100105)
               -std::lower_bound(dates.begin(),dates.end(),20090105);
    

    在SQL中我做了类似的事情:

    create table BDays(
        bday date,--the business day
        daynum int,--sequential number
        lcode int, --locale 
        primary (bday,ccode),
        unique(daynum,ccode)
        )
    

    然后使用连续的daynums为每个工作日插入值

    insert BDays values
        (20090104,1,1),
        (20090105,2,1),
        (20090106,3,1),
    -- etc for every business day in the locale
    

    这实际上不是很多数据,只需要做一次 . 要进行存在查询

    select count(1) from BDays where bday=20090101 and lcode=1
    

    做日期数学,比如在25月25日之前的最后一个工作日之前的第三个bday?

    select b1.bday from BDays b1
    join BDays b2 on(b1.lcode=1 and b2.lcode=1 and b1.daynum-3=b2.daynum)   
    join (select max(bday) bday from BDays where bday<=20091225 and lcode=1) cday 
    on(cday.bday = b2.bday )
    

相关问题