Can I control the DateTime format displayed by my cmdlet?
I have a cmdlet with a DateTime attribute that represents the timestamp of an event on the server. The cmdlet reads the log on the server and prints out some information. Since many events can occur in a short window, millisecond precision is important to logout users.
However, when using a list format or format table, only seconds are displayed in the output, for example. 4/15/2015 5:31:30 PM
... I would rather use the fff time format instead .
I know the actual data is not rounded because if I query the Millisecond property on my DateTime value, I see the correct value. For example, for a given output $event
, if there is a timestamp in my log line 2015-04-16T00:31:30.525Z
, it $event.Timestamp.Millisecond
returns 525.
Is there something I can do in my cmdlet to tell the DateTime to display with milliseconds? For example, when the user enters:
> Get-LogInfo | ft
I want to show by default:
Timestamp EventData
--------- -------
4/15/2015 17:31:28.525 (data)
I would also like similar behavior for a list of formats. Ideally, users of the cmdlet would not need to do any extra work to see milliseconds.
source to share
You can ask to Format-Table
convert DateTime
to string, but you want:
$t = New-Object psobject -Property @{Text ="test"; dt = (Get-Date)}
$t | ft Text,@{expression={"{0:HH:mm:ss.fff}" -f $_.dt};label="time with milliseconds"} -AutoSize
prints:
Text time with milliseconds
---- ----------------------
test 18:08:51.725
Alternatively, you can adjust the current long pattern of the current thread to show milliseconds:
$t = New-Object psobject -Property @{Text ="test"; dt = (Get-Date)}
[System.Threading.Thread]::CurrentThread.CurrentCulture.DateTimeFormat.LongTimePattern = 'HH:mm:ss.fff'
$t | ft * -AutoSize
prints:
Text dt
---- --
test 4/21/2015 10:24:08.877
The latter obviously affects all date-to-string conversions, so use with caution.
source to share
Both Format-Table
and Format-List
(less commonly) will change object properties and types silently. They should be one of the last things you do to collect information for display. Depending on where you have the ones in your script, they could easily be the culprit for your problem.
What stands out to me in what you say:
Milliseconds are out of order.
This suggests that your object property is not actually an object DateTime
by the time you try to sort it. You see the effects of "alphabetical sort" versus "numeric" sort.
A short example:
PS C:\>$ints = 5200,310,560,290
PS C:\>$strings = "5200","310","560","290"
PS C:\>$strings | Sort-Object
290
310
5200
560
PS C:\>$ints | Sort-Object
290
310
560
5200
To custom convert a DateTime
to fff notation:
PS C:\>(get-date).ToString("MM/dd/yyyy HH:mm:ss.fff")
04/20/2015 18:01:22.710
I've used a format that includes leading zeros for single-digit months / minutes / hours, etc. to reduce the risk of alphabetically sorting than numeric sorting. Similar note to the above, it would be better to make sure the sorting happens before any other formatting operation to get the most accurate results.
If that's not enough to help solve the problem, it will help see some of the script / code. In particular, the part that generates the object that contains the property DateTime
and what is done with it before sorting it.
source to share