Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 65 additions & 0 deletions examples/General.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,68 @@
.SYNOPSIS
This is a general example of how to use the module.
#>

# Import required functions
. ./src/variables/private/UnitMap.ps1
. ./src/functions/private/Format-UnitValue.ps1
. ./src/functions/public/Format-TimeSpan.ps1
. ./src/functions/public/Get-TimeSpan.ps1

Write-Host "=== TimeSpan Module Examples ===" -ForegroundColor Green

# Example 1: Format existing TimeSpan
Write-Host "`n1. Formatting TimeSpan objects:" -ForegroundColor Yellow
$timespan = New-TimeSpan -Hours 2 -Minutes 30 -Seconds 15
Write-Host "Original TimeSpan: $($timespan.ToString())"
Write-Host "Formatted: $(Format-TimeSpan $timespan)"
Write-Host "Formatted with precision 3: $(Format-TimeSpan $timespan -Precision 3 -FullNames)"

# Example 2: Get TimeSpan using default behavior (returns Zero)
Write-Host "`n2. Default behavior (both Start and End use current time):" -ForegroundColor Yellow
$defaultResult = Get-TimeSpan
Write-Host "Get-TimeSpan with no parameters: $($defaultResult.ToString())"

# Example 3: Get TimeSpan to future event
Write-Host "`n3. Getting TimeSpan to future events:" -ForegroundColor Yellow
$futureEvent = [DateTime]::Now.AddHours(3).AddMinutes(45)
$countdown = Get-TimeSpan -End $futureEvent
Write-Host "Event in future: $($futureEvent.ToString('yyyy-MM-dd HH:mm:ss'))"
Write-Host "Time until event: $($countdown.ToString())"
Write-Host "Formatted countdown: $(Format-TimeSpan $countdown -Precision 2 -FullNames)"

# Example 4: Get TimeSpan between two specific times
Write-Host "`n4. Getting TimeSpan between specific Start and End times:" -ForegroundColor Yellow
$startTime = [DateTime]::Now.AddHours(-2)
$endTime = [DateTime]::Now.AddHours(1)
$duration = Get-TimeSpan -Start $startTime -End $endTime
Write-Host "Start time: $($startTime.ToString('yyyy-MM-dd HH:mm:ss'))"
Write-Host "End time: $($endTime.ToString('yyyy-MM-dd HH:mm:ss'))"
Write-Host "Duration: $($duration.ToString())"
Write-Host "Formatted duration: $(Format-TimeSpan $duration -Precision 2 -FullNames)"

# Example 5: Handling negative values
Write-Host "`n5. Handling negative TimeSpan values:" -ForegroundColor Yellow
$pastDeadline = [DateTime]::Now.AddHours(-2)
$defaultResult = Get-TimeSpan -End $pastDeadline
$stopAtZeroResult = Get-TimeSpan -End $pastDeadline -StopAtZero

Write-Host "Past deadline: $($pastDeadline.ToString('yyyy-MM-dd HH:mm:ss'))"
Write-Host "Default result (allows negative): $($defaultResult.ToString())"
Write-Host "StopAtZero result: $($stopAtZeroResult.ToString())"
Write-Host "Formatted negative: $(Format-TimeSpan $defaultResult -FullNames)"

# Example 6: Pipeline usage
Write-Host "`n6. Pipeline usage:" -ForegroundColor Yellow
$events = @(
[DateTime]::Now.AddMinutes(15),
[DateTime]::Now.AddHours(2),
[DateTime]::Now.AddDays(1)
)

Write-Host "Multiple upcoming events:"
$events | ForEach-Object {
$timeLeft = $_ | Get-TimeSpan
Write-Host " Event at $($_.ToString('HH:mm:ss')): $(Format-TimeSpan $timeLeft -Precision 2)"
}

Write-Host "`n=== Examples Complete ===" -ForegroundColor Green
111 changes: 111 additions & 0 deletions src/functions/public/Get-TimeSpan.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
function Get-TimeSpan {
<#
.SYNOPSIS
Gets a TimeSpan representing the difference between two DateTime values.

.DESCRIPTION
This function calculates the time difference between a Start DateTime and End DateTime.
By default, both Start and End parameters default to the current time ([DateTime]::Now).
If neither Start nor End is provided (both use defaults), the function returns TimeSpan.Zero.
The function allows negative values by default, but can return zero for negative values using the StopAtZero parameter.

.EXAMPLE
$futureTime = [DateTime]::Now.AddMinutes(30)
Get-TimeSpan -End $futureTime

Output:
```powershell
00:30:00
```

Returns a TimeSpan representing 30 minutes until the end time.

.EXAMPLE
$pastTime = [DateTime]::Now.AddMinutes(-30)
Get-TimeSpan -End $pastTime

Output:
```powershell
-00:30:00
```

Returns a negative TimeSpan showing the end time was 30 minutes ago.

.EXAMPLE
$pastTime = [DateTime]::Now.AddMinutes(-30)
Get-TimeSpan -End $pastTime -StopAtZero

Output:
```powershell
00:00:00
```

Returns TimeSpan.Zero since the result would be negative and StopAtZero is specified.

.EXAMPLE
$startTime = [DateTime]::Now.AddHours(-2)
$endTime = [DateTime]::Now
Get-TimeSpan -Start $startTime -End $endTime

Output:
```powershell
02:00:00
```

Returns a positive TimeSpan showing the duration between start and end times.

.EXAMPLE
Get-TimeSpan

Output:
```powershell
00:00:00
```

Returns TimeSpan.Zero when both Start and End use their default values.

.OUTPUTS
System.TimeSpan

.NOTES
The TimeSpan representing the difference between the Start and End DateTime values (End - Start).

.LINK
https://psmodule.io/TimeSpan/Functions/Get-TimeSpan/
#>
[CmdletBinding()]
[OutputType([TimeSpan])]
param(
# The start DateTime. Defaults to current time.
[Parameter(ValueFromPipelineByPropertyName)]
[DateTime] $Start = [DateTime]::Now,

# The end DateTime. Defaults to current time.
[Parameter(ValueFromPipeline, ValueFromPipelineByPropertyName)]
[DateTime] $End = [DateTime]::Now,

# If specified, returns TimeSpan.Zero instead of negative values.
[Parameter()]
[switch] $StopAtZero
)

process {
# Check if both parameters are using their default values
$startIsDefault = $PSBoundParameters.Keys -notcontains 'Start'
$endIsDefault = $PSBoundParameters.Keys -notcontains 'End'

if ($startIsDefault -and $endIsDefault) {
return [TimeSpan]::Zero
}

# Calculate the time difference: End - Start
$timeSpan = $End - $Start

# Handle negative values based on StopAtZero parameter
if ($timeSpan.TotalSeconds -lt 0 -and $StopAtZero) {
return [TimeSpan]::Zero
}

return $timeSpan
}
}
76 changes: 76 additions & 0 deletions tests/PSModuleTest.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,80 @@
}
}
}

Describe 'Get-TimeSpan' {
Context 'Get-TimeSpan - Default Behavior' {
It 'Get-TimeSpan - Returns Zero when both Start and End use defaults' {
$result = Get-TimeSpan
$result | Should -Be ([TimeSpan]::Zero)
}
}

Context 'Get-TimeSpan - Future End DateTime' {
It 'Get-TimeSpan - Returns positive TimeSpan for future end datetime' {
$future = [DateTime]::Now.AddMinutes(30)
$result = Get-TimeSpan -End $future
$result.TotalMinutes | Should -BeGreaterThan 29
$result.TotalMinutes | Should -BeLessThan 31
}
}

Context 'Get-TimeSpan - Past End DateTime' {
It 'Get-TimeSpan - Returns negative TimeSpan for past end datetime by default' {
$past = [DateTime]::Now.AddMinutes(-30)
$result = Get-TimeSpan -End $past
$result.TotalMinutes | Should -BeLessThan -29
$result.TotalMinutes | Should -BeGreaterThan -31
}

It 'Get-TimeSpan - Returns Zero for past end datetime with StopAtZero' {
$past = [DateTime]::Now.AddMinutes(-30)
$result = Get-TimeSpan -End $past -StopAtZero
$result | Should -Be ([TimeSpan]::Zero)
}
}

Context 'Get-TimeSpan - Start and End Parameters' {
It 'Get-TimeSpan - Calculates difference between Start and End' {
$start = [DateTime]::Now.AddHours(-2)
$end = [DateTime]::Now
$result = Get-TimeSpan -Start $start -End $end
$result.TotalHours | Should -BeGreaterThan 1.9
$result.TotalHours | Should -BeLessThan 2.1
}

It 'Get-TimeSpan - Returns negative when End is before Start' {
$start = [DateTime]::Now
$end = [DateTime]::Now.AddHours(-1)
$result = Get-TimeSpan -Start $start -End $end
$result.TotalHours | Should -BeLessThan -0.9
$result.TotalHours | Should -BeGreaterThan -1.1
}

It 'Get-TimeSpan - Returns Zero for negative difference with StopAtZero' {
$start = [DateTime]::Now
$end = [DateTime]::Now.AddHours(-1)
$result = Get-TimeSpan -Start $start -End $end -StopAtZero
$result | Should -Be ([TimeSpan]::Zero)
}
}

Context 'Get-TimeSpan - Pipeline Support' {
It 'Get-TimeSpan - Accepts DateTime from pipeline as End parameter' {
$future = [DateTime]::Now.AddMinutes(15)
$result = $future | Get-TimeSpan
$result.TotalMinutes | Should -BeGreaterThan 14
$result.TotalMinutes | Should -BeLessThan 16
}
}

Context 'Get-TimeSpan - Exact Same Time' {
It 'Get-TimeSpan - Returns near Zero for same Start and End times' {
$time = [DateTime]::Now
$result = Get-TimeSpan -Start $time -End $time
# Should be exactly zero for same time
$result.TotalMilliseconds | Should -Be 0
}
}
}
}
Loading