I'd like to calculate the time my script runs, but my result from get-date is in totalseconds.
How can I convert this to 31:14:12 behing hours:minutes:seconds?
PS> $ts = New-TimeSpan -Seconds 1234567
PS> '{0:00}:{1:00}:{2:00}' -f $ts.Hours,$ts.Minutes,$ts.Seconds
06:56:07
or
PS> "$ts" -replace '^\d+?\.'
06:56:07
All you have to do is use the Measure-Command cmdlet to get the time:
PS > measure-command { sleep 5}
Days : 0
Hours : 0
Minutes : 0
Seconds : 5
Milliseconds : 13
Ticks : 50137481
TotalDays : 5.80294918981481E-05
TotalHours : 0.00139270780555556
TotalMinutes : 0.0835624683333333
TotalSeconds : 5.0137481
TotalMilliseconds : 5013.7481
The above output itself might be good enough for you, or you can format it appropriately as the the output of Measure-Command is a TimeSpan object. Or you can use ToString:
PS > (measure-command { sleep 125}).tostring()
00:02:05.0017446
Related
Im new to powershell and Ive been trying to convert this string to a timespan object:
"2 Days 1 Hour 15 Minutes"
Ive tried several ways to input the format using parseexact but I cant seem to get the right format down.
Ive tried something like this :
[TimeSpan]::ParseExact('2 Days 1 Hour 15 Minutes', 'd \Days h \Hour MM \Minutes', $null)
The TimeSpan parser is very sensitive, you need to escape everything that isn't a format string specifier:
[TimeSpan]::ParseExact('2 Days 1 Hour 15 Minutes', '%d\ \D\a\y\s\ %h\ \H\o\u\r\ %m\ \M\i\n\u\t\e\s', $null)
(I used the percent-sign notation for the specifiers (%d instead of d) to make them stand out in amongst all the \'s, but they're not required)
The string version normally looks like this: '2.01:15:00', so [timespan]'2.01:15' works.
I am glad to see you have an answer. Another way would be to use named captures in a regex.
PS C:\> '2 Days 1 Hour 15 Minutes' -match '^(?<Days>\d+)\D*(?<Hours>\d+)\D*(?<Minutes>\d+)\D*'
True
PS C:\> $matches
Name Value
---- -----
Hours 1
Minutes 15
Days 2
0 2 Days 1 Hour 15 Minutes
PS C:\> $Matches.Days
2
PS C:\> $Matches.Hours
1
PS C:\> $Matches.Minutes
15
PS C:\> $Ts = New-TimeSpan -days $Matches.Days -Hours $Matches.Hours -Minutes $Matches.Minutes
PS C:\> $Ts
Days : 2
Hours : 1
Minutes : 15
Seconds : 0
Milliseconds : 0
Ticks : 1773000000000
TotalDays : 2.05208333333333
TotalHours : 49.25
TotalMinutes : 2955
TotalSeconds : 177300
TotalMilliseconds : 177300000
I have a huge array which contains dates. The date has the following form: tt.mm.yyyy. I know how to sort the array with Sort-Object, but the sorting takes a lot of time. I found another way of sorting arrays, but it doesn't work as expected.
My former code to sort the array was like this.
$data | Sort-Object { [System.DateTime]::ParseExact($_, "dd.MM.yyyy", $null) }
But as I siad before: this way of sorting is too slow. The Sort() method from System.Array seems to be much faster.
[Array]::Sort([array]$array)
This code sorts an array containing strings much faster than Sort-Object. Is there a way how I can change the above sorting method like the Sort-Object method?
The .NET method will work for dates if you make sure that the array is of type DateTime.
Meaning you should use
[DateTime[]]$dateArray
instead of
[Array]$dateArray
when you create it. Then you can use
[Array]::Sort($dateArray)
to perform the sort it self...
Your input data are date strings with a date format that doesn't allow sorting in "date" order. You must convert the strings either to actual dates
Get-Date $_
[DateTime]::ParseExact($_, "dd.MM.yyyy", $null)
or change the format of the string dates to ISO format, which does allow sorting in date order.
'{2}-{1}-{0}' -f ($_ -split '.')
'{0}-{1}-{2}' -f $_.Substring(6,4), $_.Substring(3,2), $_.Substring(0,2)
$_ -replace '(\d+)\.(\d+).(\d+)', '$3-$2-$1'
At some point you must do one of these conversions, either when creating the data or when sorting.
I ran some tests WRT performance of each conversion, and string transformation using the Substring() method seems to be the fastest way:
PS C:\> $dates = 1..10000 | % {
>> $day = Get-Random -Min 1 -Max 28
>> $month = (Get-Random -Min 1 -Max 12
>> $year = Get-Random -Min 1900 -Max 2014
>> '{0:d2}.{1:d2}.{2}' -f $day, $month, $year
>> }
>>
PS C:\> Measure-Command { $dates | sort {Get-Date $_} }
Days : 0
Hours : 0
Minutes : 0
Seconds : 1
Milliseconds : 520
Ticks : 15200396
TotalDays : 1,75930509259259E-05
TotalHours : 0,000422233222222222
TotalMinutes : 0,0253339933333333
TotalSeconds : 1,5200396
TotalMilliseconds : 1520,0396
PS C:\> Measure-Command { $dates | sort {'{2}-{1}-{0}' -f ($_ -split '.')} }
Days : 0
Hours : 0
Minutes : 0
Seconds : 0
Milliseconds : 413
Ticks : 4139027
TotalDays : 4,79054050925926E-06
TotalHours : 0,000114972972222222
TotalMinutes : 0,00689837833333333
TotalSeconds : 0,4139027
TotalMilliseconds : 413,9027
PS C:\> Measure-Command { $dates | sort {$_ -replace '(\d+)\.(\d+).(\d+)', '$3-$2-$1'} }
Days : 0
Hours : 0
Minutes : 0
Seconds : 0
Milliseconds : 348
Ticks : 3488962
TotalDays : 4,03815046296296E-06
TotalHours : 9,69156111111111E-05
TotalMinutes : 0,00581493666666667
TotalSeconds : 0,3488962
TotalMilliseconds : 348,8962
PS C:\> Measure-Command { $dates | sort {[DateTime]::ParseExact($_, "dd.MM.yyyy", $null)} }
Days : 0
Hours : 0
Minutes : 0
Seconds : 0
Milliseconds : 340
Ticks : 3408966
TotalDays : 3,9455625E-06
TotalHours : 9,46935E-05
TotalMinutes : 0,00568161
TotalSeconds : 0,3408966
TotalMilliseconds : 340,8966
PS C:\> Measure-Command { $dates | sort {'{0}-{1}-{2}' -f $_.Substring(6,4), $_.Substring(3,2), $_.Substring(0,2)} }
Days : 0
Hours : 0
Minutes : 0
Seconds : 0
Milliseconds : 292
Ticks : 2926835
TotalDays : 3,38754050925926E-06
TotalHours : 8,13009722222222E-05
TotalMinutes : 0,00487805833333333
TotalSeconds : 0,2926835
TotalMilliseconds : 292,6835
$File="C:\temp\test\ID.txt"
$line="ART.023.AGA_203.PL"
Measure-Command {$Sel = Select-String -pattern $line -path $File }
Measure-Command {
$reader = New-Object System.IO.StreamReader($File)
$content = $reader.ReadToEnd().Split('`n')
$results = $content | select-string -Pattern $line
}
Measure-Command {
$content= get-content $File
$results = $content | select-string -Pattern $line
$results
}
Days : 0
Hours : 0
Minutes : 0
Seconds : 0
Milliseconds : 197
Ticks : 1970580
TotalDays : 2.28076388888889E-06
TotalHours : 5.47383333333333E-05
TotalMinutes : 0.0032843
TotalSeconds : 0.197058
TotalMilliseconds : 197.058
Days : 0
Hours : 0
Minutes : 0
Seconds : 4
Milliseconds : 135
Ticks : 41350664
TotalDays : 4.78595648148148E-05
TotalHours : 0.00114862955555556
TotalMinutes : 0.0689177733333333
TotalSeconds : 4.1350664
TotalMilliseconds : 4135.0664
Days : 0
Hours : 0
Minutes : 0
Seconds : 4
Milliseconds : 926
Ticks : 49265692
TotalDays : 5.70204768518518E-05
TotalHours : 0.00136849144444444
TotalMinutes : 0.0821094866666667
TotalSeconds : 4.9265692
TotalMilliseconds : 4926.5692
i want to search about 10000 $line in $File
search time very slower,any faster?
example :
search Keyword:$line ,then $File will show line
Keyword:ART.023.AGA_203.PL
file:2,45433;ART.023.AGA_203.PL;dddd;wwww;tt;
How does this compare to your other methods?
Measure-Command {
Get-Content $file -ReadCount 1000 |
foreach {$_ -match $line}
}
Note: when comparison testing operations that do disk reads like this, always run multiple tests and discard the first one. If the disk has any on-board read cache, the first test can pre-load the cache for subsequent tests and skew the results.
Here is one example, but there must be a more efficient way:
1..100|%{$temp=$_;$temp%=3;if ($temp -eq 0){$_} }
1..100 | Where-Object {$_ % 3 -eq 0}
I would guess that the "most efficient" way would be to use a plain old for loop:
for($i=3; $i -le 100; $i +=3){$i}
Though that's not very elegant. You could create a function:
function range($start,$end,$interval) {for($i=$start; $i -le $end; $i +=$interval){$i}}
Timing this against your method (using more pithy version of other answer):
# ~> measure-command {1..100 | Where-Object {$_ % 3 -eq 0}}
Days : 0
Hours : 0
Minutes : 0
Seconds : 0
Milliseconds : 7
Ticks : 76020
TotalDays : 8.79861111111111E-08
TotalHours : 2.11166666666667E-06
TotalMinutes : 0.0001267
TotalSeconds : 0.007602
TotalMilliseconds : 7.602
# ~> measure-command{range 3 100 3}
Days : 0
Hours : 0
Minutes : 0
Seconds : 0
Milliseconds : 0
Ticks : 6197
TotalDays : 7.1724537037037E-09
TotalHours : 1.72138888888889E-07
TotalMinutes : 1.03283333333333E-05
TotalSeconds : 0.0006197
TotalMilliseconds : 0.6197
How can i use New-Timespan cmdlet to calculate the total time taken for script execution.I tried a sample like this.
$val=Get-Date
$start=New-TimeSpan -Start $val
$val2=Get-Date
$end=New-TimeSpan -End $val2
$diff=New-TimeSpan -Start $start -End $end
But ended up with following error: New-TimeSpan : Cannot bind parameter 'Start'. Cannot convert the "00:00:08.7110000" value of type "System.TimeSpan" to
type "System.DateTime".
You don't need to use New-TimeSpan just subtract the DateTime objects:
$script_start = Get-Date
Start-Sleep -Seconds 5
$script_end = Get-Date
$script_end - $script_start
This will create a TimeSpan object.
You could use Measure-Command. It returns a timespan object. Example:
PS C:\> Measure-Command -Expression {1..10000000}
Days : 0
Hours : 0
Minutes : 0
Seconds : 1
Milliseconds : 714
Ticks : 17149279
TotalDays : 1.98487025462963E-05
TotalHours : 0.000476368861111111
TotalMinutes : 0.0285821316666667
TotalSeconds : 1.7149279
TotalMilliseconds : 1714.9279