Friday, January 14, 2011

Replicate UNIX 'cal' in PowerShell

This is a good exercise in using dates in a loop. This code replicates somewhat the functionality of the command line application 'cal' that first appeared in Version 5 AT&T UNIX. In the code, you will perform while loops based on months and days. Save the code in a file called 'Output-Calendar.ps1'. If you provide no parameters, it will display a calendar of the current month. If you provide a valid date as a parameter, it will display that month's calendar. If you provide two months, it will generate all the calendars between those two dates. It does not validate if the input are valid dates and assumes the culture is English.

Examples:

.\Output-Calendar.ps1
.\Output-Calendar.ps1 1/2000
.\Output-Calendar.ps1 1/1/2010 12/31/2010
param([string]$start,[string]$end)

Function Get-LastDayOfMonth($date) {
 return ((Get-Date ((((Get-Date $date).AddMonths(1)).Month).ToString() + "/1/" + (((Get-Date $date).AddMonths(1)).Year).ToString()))) - (New-TimeSpan -seconds 1)
}

Set-Variable -name dayOfWeekLine -option Constant -value " Su Mo Tu We Th Fr Sa "
if($start -eq "" -and $end -eq "") {
 $startDate = Get-Date
 $endDate = Get-Date
} elseif($end -eq "") {
 $startDate = Get-Date $start
 $endDate = Get-Date $start
} else {
 $startDate = Get-Date $start
 $endDate = Get-Date $end 
}
if($startDate -gt $endDate) {
 Write-Warning "The Start Date must be earlier than the End Date"
 exit
}
$month = $startDate
Write-Host ""
while($month -le $endDate) {
 $firstDayOfMonth = Get-Date ((((Get-Date $month).Month).ToString() + "/1/" + ((Get-Date $month).Year).ToString() + " 00:00:00"))
 $lastDayOfMonth = Get-LastDayOfMonth $firstDayOfMonth
 $day = $firstDayOfMonth
 $headline = ((Get-Date $firstDayOfMonth -Format MMMM) + " " + $firstDayOfMonth.Year)
 Write-Host (" " * (($dayOfWeekLine.Length - $headline.Length) / 2)) -noNewline
 Write-Host $headline
 Write-Host $dayOfWeekLine
 while($day -le $lastDayOfMonth) {
  if($day.day -eq 1 -and $day.DayOfWeek -ne "Sunday") {
   Write-Host " " -noNewline
   if($day.DayOfWeek -eq "Saturday") {
    Write-Host (" " * 15) -noNewline
   } elseif($day.DayOfWeek -eq "Friday") {
    Write-Host (" " * 12) -noNewline
   } elseif($day.DayOfWeek -eq "Thursday") {
    Write-Host (" " * 9) -noNewline
   } elseif($day.DayOfWeek -eq "Wednesday") {
    Write-Host (" " * 6) -noNewline
   } elseif($day.DayOfWeek -eq "Tuesday") {
    Write-Host (" " * 3) -noNewline
   }
  }
  if($day.DayOfWeek -eq "Saturday") {
   Write-Host (" " + (Get-Date $day -Format dd))
  } else {
   Write-Host (" " + (Get-Date $day -Format dd)) -noNewline
  }
  $day = $day.AddDays(1)
 }
 if($day.DayOfWeek -ne "Sunday") {
  Write-Host ""
 }
 Write-Host ""
 $month = $firstDayOfMonth.AddMonths(1)
}

No comments:

Post a Comment