Excallypurr
Excallypurr

Reputation: 319

How can I get Minutes and seconds (mm:ss) from a decimal value in Powershell

I have a bit of code that is waiting different intervals every loop (currently based on a random range of seconds). I want to convert this random number of seconds, between 10 and 399, to minutes and specifically to show in the mm:ss format. This what I currently have:

x = 1
for ( $x -eq 0) {
    $y = Get-Random -Maximum 399 -Minimum 10
    Write-Host '$y is' $y
    $y2 = ($y/60)
    Write-Host '$y2 is '$y2
    $y3 = Get-Date -Minute($y2) -UFormat %M:%S
    Write-Host "Waiting "$y3
    Start-Sleep -s $y
}

What I don't understand is every time I run this loop y and y2 are correctly written but y3 displays the wrong time. I'm not entirely certain as to why this is happening and have been scratching my head all day wondering why it's displaying a different time when I know the variables going into it are correct. This is the way I think I can accomplish this task but if anyone knows of a better way to do it, I am all ears! I just would also like to know why this bit of code isn't working as I think it should. I really appreciate the help!

Upvotes: 0

Views: 1832

Answers (1)

Jonathon Anderson
Jonathon Anderson

Reputation: 1198

As was pointed out in the comments by jfrmilner, New-TimeSpan is another choice that makes more sense semantically.The displayed results are the same, even though you're working with different data structures under the hood.

If you want to use that approach, you should use this:

$y3 = (New-TimeSpan -Seconds $y).ToString("mm\:ss")

Here is some more information about Get-Date in case you still want to use it.

You have two problems with the Date that you're creating.

  1. The -Minute parameter only takes a whole integer as a value. Since you are passing a decimal, it does some automatic rounding, which causes your minutes to be inaccurate.
  2. The -Second parameter is not specified, so Get-Date is using the seconds from the system time to fill in the missing information.

Replace your Get-Date operation with

$y3 = Get-Date -Minute([System.Math]::Truncate($y2)) -Second($y % 60) -UFormat %M:%S
  1. [System.Math]::Truncate() causes everything after the decimal to be dropped, giving you the whole integer value you want for -Minute
  2. Modulus division for -Second gives you the remainder of the operation $y / 60, which is the number of seconds you're looking for

Upvotes: 1

Related Questions