2016-07-12 3 views
1

У меня есть упражнение, с которым у меня небольшие проблемы.Способ расчета рабочих дней

Я должен создать калькулятор, который принимает два параметра: Дата начала и дни для добавления (кроме субботы и воскресенья, только рабочие дни, с понедельника по пятницу). Другое дело, что сумма должна включать дату начала.

E.g. давайте начнем день 12 июля 2016 года и добавим 8 дней, которые соответствуют 21 июля 2016 года (суббота и воскресенье исключены, а вторник, 21 июля 2016 года считается одним днем).

Надеюсь, я понятен.

Я пытался что-то закодировать, но он не работает.

// rStringGridEd1->IntCells[3][row] is a custom stringgrid 
// and correspond to the number of days to add, j is the 
// counter for the loop 
while (j < rStringGridEd1->IntCells[3][row]) 
{ 
    if (DayOfWeek(date) != 1 || DayOfWeek(date) !=7) 
    { 
     // if current date (TDate date = "12/07/16") is not Saturday or Sunday increment date by one day 
     date++; 
    } 
    else if(DayOfWeek(date) == 1) 
    { 
     //If date correspond to sunday increment the date by one and j the counter by one 
     date=date+1; 
     j++; 
    } 
    else if(DayOfWeek(date) == 7) 
    { 
     //If date correspond to saturday increment the date by two days and j the counter by one 
     date=date+2; 
     j++; 
    } 
    j++; 
} 

Может ли кто-нибудь помочь мне, пожалуйста?

+2

Borland C++ ... Разве это не инструмент бабушки? – coincoin

+0

'date + 2' ничего не увеличивает, это как nop. Вероятно, вы имели в виду 'date + = 2'. Аналогично для 'date + 1'. –

+0

совпадение, я согласен с вами, но мне нужно работать с borland C++ – Lazarius

ответ

3

Вот что Lee Painton «s отлично (и до-голосование) ответ будет выглядеть, как с помощью этого free, open-source C++11/14 date library, который построен на вершине <chrono>:

#include "date.h" 
#include <iostream> 

date::year_month_day 
get_end_job_date(date::year_month_day start, date::days length) 
{ 
    using namespace date; 
    --length; 
    auto w = weeks{length/days{5}}; 
    length %= 5; 
    auto end = sys_days{start} + w + length; 
    auto wd = weekday{end}; 
    if (wd == sat) 
     end += days{2}; 
    else if (wd == sun) 
     end += days{1}; 
    return end; 
} 

Вы могли бы осуществить это следующим образом:

int 
main() 
{ 
    using namespace date::literals; 
    std::cout << get_end_job_date(12_d/jul/2016, date::days{8}) << '\n'; 
} 

Какие выходы:

2016-07-21 

У этого упрощенного калькулятора есть предварительное условие, что start не на выходных. Если это не является желательным предварительным условием, вы можете обнаружить это до вычисления и приращения start внутренне на день или два.

date library позаботился о таких вещах, как отношения между days и weeks, и как добавить days к дате. Он основан на очень эффективных (неитеративных) алгоритмах shown and described here.

1

Если вам не требуется использовать цикл, вы можете рассмотреть возможность реорганизации своего решения с более простым вычислением. Рассмотрим, например, что каждые пять рабочих дней автоматически добавляет семь дней к дате. Таким образом, используя коэффициент и остаток дней для добавления, следует указать, сколько общих дней добавить к вашей переменной date, не прибегая к петле грубой силы.

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

+0

Я буквально просто печатал это. Для * в какой день недели я заканчиваю *, вы можете просто взять текущий день, добавить количество дней, чтобы сдвинуть его, и принять этот модуль 5 - так как мы всегда пропускаем выходные. – will

+0

Да, хотя вам нужно помнить, что день недели начинается в воскресенье. –

+0

просто смещен, чтобы положить понедельник как 1 раньше, а затем перевернуть его после модуляции. – will

Смежные вопросы