Working Days

by daytime10 at 2012-11-01 12:38:29

Hey guys, I have a challenging one for all of you (well at least I think its challenging lol)

I need to take an employees start date pulled from an AD attribute and do the following

Add 60 WORKING days to it (not including weekends and company holidays) - Put this date in a variable, then take that date and minus 10 Working days from it and put it in a seperate variable
Add 120 WORKING days to it (not including weekends and company holidays) - Put this date in a variable then take that date and minus 10 Working days from it and put it in a seperate variable

So basically 4 variables

I was thinking of sticking the company holidays in some kind of text file that I can maintain, the script can use this while counting dates to determine if its a special holiday

Any Ideas, I am kind of stumped on this one…

Thanks in advance!
by DonJ at 2012-11-01 13:29:29
Tricky indeed.

One option would be to populate an array with every date in your 60-days range. Populate a second array with holiday dates from your text file. Go through those holiday dates one at a time in a foreach loop, and see if each date is -in (that’s the -in operator; could also use -contains) the 60-days array. When one is found, you add another date, making it a 61-days array (for example).

In other words, you can’t add just working days. What you need to discover is if your 60-day range includes a holiday, and if it does, you increment it to a 61-day range. That way you know how many calendar days to add.

There’s probably something more elegant you could do with the base System.Array class, if you’re comfortable calling its methods.
by nohandle at 2012-11-02 05:10:07
Don: imho the foreach loop gets “broken” if the underlying array changes. More precisely it enumerates only on the original set of items. going only from day 0 to 59 not checking if the days added are weekends or holidays. or maybe I just don’t get your example fully.

if I assume that i have a list of holidays for all dates I would check check if the next day is weekday and not in holiday list, counting the days that fulfil the condition and saving the date if the counter is 50, 60,110 and 120 (in a hashtable probably).
and double check for one-off error.

to improve performance make sure you validate the weekday first. hashtable is probably better option than array for the holiday list. but I am not sure if indexing through the array has better or worse performance than getting a key from hashtable in this case. but not really a concern in this case.
by nohandle at 2012-11-02 07:25:55
you probably gonna convert the list to the datetime in the first place,
and then spit it out also as date time objects. I didn’t want to play with it too much and run into datetime format related issues, and also I wanted to preserve ale the info so you can also learn something about Czech holidays this way .)

$holidays = @‘
08.04.2012 Velikono?ní ned?le
09.04.2012 Velikono?ní pond?lí
01.05.2012 Svátek práce (úterý)
08.05.2012 Den vít?zství (úterý)
05.07.2012 Den slovanských v?rozv?st? Cyrila a Metod?je (?tvrtek)
06.07.2012 Den upálení mistra Jana Husa (pátek)
28.09.2012 Den ?eské státnosti (pátek)
28.10.2012 Den vzniku samostatného ?eskoslovenského státu (ned?le)
17.11.2012 Den boje za svobodu a demokracii (st?eda)
24.12.2012 Št?drý den (pond?lí)
25.12.2012 1. svátek váno?ní (úterý)
26.12.2012 2. svátek váno?ní (st?eda)
27.12.2012 není svátek (?tvrtek)
28.12.2012 není svátek (pátek)
29.12.2012 víkend (sobota)
30.12.2012 víkend (ned?le)
31.12.2012 Silvestr (pond?lí)
01.01.2013 Nový rok (úterý)
’@ -split “n&quot;<br>$hash=@{}<br>foreach &#40;$line in $holidays&#41; <br>{<br> $tempDate,$name = $line -split &quot; &quot; <br> $hash.$tempDate = $name<br>}<br>function format-date &#40;[datetime]$date&#41;<br>{<br> &quot;{0:dd.MM.yyyy}&quot; -f $date<br>}<br><br>[datetime]$date = &quot;12.23.2012&quot;<br>$date= &quot;11.1.2012&quot;<br>$counter = 1<br>while &#40;$counter -le 120&#41;<br>{<br> $date = $date.AddDays&#40;1&#41;<br> if &#40;&#40;$date.DayOfWeek -eq [dayofWeek]::Saturday&#41; -or <br> &#40;$date.DayOfWeek -eq [dayofWeek]::Sunday&#41;&#41; <br> {continue}<br> if &#40;$hash.ContainsKey&#40;&#40;format-date $date&#41;&#41;&#41; <br> {continue}<br> <br> if &#40;1&lt;#for test#&gt;,50,60,110,120 -contains $counter&#41; <br> {format-date $date}<br> $counter++<br>}<br><br>&lt;#<br>test<br>&quot;12.23.2012&quot; +1<br>produced by script<br>02.01.2013<br><br>&quot;1.11.2012&quot; +1<br>2.11.2012<br><br>seems to work<br><br>#&gt;</code></blockquote>by daytime10 at 2012-11-02 12:55:26<blockquote>Thanks for the ideas guys<br><br>Let me try these in my script and see if I can get it functioning, will get back to you<br><br>Thanks again!</blockquote>by daytime10 at 2012-11-12 11:46:59<blockquote>Just wanted to give an update<br><br>This is what I ended up using and got it working. Added a counter function and such<br><br>#Date Calculations<br>#Company Holidays List<br>$holidays = @'<br>25.12.2012 Christmas Day<br>26.12.2012 Boxing Day<br>27.12.2012 Company Holiday<br>28.12.2012 Company Holiday<br>31.12.2012 Shutdown<br>01.01.2013 New Years<br>'@ -split &quot;r”
foreach ($line in $holidays)
$tempDate,$name = $line -split " "
$hash.$tempDate = $name
function format-date ([datetime]$date)
“{0:dd.MM.yyyy}” -f $date

[datetime]$date = $searchdate
#$date= “11.1.2012”
$counter = 1
while ($counter -le 120) #Count 120 Days checking for holidays/weekends
$date = $date.AddDays(1)
if (($date.DayOfWeek -eq [dayofWeek]::Saturday) -or
($date.DayOfWeek -eq [dayofWeek]::Sunday))
$counter = $counter - 1
if ($hash.ContainsKey((format-date $date)))
$counter = $counter - 1

if ($counter -eq 50){
$date50 = $date.AddHours(9) #50th Work Day
#write-host $date50

if ($counter -eq 60){
$date60 = $date.AddHours(9) #60th Work Day
#write-host $date60

if ($counter -eq 110){
$date110 = $date.AddHours(9) #110th Work Day
#write-host $date110

if ($counter -eq 120){
$date120 = $date.AddHours(9) #120th Work Day
#write-host $date120
by nohandle at 2012-11-14 09:32:56
Glad this helped, please mark it as solved by clicking the solved button.