public/Format-AsISO8601Duration.ps1
Function Format-AsISO8601Duration { <# .SYNOPSIS Formats a time duration to ISO-8601 format .DESCRIPTION Formats a time duration to ISO-8601 format as described in section 'Durations' at https://en.wikipedia.org/wiki/ISO_8601. All parameters for date and time elements may have a decimal fraction eg. 0.5 years to indicate half a year. When using the Optimize parameter to prevent each date and time element to exceed their value, the following definitions are used: 1 year = 12 months 1 Month = 30 days 1 day = 24 hours 1 hour = 60 minutes 1 minute = 60 seconds .EXAMPLE Format-AsISO8601Duration -Years 2 -Months 11 -Days 29 -Hours 23 -Minutes 59 -Seconds 61 -Optimize Format-AsISO8601Duration -Seconds 30 .PARAMETER Years The numbers of years in the duration. .PARAMETER Months The numbers of months in the duration. .PARAMETER Days The numbers of days in the duration. .PARAMETER Hours The numbers of hours in the duration. .PARAMETER Minutes The numbers of minutes in the duration. .PARAMETER Seconds The numbers of seconds in the duration. .PARAMETER Optimize Prevents date and time values in a duration representation from exceeding their "carry over points" eg. transforming 65 seconds to 1 minute and 5 seconds. .INPUTS TO DO .OUTPUTS The duration formatted according to ISO-8601 as in P[n]Y[n]M[n]DT[n]H[n]M[n]S, where n represents the individual date and time elements. .LINK https://github.com/DennisWagner/SQLServerDevOpsTools .NOTES Written by (c) Dennis Wagner Kristensen, 2021 https://github.com/DennisWagner/SQLServerDevOpsTools This PowerShell script is released under the MIT license http://www.opensource.org/licenses/MIT #> [CmdletBinding()] Param ( [Parameter(Mandatory=$false)][decimal]$Years, [Parameter(Mandatory=$false)][decimal]$Months, [Parameter(Mandatory=$false)][decimal]$Days, [Parameter(Mandatory=$false)][decimal]$Hours, [Parameter(Mandatory=$false)][decimal]$Minutes, [Parameter(Mandatory=$false)][decimal]$Seconds, [Parameter(Mandatory=$false)][switch]$Optimize ) BEGIN { If (-not $Years -and -not $Months -and -not $Days -and -not $Hours -and -not $Minutes -and -not $Seconds) { Throw "At least one date/time parameter must be supplied." } If ($Years -lt 0) { Throw "Parameter Years cannot be a negative number." } If ($Months -lt 0) { Throw "Parameter Months cannot be a negative number." } If ($Days -lt 0) { Throw "Parameter Days cannot be a negative number." } If ($Hours -lt 0) { Throw "Parameter Hours cannot be a negative number." } If ($Minutes -lt 0) { Throw "Parameter Minutes cannot be a negative number." } If ($Seconds -lt 0) { Throw "Parameter Seconds cannot be a negative number." } } PROCESS { $YearsOptimized = $Years $MonthsOptimized = $Months $DaysOptimized = $Days $HoursOptimized = $Hours $MinutesOptimized = $Minutes $SecondsOptimized = $Seconds If ($Optimize) { If ($SecondsOptimized -ge 60) { $MinutesOptimized += [Math]::Truncate($SecondsOptimized / 60) $SecondsOptimized %= 60 } If ($MinutesOptimized -ge 60) { $HoursOptimized += [Math]::Truncate($MinutesOptimized / 60) $MinutesOptimized %= 60 } If ($HoursOptimized -ge 24) { $DaysOptimized += [Math]::Truncate($HoursOptimized / 24) $HoursOptimized %= 24 } If ($DaysOptimized -ge 30) { $MonthsOptimized += [Math]::Truncate($DaysOptimized / 30) $DaysOptimized %= 30 } If ($MonthsOptimized -ge 12) { $YearsOptimized += [Math]::Truncate($MonthsOptimized / 12) $MonthsOptimized %= 12 } } $ISO8601Str = "P" If ($YearsOptimized -gt 0) { $ISO8601Str += "$($YearsOptimized)Y" } If ($MonthsOptimized -gt 0) { $ISO8601Str += "$($MonthsOptimized)M" } If ($DaysOptimized -gt 0) { $ISO8601Str += "$($DaysOptimized)D" } If ($HoursOptimized -gt 0 -or $MinutesOptimized -gt 0 -or $SecondsOptimized -gt 0) { $ISO8601Str += "T" If ($HoursOptimized -gt 0) { $ISO8601Str += "$($HoursOptimized)H" } If ($MinutesOptimized -gt 0) { $ISO8601Str += "$($MinutesOptimized)M" } If ($SecondsOptimized -gt 0) { $ISO8601Str += "$($SecondsOptimized)S" } } } END { Write-Output $ISO8601Str } } |