哪个日期是给定日期范围内的工作日

时间:2011-06-22 14:39:25

标签: date crystal-reports crystal-reports-2008 date-range

是否有内置功能可以告诉我哪几天是工作日?这就是我的意思,

如果我选择今天的日期(2011年6月14日),它会给我今天的任何检查号码。这个提前期包括周末。因此,如果我有一个客户在10日(星期五)开始一个项目并在今天完成它;它会显示大约需要五天而不是三天。

3 个答案:

答案 0 :(得分:1)

我相信很久以前曾经有过这样的功能,但我相信功能已被删除。我相信您应该能够使用以下内容来计算两个日期之间的工作日:

DateDiff ("d", {Orders.OrderDate}, {Orders.ShipDate}) -
DateDiff ("ww", {Orders.OrderDate}, {Orders.ShipDate}, crSaturday) -
DateDiff ("ww", {Orders.OrderDate}, {Orders.ShipDate}, crSunday)

这得到总天数差异,并从总数中减去星期六和星期日。请注意,这不包括假期。为此,您需要在自己的用户函数库中维护它们并将它们包含在计算中。

希望这有帮助。

答案 1 :(得分:0)

这是我提出的解决方案。如果它超过7天,我知道要减去多少天。如果它不到7天,我仍然可以知道它是否跨越了周末。 Crystal报告有一个函数DayOfWeek,它返回当天的数字,即星期日= 1,星期一= 2等。如果结束时间日期数小于开始时间数,我们知道它已经过了周末。我们可以减去2。

timeDiff是startdate - finishdate。

if({@timeDiff} >= 35) then
{@timeDiff} - 10
else if({@timeDiff} >= 28) then
{@timeDiff} - 8
else if({@timeDiff} >= 21) then
{@timeDiff} - 6
else if({@timeDiff} >= 14) then
{@timeDiff} - 4
else if({@timeDiff} >= 7) then
{@timeDiff} - 2
else if(DayOfWeek({Command.Finishdate}) < DayOfWeek({Command.Startdate})) then
{@timeDiff} - 2
else
{@timeDiff}

我在我的网站上有更深入的解释。链接是here

答案 2 :(得分:0)

这是一个怪物解决方案,也考虑到公众假期:

// WorkingDays
// Count the number of working days between a start and an end date.
// 
// startDate - first date in the interval
// endDate   - last date in the interval
// countStartAndEnd - if true 1 feb to 2 feb will count as 2 days
//                    if false 1 feb to 2 feb will count as 1 day
//                    given both of them are working days
Function  (dateVar startDate, dateVar endDate, optional booleanVar countStartAndEnd := False)

local NumberVar Weeks; 
local NumberVar Days; 
local NumberVar Hol;

// 5 days for every week (whole or partial)
Weeks := (Truncate (endDate - dayofWeek(endDate) + 1 - (startDate - dayofWeek    (startDate) + 1)) /7 ) * 5;
// Number of days in partial weeks (can be positive or negative)
Days := DayOfWeek(endDate) - DayOfWeek(startDate) + 1 + 
(if DayOfWeek(startDate) = crSunday then -1 else 0) + 
(if DayOfWeek(endDate) = crSaturday then -1 else 0);

// Count number of public holidays in the period
local NumberVar iYear;
local NumberVar i;
for iYear := Year(startDate) to Year(endDate) do (
    Local DateVar Array Holidays := getHolidays(iYear);
    for i := 1 to uBound(Holidays) do (
        local NumberVar hMonth := Month(Holidays[i]);
        local NumberVar hDay := Day(Holidays[i]);
        local DateVar hDate := cDate(iYear, hMonth, hDay);
        if DayOfWeek(hDate) in crMonday to crFriday and
            hDate in startDate to endDate then Hol := Hol+1;
        );
    );

// Return number of working days
Weeks + Days - Hol - toNumber(not countStartAndEnd);

上述代码已在KenHamady找到的解决方案中修改。

上一个函数调用以下函数并返回所有公共假日:

// getHolidays
// Returns an array with all public holidays for a given year
// These are Swedish holidays. Modify as needed.
Function (Numbervar yyyy)

Datevar Array holidays;
local Datevar holiday;
local Datevar easterSunday := getEasterSunday(yyyy);

// New Years Day
// 1 jan
holiday:=Date(yyyy, 1, 1);
Redim Preserve holidays[Ubound(holidays)+1];
holidays[Ubound(holidays)]:=holiday;

// Epiphany 
// 6 jan
holiday:=Date(yyyy, 1, 6);
Redim Preserve holidays[Ubound(holidays)+1];
holidays[Ubound(holidays)]:=holiday;

// Good Friday
// 2 days before easter sunday
holiday:=cDate(DateAdd("d", -2, easterSunday));
Redim Preserve holidays[Ubound(holidays)+1];
holidays[Ubound(holidays)]:=holiday;

// Holy Saturday
// 1 day before easter sunday
holiday:=cDate(DateAdd("d", -1, easterSunday));
Redim Preserve holidays[Ubound(holidays)+1];
holidays[Ubound(holidays)]:=holiday;

// Easter Sunday
// The first Sunday following the first ecclesiastical full moon that occurs on or after the day of the vernal equinox
holiday:=cDate(DateAdd("d", -2, easterSunday));
Redim Preserve holidays[Ubound(holidays)+1];
holidays[Ubound(holidays)]:=holiday;

// Easter Monday
// 1 day after easter sunday
holiday:=cDate(DateAdd("d", 1, easterSunday));
Redim Preserve holidays[Ubound(holidays)+1];
holidays[Ubound(holidays)]:=holiday;

// Labour day
// 1 may
holiday:=Date(yyyy, 5, 1);
Redim Preserve holidays[Ubound(holidays)+1];
holidays[Ubound(holidays)]:=holiday;

// Ascension
// 39 days after easter sunday
holiday:=cDate(DateAdd("d", 39, easterSunday));
Redim Preserve holidays[Ubound(holidays)+1];
holidays[Ubound(holidays)]:=holiday;

// National day
// 6 june
holiday:=Date(yyyy, 6, 6);
Redim Preserve holidays[Ubound(holidays)+1];
holidays[Ubound(holidays)]:=holiday;

// Midsummer's eve
// The friday in the interval 19 june - 25 june
holiday:=cDate(DateAdd("d", 1-dayOfWeek(Date(yyyy, 6, 25), crFriday), Date(yyyy, 6, 25)));
Redim Preserve holidays[Ubound(holidays)+1];
holidays[Ubound(holidays)]:=holiday;

// All saints' day
// The saturday in the interval 31 october - 6 november
holiday:=cDate(DateAdd("d", 1-dayOfWeek(Date(yyyy, 11, 6), crSaturday), Date(yyyy, 11, 6)));
Redim Preserve holidays[Ubound(holidays)+1];
holidays[Ubound(holidays)]:=holiday;

// Christmas eve
// 24 december
holiday:=Date(yyyy, 12, 24);
Redim Preserve holidays[Ubound(holidays)+1];
holidays[Ubound(holidays)]:=holiday;

// Chritmas day
// 25 december
holiday:=Date(yyyy, 12, 25);
Redim Preserve holidays[Ubound(holidays)+1];
holidays[Ubound(holidays)]:=holiday;

// St. Stephen's Day
// 26 december
holiday:=Date(yyyy, 12, 26);
Redim Preserve holidays[Ubound(holidays)+1];
holidays[Ubound(holidays)]:=holiday;

// New year's eve
// 31 december
holiday:=Date(yyyy, 12, 31);
Redim Preserve holidays[Ubound(holidays)+1];
holidays[Ubound(holidays)]:=holiday;

holidays;

上面的代码基于this post craig中的自定义函数。

假期功能需要能够获得给定年份的复活节星期日:

// getEasterSunday
// Returnes a dateVar of the easter sunday for a given year
//
// Based upon formula from http://aa.usno.navy.mil/faq/docs/easter.php
Function (numberVar yyyy)

local numberVar c := int(yyyy / 100);
local numberVar n := yyyy - 19 * int(yyyy / 19);
local numberVar k := int((c-17)/25);
local numberVar i := c - int(c/4) - int((c-k)/3) + 19*n + 15;
i := i - 30 * int(i/30);
i := i - int(i/28) * ( 1 - int(i/28) * int(29/(i+1)) * int((21-n)/11));
local numberVar j := yyyy + int(yyyy/4) + i + 2 - c + int(c/4);
j := j - 7 * int(j/7);
local numberVar l := i - j;
local numberVar m := 3 + int((l+40)/44);
local numberVar d := l + 28 - 31 * int(m/4);

cDate(yyyy, m , d);

来自United States Naval Observatory的复活节星期日计算公式。

相关问题