diff --git a/src/functions/private/Format-UnitValue.ps1 b/src/functions/private/Format-UnitValue.ps1 index 8144c57..eebdb48 100644 --- a/src/functions/private/Format-UnitValue.ps1 +++ b/src/functions/private/Format-UnitValue.ps1 @@ -5,44 +5,53 @@ .DESCRIPTION This function takes an integer value and a unit and returns a formatted string. - If the -FullNames switch is specified, the function uses the singular or plural full unit name. - Otherwise, it returns the value with the unit abbreviation. + The format can be specified as Symbol, Abbreviation, or FullName. .EXAMPLE - Format-UnitValue -Value 5 -Unit 'meter' + Format-UnitValue -Value 5 -Unit 'Hours' -Format Symbol Output: ```powershell - 5m + 5h + ``` + + Returns the formatted value with its symbol. + + .EXAMPLE + Format-UnitValue -Value 5 -Unit 'Hours' -Format Abbreviation + + Output: + ```powershell + 5hr ``` Returns the formatted value with its abbreviation. .EXAMPLE - Format-UnitValue -Value 1 -Unit 'meter' -FullNames + Format-UnitValue -Value 1 -Unit 'Hours' -Format FullName Output: ```powershell - 1 meter + 1 hour ``` Returns the formatted value with the full singular unit name. .EXAMPLE - Format-UnitValue -Value 2 -Unit 'meter' -FullNames + Format-UnitValue -Value 2 -Unit 'Hours' -Format FullName Output: ```powershell - 2 meters + 2 hours ``` Returns the formatted value with the full plural unit name. .OUTPUTS - string. A formatted string combining the value and its corresponding unit abbreviation or full name. + string. A formatted string combining the value and its corresponding unit in the specified format. .LINK - https://psmodule.io/Format/Functions/Format-UnitValue/ + https://psmodule.io/TimeSpan/Functions/Format-UnitValue/ #> [OutputType([string])] [CmdletBinding()] @@ -55,16 +64,23 @@ [Parameter(Mandatory)] [string] $Unit, - # Switch to use full unit names instead of abbreviations. + # The format for displaying the unit. [Parameter()] - [switch] $FullNames + [ValidateSet('Symbol', 'Abbreviation', 'FullName')] + [string] $Format = 'Symbol' ) - if ($FullNames) { - # Choose singular or plural form based on the value. - $unitName = if ($Value -eq 1) { $script:UnitMap[$Unit].Singular } else { $script:UnitMap[$Unit].Plural } - return "$Value $unitName" + switch ($Format) { + 'FullName' { + # Choose singular or plural form based on the value. + $unitName = if ($Value -eq 1) { $script:UnitMap[$Unit].Singular } else { $script:UnitMap[$Unit].Plural } + return "$Value $unitName" + } + 'Abbreviation' { + return "$Value$($script:UnitMap[$Unit].Abbreviation)" + } + 'Symbol' { + return "$Value$($script:UnitMap[$Unit].Symbol)" + } } - - "$Value$($script:UnitMap[$Unit].Abbreviation)" } diff --git a/src/functions/public/Format-TimeSpan.ps1 b/src/functions/public/Format-TimeSpan.ps1 index 92975e4..da88b47 100644 --- a/src/functions/public/Format-TimeSpan.ps1 +++ b/src/functions/public/Format-TimeSpan.ps1 @@ -5,7 +5,7 @@ .DESCRIPTION This function converts a TimeSpan object into a formatted string based on a chosen unit or precision. - It allows specifying a base unit, the number of precision levels, and whether to use full unit names. + It allows specifying a base unit, the number of precision levels, and the format for displaying units. If the TimeSpan is negative, it is prefixed with a minus sign. .EXAMPLE @@ -16,27 +16,29 @@ 2h ``` - Formats the given TimeSpan into a human-readable format using the most significant unit. + Formats the given TimeSpan into a human-readable format using the most significant unit with symbols (default). .EXAMPLE - [TimeSpan]::FromSeconds(3661) | Format-TimeSpan -Precision 2 -FullNames + New-TimeSpan -Minutes 90 | Format-TimeSpan -Format Abbreviation Output: ```powershell - 1 hour 1 minute + 2hr ``` - Returns the TimeSpan formatted into multiple components based on the specified precision. + Formats the given TimeSpan using abbreviations instead of symbols. .EXAMPLE - [TimeSpan]::FromMilliseconds(500) | Format-TimeSpan -Precision 2 -FullNames + [TimeSpan]::FromSeconds(3661) | Format-TimeSpan -Precision 2 -Format FullName Output: ```powershell - 500 milliseconds 0 microseconds + 1 hour 1 minute ``` - Forces the output to be formatted in milliseconds, regardless of precision. + Returns the TimeSpan formatted into multiple components using full unit names. + + .OUTPUTS System.String @@ -61,9 +63,10 @@ [Parameter()] [string] $BaseUnit, - # If specified, outputs full unit names instead of abbreviations. + # Specifies the format for displaying time units. [Parameter()] - [switch] $FullNames + [ValidateSet('Symbol', 'Abbreviation', 'FullName')] + [string] $Format = 'Symbol' ) process { @@ -74,7 +77,10 @@ $originalTicks = $TimeSpan.Ticks # Ordered list of units from most to least significant. - $orderedUnits = @($script:UnitMap.Keys) + $orderedUnits = [System.Collections.ArrayList]::new() + foreach ($key in $script:UnitMap.Keys) { + $null = $orderedUnits.Add($key) + } if ($Precision -eq 1) { # For precision=1, use the "fractional" approach. @@ -93,7 +99,7 @@ $fractionalValue = $originalTicks / $script:UnitMap[$chosenUnit].Ticks $roundedValue = [math]::Round($fractionalValue, 0, [System.MidpointRounding]::AwayFromZero) - $formatted = Format-UnitValue -value $roundedValue -unit $chosenUnit -FullNames:$FullNames + $formatted = Format-UnitValue -Value $roundedValue -Unit $chosenUnit -Format $Format if ($isNegative) { $formatted = "-$formatted" } return $formatted } else { @@ -122,7 +128,7 @@ $value = [math]::Floor($remainder / $unitTicks) } $remainder = $remainder - ($value * $unitTicks) - $resultSegments += Format-UnitValue -value $value -unit $unit -FullNames:$FullNames + $resultSegments += Format-UnitValue -Value $value -Unit $unit -Format $Format } $formatted = $resultSegments -join ' ' if ($isNegative) { $formatted = "-$formatted" } diff --git a/src/variables/private/UnitMap.ps1 b/src/variables/private/UnitMap.ps1 index 1104bb0..34a4e05 100644 --- a/src/variables/private/UnitMap.ps1 +++ b/src/variables/private/UnitMap.ps1 @@ -7,73 +7,85 @@ $script:UnitMap = [ordered]@{ 'Millennia' = @{ Singular = 'millennium' Plural = 'millennia' - Abbreviation = 'mil' + Abbreviation = 'mill' + Symbol = 'kyr' Ticks = [System.TimeSpan]::TicksPerDay * $script:AverageDaysInYear * 1000 } 'Centuries' = @{ Singular = 'century' Plural = 'centuries' Abbreviation = 'cent' + Symbol = 'c' Ticks = [System.TimeSpan]::TicksPerDay * $script:AverageDaysInYear * 100 } 'Decades' = @{ Singular = 'decade' Plural = 'decades' Abbreviation = 'dec' + Symbol = 'dec' Ticks = [System.TimeSpan]::TicksPerDay * $script:AverageDaysInYear * 10 } 'Years' = @{ Singular = 'year' Plural = 'years' - Abbreviation = 'y' + Abbreviation = 'yr' + Symbol = 'y' Ticks = [System.TimeSpan]::TicksPerDay * $script:AverageDaysInYear } 'Months' = @{ Singular = 'month' Plural = 'months' - Abbreviation = 'mo' + Abbreviation = 'mon' + Symbol = 'mo' Ticks = [System.TimeSpan]::TicksPerDay * $script:AverageDaysInMonth } 'Weeks' = @{ Singular = 'week' Plural = 'weeks' - Abbreviation = 'w' + Abbreviation = 'wk' + Symbol = 'wk' Ticks = [System.TimeSpan]::TicksPerDay * $script:DaysInWeek } 'Days' = @{ Singular = 'day' Plural = 'days' - Abbreviation = 'd' + Abbreviation = 'day' + Symbol = 'd' Ticks = [System.TimeSpan]::TicksPerDay } 'Hours' = @{ Singular = 'hour' Plural = 'hours' - Abbreviation = 'h' + Abbreviation = 'hr' + Symbol = 'h' Ticks = [System.TimeSpan]::TicksPerHour } 'Minutes' = @{ Singular = 'minute' Plural = 'minutes' Abbreviation = 'min' + Symbol = 'm' Ticks = [System.TimeSpan]::TicksPerMinute } 'Seconds' = @{ Singular = 'second' Plural = 'seconds' - Abbreviation = 's' + Abbreviation = 'sec' + Symbol = 's' Ticks = [System.TimeSpan]::TicksPerSecond } 'Milliseconds' = @{ Singular = 'millisecond' Plural = 'milliseconds' - Abbreviation = 'ms' + Abbreviation = 'msec' + Symbol = 'ms' Ticks = [System.TimeSpan]::TicksPerMillisecond } 'Microseconds' = @{ Singular = 'microsecond' Plural = 'microseconds' - Abbreviation = "$([char]0x00B5)s" + Abbreviation = 'µsec' + Symbol = "µs" Ticks = 10 } } diff --git a/tests/PSModuleTest.Tests.ps1 b/tests/PSModuleTest.Tests.ps1 index 0b49355..5ea51af 100644 --- a/tests/PSModuleTest.Tests.ps1 +++ b/tests/PSModuleTest.Tests.ps1 @@ -1,7 +1,9 @@ -Describe 'TimeSpan' { + + +Describe 'TimeSpan' { Describe 'Format-TimeSpan' { Context 'Format-TimeSpan - Basic Usage' { - It 'Format-TimeSpan - Formats 90 minutes as 2h' { + It 'Format-TimeSpan - Formats 90 minutes as 2h (default symbols)' { $result = New-TimeSpan -Minutes 90 | Format-TimeSpan $result | Should -Be '2h' } @@ -9,14 +11,14 @@ Context 'Format-TimeSpan - Precision and FullNames' { It 'Format-TimeSpan - Formats 3661 seconds with precision 2 and full names' { - $result = [TimeSpan]::FromSeconds(3661) | Format-TimeSpan -Precision 2 -FullNames + $result = [TimeSpan]::FromSeconds(3661) | Format-TimeSpan -Precision 2 -Format FullName $result | Should -Be '1 hour 1 minute' } } Context 'Format-TimeSpan - Smallest Unit Handling' { It 'Format-TimeSpan - Formats 500 milliseconds with precision 2 and full names' { - $result = [TimeSpan]::FromMilliseconds(500) | Format-TimeSpan -Precision 2 -FullNames + $result = [TimeSpan]::FromMilliseconds(500) | Format-TimeSpan -Precision 2 -Format FullName $result | Should -Be '500 milliseconds 0 microseconds' } } @@ -24,7 +26,7 @@ Context 'Format-TimeSpan - Negative TimeSpan' { It 'Format-TimeSpan - Formats negative 5 minutes correctly' { $result = New-TimeSpan -Minutes -5 | Format-TimeSpan - $result | Should -Be '-5min' + $result | Should -Be '-5m' } } @@ -35,14 +37,56 @@ } # Test micro seconds It 'Format-TimeSpan - Forces formatting in microseconds' { - $result = [TimeSpan]::FromMilliseconds(1) | Format-TimeSpan -BaseUnit 'Microseconds' -FullNames + $result = [TimeSpan]::FromMilliseconds(1) | Format-TimeSpan -BaseUnit 'Microseconds' -Format FullName $result | Should -Be '1000 microseconds' } - # Test microsecond abbreviation - It 'Format-TimeSpan - Forces formatting in microseconds with abbreviation' { - $result = [TimeSpan]::FromMilliseconds(1) | Format-TimeSpan -BaseUnit 'Microseconds' + # Test microsecond symbol + It 'Format-TimeSpan - Forces formatting in microseconds with symbol' { + $result = [TimeSpan]::FromMilliseconds(1) | Format-TimeSpan -BaseUnit 'Microseconds' -Format Symbol + $result | Should -Be "1000$([char]0x00B5)s" + } + } + + Context 'Format-TimeSpan - Format Parameter' { + It 'Format-TimeSpan - Formats 90 minutes using symbols (default)' { + $result = New-TimeSpan -Minutes 90 | Format-TimeSpan -Format Symbol + $result | Should -Be '2h' + } + It 'Format-TimeSpan - Formats 90 minutes using abbreviations' { + $result = New-TimeSpan -Minutes 90 | Format-TimeSpan -Format Abbreviation + $result | Should -Be '2hr' + } + It 'Format-TimeSpan - Formats 5 minutes using symbols' { + $result = New-TimeSpan -Minutes 5 | Format-TimeSpan -Format Symbol + $result | Should -Be '5m' + } + It 'Format-TimeSpan - Formats seconds using symbols' { + $result = [TimeSpan]::FromMinutes(2) | Format-TimeSpan -BaseUnit 'Seconds' -Format Symbol + $result | Should -Be '120s' + } + It 'Format-TimeSpan - Formats microseconds using symbols' { + $result = [TimeSpan]::FromMilliseconds(1) | Format-TimeSpan -BaseUnit 'Microseconds' -Format Symbol $result | Should -Be '1000µs' } + It 'Format-TimeSpan - Formats negative 5 minutes using symbols' { + $result = New-TimeSpan -Minutes -5 | Format-TimeSpan -Format Symbol + $result | Should -Be '-5m' + } + + It 'Format-TimeSpan - Formats days using symbols' { + $result = New-TimeSpan -Days 3 | Format-TimeSpan -Format Symbol + $result | Should -Be '3d' + } + + It 'Format-TimeSpan - Formats weeks using symbols' { + $result = New-TimeSpan -Days 14 | Format-TimeSpan -Format Symbol + $result | Should -Be '2wk' + } + + It 'Format-TimeSpan - Formats milliseconds using symbols' { + $result = [TimeSpan]::FromMilliseconds(500) | Format-TimeSpan -Format Symbol + $result | Should -Be '500ms' + } } } }