Vappu simoissa ja tylsyyksissäni sain päähäni kirjoitella viestiketjussa mainitun NetworkDays() funktion toteutuksen PL/I:llä.
Alla olevaan bittimerkkijono pohjaiseen ratkaisuun päädyin itse. Jos jollakin tulee mieleen parempi sekä suoraviivaisempi tapa toteutukseen niin sopii paljastaa oma ratkaisutapansa.
*PROCESS MARGINS(1, 140);
t1: proc options (main);
dcl from char (8) date ('DDMMYYYY');
dcl to char (8) date ('DDMMYYYY');
dcl holidays (7) char (8) date ('DDMMYYYY')
init ('01012012', '06012012', '01052012', '06122012', '24122012', '25122012', '26122012');
from = '01122012';
to = '31122012';
put skip list ('Number of working days in december 2012: ' || trim(workdays(from, to, holidays)));
(STRINGRANGE, SUBSCRIPTRANGE):
workdays: proc (from, to, holiday_list) returns (fixed bin (31));
dcl (from, to) char (8) date ('DDMMYYYY');
dcl holiday_list (*) char (8) date ('DDMMYYYY') optional;
dcl (days_from, days_to, day) fixed bin (31);
dcl total_days fixed bin (31);
dcl week_index fixed bin (31);
dcl nworkdays fixed bin (31);
dcl i fixed bin (31);
dcl (result, holiday) bit (*) controlled;
dcl weeks (7) bit (7) nonasgn init ('1000001'b, '0000011'b, '0000110'b, '0001100'b, '0011000'b, '0110000'b, '1100000'b);
dcl (days, weekday, tally, substr, lbound, hbound, copy, omitted) builtin;
days_from = days(from, 'DDMMYYYY');
days_to = days(to, 'DDMMYYYY');
total_days = days_to - days_from + 1;
if total_days <= 0 then return (0);
allocate result bit (total_days);
week_index = weekday(days_from);
result = copy(weeks(week_index), total_days / 7) || substr(weeks(week_index), 1, mod(total_days, 7));
if ^omitted(holiday_list) then
do;
allocate holiday bit (total_days);
do i = lbound(holiday_list) to hbound(holiday_list);
day = days(holiday_list(i), 'DDMMYYYY');
if (day >= days_from) & (day <= days_to) then
do;
holiday = copy('0'b, day - days_from ) || '1'b || copy('0'b, days_to - day);
result = result | holiday;
end;
end;
free holiday;
end;
nworkdays = tally(result, '0'b);
free result;
return (nworkdays);
end workdays;
end t1;En jaksanut tehdä tarkistuksia sille, että onko esim helatorstai ja vappu samana päivänä, mutta tässä jotain sinneppäin:
using System;
using System.Collections.Generic;
namespace WorkingDays
{
class Program
{
static void Main(string[] args)
{
bool ConvertState = false;
int SelectedYear = 0;
while (!ConvertState)
{
Console.Clear();
Console.Write("Syötä haluttu vuosi: ");
string input = Console.ReadLine();
ConvertState = int.TryParse(input, out SelectedYear);
}
int VacationAmount = CountVacationDays(SelectedYear);
DateTime FirstDay = new DateTime(SelectedYear,1,1);
DateTime LastDay = new DateTime(SelectedYear,12,31);
int WorkingDays = 0;
if(DateTime.IsLeapYear(SelectedYear))
{
DateTime LeapDay = new DateTime(SelectedYear,2,29);
if(LeapDay.DayOfWeek != DayOfWeek.Saturday && LeapDay.DayOfWeek != DayOfWeek.Sunday)
WorkingDays++;
}
for (DateTime DT = FirstDay; DT < LastDay; DT = DT.AddDays(1))
{
if (DT.DayOfWeek != DayOfWeek.Saturday && DT.DayOfWeek != DayOfWeek.Sunday)
WorkingDays++;
}
WorkingDays = WorkingDays - VacationAmount;
Console.WriteLine("Työpäiviä vuonna {0} on {1} kappaletta", SelectedYear.ToString(), WorkingDays.ToString());
Console.ReadLine();
}
static int CountVacationDays(int Year)
{
List<DateTime> VacationList = new List<DateTime>();
//Static Vacation Days
VacationList.Add(new DateTime(Year, 1, 1));
VacationList.Add(new DateTime(Year, 1, 6));
VacationList.Add(new DateTime(Year, 5, 1));
VacationList.Add(new DateTime(Year, 12, 6));
VacationList.Add(new DateTime(Year, 12, 24));
VacationList.Add(new DateTime(Year, 12, 25));
VacationList.Add(new DateTime(Year, 12, 26));
int MovingVacationDays = 4; //Helatorstai,pitkäperjantai, Pääsiäismaanantai,Juhannusaatto
int TotalVacationDays = 0;
VacationList.ForEach(delegate(DateTime date)
{
if (date.DayOfWeek != DayOfWeek.Saturday && date.DayOfWeek != DayOfWeek.Sunday)
TotalVacationDays++;
});
TotalVacationDays += MovingVacationDays;
return TotalVacationDays;
}
}
}Aihe on jo aika vanha, joten et voi enää vastata siihen.