Sunday, February 24, 2008

2008 Scripting Games, Solution 4

# Advanced Event 4: Image is Everything
# http://www.microsoft.com/technet/scriptcenter/funzone/games/games08/aevent4.mspx

# Being non-native English speaking, I wanted to turn this
# into a generic calendar, that could be used anywhere
# Consequently, I created a function that by default uses
# the default culture and then specified en-US when calling
# it to comply with event rules

function Show-Calendar {
param($startDate=(Get-Date),$Culture)

if ($Culture) {
# Use supplied culture
$culture=[globalization.cultureinfo] $Culture
}
else {
# Use default culture
$culture=Get-Culture
}

# Get first day of week, the calender must be show correct
# e.g. in US Sunday is the first day of week, in Denmark Monday is the first
$firstDayOfWeek=$culture.DateTimeFormat.FirstDayofWeek
# Get the weekdays
$weekdays=$culture.DateTimeFormat.ShortestDayNames
# Calculate the width or the weekdays to right-adjust values
$width=($weekdays | measure-object -maximum length).maximum

# If first day of week is not 0, shift the order
if ([int]$FirstDayOfWeek) {
$ShiftedWeekdays=$weekdays[$FirstDayOfWeek..($WeekDays.count)] + $weekdays[0..($FirstDayOfWeek-1)]
}
else {
$ShiftedWeekdays=$weekdays
}

$StartDate=[datetime]$startDate
# Make sure we start the first day in the month
$StartDate=New-Object datetime $StartDate.year,$StartDate.month,1

# Working date
$Date=$StartDate

# Header
$Date.ToString($culture.DateTimeFormat.YearMonthPattern,$culture)

# Process scriptblock and pipe output to Format-Table
&{
while ($date.Month -eq $StartDate.Month) {
# Week-break code
if ([int]$date.DayOfWeek -eq $firstDayOfWeek -and $week) {
$week
$week=$null
}
# Create week object with days as properties
if (!$week) {
$week=New-Object Object
$ShiftedWeekdays | % {
Add-Member -inputObject $week NoteProperty $_ $null
}
}
# Get the day e.g. the property name
$dayOfWeek=$Weekdays[$date.DayOfWeek]
# Assign value to property
$week.$dayOfWeek="{0,$width}" -f $date.day # Right adjust values
# Values must be right-aligned as the days will $null-values will
# set off Format-Table left-aligning those columns

# Next day
$date=$date.AddDays(1)
}
if ($week) {
# Print out final week, if any
$week
}
} | Format-Table -autosize # Pick up the alias properties and format it

}

# Prompt user
$month=read-host "Enter month in month/year format"
# Split into month and year
$month,$year=$month.split("/")
# And call function with en-us culture
Show-Calendar (New-Object Datetime $year,$month,1) "en-us"

No comments: