IsoDates.psm1 (modification of post by view diff)
embed code: <script type="text/javascript" src="http://PoshCode.org/embed/966"></script>download | new post
A handful of functions for returning IS0-8601 formatted dates and parsing them. All functions work (even in the pipeline) in both PowerShell 1 and 2.
- #requires -version 1.0
- # or version 2.0, obviously
- ## ISO 8601 Dates
- ########################################################################
- ## Copyright (c) Joel Bennett, 2009
- ## Free for use under GPL, MS-RL, MS-PL, or BSD license. Your choice.
- function Get-ISODate {
- #.Synopsis
- # Get the components of an ISO 8601 date: year, week number, day of week
- #.Description
- # For any given date you get an array of year, week, day that you can use
- # as part of a string format....
- #.Parameter Date
- # The date you want to analyze. Accepts dates on the pipeline
- Param([DateTime]$date=$(Get-Date))
- Process {
- if($_){$date=$_}
- ## Get Jan 1st of that year
- $startYear = Get-Date -Date $date -Month 1 -Day 1
- ## Get Dec 31st of that year
- $endYear = Get-Date -Date $date -Month 12 -Day 31
- ## ISO 8601 weeks are Monday-Sunday, with days marked 1-7
- ## But .Net's DayOfWeek enum is 0 for Sunday through 6 for saturday
- $dayOfWeek = @(7,1,2,3,4,5,6)[$date.DayOfWeek]
- $lastofWeek = @(7,1,2,3,4,5,6)[$endYear.DayOfWeek]
- ## By definition: the first week of a year is the one which
- ## includes the first Thursday, and thus, January 4th
- $adjust = @(6,7,8,9,10,4,5)[$startYear.DayOfWeek]
- switch([Math]::Floor((($date.Subtract($startYear).Days + $adjust)/7)))
- {
- 0 {
- ## Return weeknumber of dec 31st of the previous year
- ## But return THIS dayOfWeek
- Write-Output @(
- @(Get-ISODate $startYear.AddDays(-1))[0,1] + @(,$dayOfWeek))
- }
- 53 {
- ## If dec 31st falls before thursday it is week 01 of next year
- if ($lastofWeek -lt 4) {
- Write-Output @(($date.Year + 1), 1, $dayOfWeek)
- } else {
- Write-Output @($date.Year, $_, $dayOfWeek)
- }
- }
- default {
- Write-Output @($date.Year, $_, $dayOfWeek)
- }
- }
- }
- }
- function Get-ISOWeekOfYear {
- #.Synopsis
- # Get the correct (according to ISO 8601) week number
- #.Description
- # For any given date you get the week of the year, according to ISO8610
- #.Parameter Date
- # The date you want to analyze. Accepts dates on the pipeline
- Param([DateTime]$date=$(Get-Date))
- Process {
- if($_){$date=$_}
- @(Get-ISODate $date)[1]
- }
- }
- function Get-ISOYear {
- #.Synopsis
- # Get the correct (according to ISO 8601) year number
- #.Description
- # For any given date you get the year number, according to ISO8610 ...
- # for some days at the begining or end of year, it reports the previous
- # or the next year (because ISO defines those days as part of the first
- # or last week of the adjacent year).
- #.Parameter Date
- # The date you want to analyze. Accepts dates on the pipeline
- Param([DateTime]$date=$(Get-Date))
- Process {
- if($_){$date=$_}
- @(Get-ISODate $date)[0]
- }
- }
- function Get-ISODayOfWeek {
- #.Synopsis
- # Get the correct (according to ISO 8601) day of the week
- #.Description
- # For any given date you get the day of the week, according to ISO8610
- #.Parameter Date
- # The date you want to analyze. Accepts dates on the pipeline
- Param([DateTime]$date=$(Get-Date))
- Process {
- if($_){$date=$_}
- @(7,1,2,3,4,5,6)[$date.DayOfWeek]
- }
- }
- function Get-ISODateString {
- #.Synopsis
- # Get the correctly formatted (according to ISO 8601) date string
- #.Description
- # For any given date you get the date string, according to ISO8610,
- # like: 2009-W12-4 for Thursday, March 19th, 2009
- #.Parameter Date
- # The date you want to analyze. Accepts dates on the pipeline
- Param([DateTime]$date=$(Get-Date))
- Process {
- if($_){$date=$_}
- "{0}-W{1:00}-{2}" -f @(Get-ISODate $date)
- }
- }
- function ConvertFrom-ISODateString {
- #.Synopsis
- # Parses ISO 8601 Date strings in the format: 2009-W12-4 to DateTime
- #.Description
- # Allows converting ISO-formated date strings back into actual objects
- #.Parameter Date
- # An ISO8601 date, like:
- # 2009-W12-4 for Thursday, March 19th, 2009
- # 1999-W52-6 for Saturday, January 1st, 2000
- # 2000-W01-1 for Monday, January 3rd, 2000
- Param([string]$date)
- Process {
- if($_){$date=$_}
- if($date -notmatch "\d{4}-W\d{2}-\d") {
- Write-Error "The string is not an ISO 8601 formatted date string"
- }
- $ofs = ""
- $year = [int]"$($date[0..3])"
- $week = [int]"$($date[6..7])"
- $day = [int]"$($date[9])"
- $firstOfYear = Get-Date -year $year -day 1 -month 1
- $days = 7*$week - ((Get-ISODayOfWeek $firstOfYear) - $day)
- $result = $firstOfYear.AddDays( $days )
- if(($result.Year -ge $year) -and ((Get-ISODayOfWeek $firstOfYear) -le 4) ) {
- return $firstOfYear.AddDays( ($days - 7) )
- } else {
- return $result
- }
- }
- }
Submit a correction or amendment below (click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.
PowerShell Code Repository