1

I am referencing a list which has a lot of data in the form of the elapsed time of a process and I'm trying to convert it to a format where I can find the average amount of elapsed time.

The data looks something like this:

ElapsedTime
0 hours, 1 minutes, 14 seconds
0 hours, 16 minutes, 2 seconds
0 hours, 4 minutes, 0 seconds
0 hours, 11 minutes, 59 seconds

So I have the above data Imported into a variable and extract the numerical data using this formula:

$ElapsedHours, $ElapsedMinutes, $ElapsedSeconds = $TimeElapsed -split ', ' -split ' ' | Select -Index 0,2,4

From there I assign the values to a variable and an instance of New-TimeSpan:

$ElapsedTimeSpanObject = New-TimeSpan -Hours $ElapsedHours -Minutes $ElapsedMinutes -Seconds -$ElapsedSeconds

This is the part that gets tricky for me. The two above examples of code are all taking place within a Foreach loop and I've already created a blank array. After the timespan object is created, it is inserted into the array and looks at the next ElapsedTime value.

I want to find the average of the total array.

When I execute the current code I have for trying to find the Average I get an error. Here is the code I'm using:

$ElapsedTimespanCollection | Measure-Object -Average

Executing the above code gives me this error for each object in the array:

Measure-Object : Input object "00:02:44" is not numeric. At line:1 char:30 + $ElapsedTimespanCollection | Measure-Object -Average + ~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidType: (00:02:44:TimeSpan) [Measure-Object], PSInvalidOperationException + FullyQualifiedErrorId : NonNumericInputObject,Microsoft.PowerShell.Commands.MeasureObjectCommand

So how do I go about converting or formatting these measurements of time into something I can check against for their average?

  • Are you showing all of the times in the array that you want? I'm just confused where the input 00:02:44 comes from. – DrZoo Jul 3 '18 at 20:44
  • The 00:02:44 comes from an example of the type of error messages I am getting with the above code. I don't have that particular snippet in the ElapsedTime data but you get the picture. The ElapsedTime data is an example of the data I am working with. – cyborgcommando0 Jul 3 '18 at 20:59
3

You can use TimeSpan to convert the data to a valid time type and then use the .TotalSeconds property to convert the hh:mm:ss string to a time format you can then get numeric total seconds, etc. There are additional methods and properties you should be able to utilize here to help.

$ElapsedHours, $ElapsedMinutes, $ElapsedSeconds = $TimeElapsed -split ', ' -split ' ' | Select -Index 0,2,4
$ElapsedTimeSpanObject = New-TimeSpan -Hours $ElapsedHours -Minutes $ElapsedMinutes -Seconds -$ElapsedSeconds

## -- $ElapsedTimespanCollection = "00:02:44"
$ElapsedTimespanCollection = [TimeSpan]$ElapsedTimespanCollection 
$ElapsedTime.TotalSeconds

Further Resources

  • TimeSpan Structure

    Properties

    • Seconds: Gets the seconds component of the time interval represented by the current TimeSpan structure.

    Methods

    • Duration(): Returns a new TimeSpan object whose value is the absolute value of the current TimeSpan object.
  • cyborgcommando0 - You are obviously going to have to calculate the sum of the seconds, then divide that by the number of objects in the set to get the average seconds, and then convert that back to a duration. For your immediately problem, I showed example of how to convert from string 00:00:00 to a time type to then be able to convert to other numeric data type and such. Happy to help further if you ask, so let me know. – Pimp Juice IT Jul 3 '18 at 21:25
  • I've never used Measure-Object -Average with an array of hh:mm:ss strings or time duration for that matter but you may already know how to get Measure-Object -Average to bring back an average for the array set or whatever. I have to step away but will check in later. – Pimp Juice IT Jul 3 '18 at 21:27
  • 1
    You got me on the right track. For some reason I was thinking the TotalSeconds method was only Seconds and not minutes or hours and I'm going to blame my script for poisoning my mind. I changed the code inserting each TimeSpan Object to this: $ElapsedTimespanCollection += $ElapsedTimeSpanObject.TotalSeconds Then I just did the below code and it gives me what I need. $FindElapsedTimeSpanAverage = ($ElapsedTimespanCollection | Measure-Object -Average).Average $ElapsedTimeSpanAverageObject = New-TimeSpan -Seconds $FindElapsedTimeSpanAverage Thanks – cyborgcommando0 Jul 3 '18 at 22:04
0

This script uses a RegEx with (capture groups) to extract hours, minuts and seconds from an inline csv with a here string. It creates a PSCustomObject from all the time data

## Q:\Test\2018\07\03\SU_1336282.ps1
$TimeLapsed = @"
ElapsedTime
0 hours, 1 minutes, 14 seconds
0 hours, 16 minutes, 2 seconds
0 hours, 4 minutes, 0 seconds
0 hours, 11 minutes, 59 seconds
"@ | ConvertFrom-Csv -Delimiter '|'

$Elapsed = ForEach($row in $TimeLapsed) {
    if ($row -match '(?<HH>\d+) hours, (?<mm>\d+) minutes, (?<ss>\d+) seconds'){
        $TotalSecs = (3600 * $Matches.HH) +
                     (  60 * $Matches.mm) +
                        [int]$Matches.ss
        [PSCustomObject]@{
            Hour     = [int]$Matches.HH
            Minute   = [int]$Matches.mm
            Seconds  = [int]$Matches.ss
            TotalSecs= $TotalSecs
        }
    }
}
$Elapsed
$Elapsed | Measure TotalSecs -Average -Sum -MAx -Min|ft *

Sample output:

> .\SU_1336282.ps1

Hour Minute Seconds TotalSecs
---- ------ ------- ---------
   0      1      14        74
   0     16       2       962
   0      4       0       240
   0     11      59       719



Count Average  Sum Maximum Minimum Property
----- -------  --- ------- ------- --------
    4  498,75 1995     962      74 TotalSecs

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.