Какие дни являются рабочими днями в данном диапазоне дат - PullRequest
1 голос
/ 22 июня 2011

Есть ли встроенная функция, которая скажет мне, какие дни являются рабочими днями? это то, что я имею в виду,

Если бы я выбрал сегодняшнюю дату (14.06.2011), это даст мне любые контрольные номера, которые были закрыты сегодня. Это время включает выходные. Так что, если бы у меня был заказчик, начни проект 10 (пятница) и закончи его сегодня; это показало бы, что это заняло приблизительно пять дней вместо трех.

Ответы [ 3 ]

1 голос
/ 23 июня 2011

Я полагаю, что раньше была функция, которая делала это давным-давно, но я считаю, что эта функция была с тех пор удалена.Я считаю, что вы должны быть в состоянии использовать что-то вроде следующего, которое вычисляет рабочие дни между двумя датами:

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

Это позволяет получить общую разницу дней и вычесть субботу и воскресенье из общей суммы.Обратите внимание, что это не включает праздничные дни.Для этого вам нужно сохранить их в собственной библиотеке пользовательских функций и включить их в расчет.

Надеюсь, это поможет.

0 голосов
/ 01 февраля 2013

Вот решение для монстров, которое также учитывает государственные праздники:

// 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;

Код выше на основе пользовательской функции в этом сообщении от 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);

Формула расчета пасхального воскресенья из Военно-морская обсерватория США .

0 голосов
/ 23 июня 2011

Это решение, которое я придумал. Довольно много, если это что-то более 7 дней, я знаю, сколько дней вычесть. если это меньше 7 дней, я все еще могу выяснить, охватывал ли он выходные. В отчетах Crystal есть функция DayOfWeek, которая возвращает номер дня, т. Е. Воскресенье = 1, понедельник = 2 и т. Д. Если номер дня конечного времени меньше номера начального времени, мы знаем, что он прошел в выходные. и мы можем вычесть 2.

timeDiff - начальная дата - конечная дата.

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}

У меня есть более подробное объяснение на моем сайте. ссылка здесь

...