给定日期范围的生成工作日日期的算法

时间:2010-04-18 06:16:28

标签: c++ algorithm date

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

STL或C ++中是否有允许进行此类计算的工具?

3 个答案:

答案 0 :(得分:5)

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

答案 1 :(得分:2)

由于每个行业都有自己的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

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日之前的最后一个工作日之前的第三天?

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 )

答案 2 :(得分:1)

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