PowerShell’s Get-Date FileDateTime for Safe Filenames

Since about the beginning of time now, I’ve used Get-Date to create my own safe filenames. It’s a date and time format that is safe to be used as/in a file’s name without including anything that can’t be. Here’s what I’ve long used.

Get-Date -Format 'DyyyyMMddTHHmmss.fffffff'

That’ll produce something such as this.

D20191211T201315.1474900

Okay, maybe I haven’t always used this, but I certainly used a variation. It was after the beginning of time, if you will, that I switched to this version, which includes the dot and the seven Fs. The Fs (in lowercase [it’s important]) display milliseconds. I added these to help ensure that filenames that include the date and time were more likely to be unique. You can imagine. You create more than one file in the same second, and you run up against a file already existing error if you don’t include milliseconds. Before we continue, let’s ensure all the other letters represented in the above code example are included here:

I should mention, that using this format ensures proper file sorting and ordering. That can be important. It’s always been there (or it’s likely, at least), but it turns out that there’s an easier way than what I’ve been doing.

I can still learn something new that I hadn’t known before, such as using Get-Date differently. I can now create safe filenames that include the date and time, even after I’ve spent several dedicated years of using and writing about PowerShell. Maybe it was forgotten. I doubt that in this case. That said, it is possible to overlook easier, and potentially better ways of doing things once you have a solution for something.

Instead of creating safe filenames using Get-Date, the Format parameter, and .NET format specifiers (as they’re called), I recently noticed that someone — likely at Microsoft, as this has probably been around a while — took care of this for us.

The Get-Date cmdlet includes a couple, notable parameter values that can be used with the Format parameter. Two we’ll discuss are FileDate and FileDateTime. Take a look at this; it returns the date, without the time.

PS> Get-Date -Format FileDate
20191211

The date without the time is not exactly what I was after — the time is vital in my mind. Therefore, let’s repeat this example with the FileDateTime Format parameter value.

PS> Get-Date -Format FileDateTime
20191211T2015018186

Oh, look — there it is That’s the built-in way to ensure a unique and safe filename that includes date and time without the need of using my earlier example. It’ll probably be easier to remember that than this value: ‘DyyyyMMddTHHmmss.fffffff’. Do notice that the decision at Microsoft, because again this was probably written before PowerShell was open-sourced, is that four digits for milliseconds is likely suitable. I’m even not sure why I chose to use seven digits, anyway. Meh.

And, if you want to find out about uniqueness for sure — as I did — put it in a loop. The below example creates 25 safe (files and) filenames. It seems to work just fine for me.

PS> 1..25 | ForEach-Object {New-Item -Path '.\Documents\Test' -Name "$(Get-Date -Format FileDateTime).txt"}

    Directory: C:\Users\tommymaynard\Documents\Test

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----        12/11/2019  8:30 PM              0 20191211T2030184424.txt
-a----        12/11/2019  8:30 PM              0 20191211T2030184471.txt
-a----        12/11/2019  8:30 PM              0 20191211T2030184486.txt
-a----        12/11/2019  8:30 PM              0 20191211T2030184507.txt
-a----        12/11/2019  8:30 PM              0 20191211T2030184521.txt
-a----        12/11/2019  8:30 PM              0 20191211T2030184535.txt
-a----        12/11/2019  8:30 PM              0 20191211T2030184548.txt
-a----        12/11/2019  8:30 PM              0 20191211T2030184561.txt
-a----        12/11/2019  8:30 PM              0 20191211T2030184577.txt
-a----        12/11/2019  8:30 PM              0 20191211T2030184593.txt
-a----        12/11/2019  8:30 PM              0 20191211T2030184614.txt
-a----        12/11/2019  8:30 PM              0 20191211T2030184630.txt
-a----        12/11/2019  8:30 PM              0 20191211T2030184652.txt
-a----        12/11/2019  8:30 PM              0 20191211T2030184669.txt
-a----        12/11/2019  8:30 PM              0 20191211T2030184687.txt
-a----        12/11/2019  8:30 PM              0 20191211T2030184704.txt
-a----        12/11/2019  8:30 PM              0 20191211T2030184721.txt
-a----        12/11/2019  8:30 PM              0 20191211T2030184738.txt
-a----        12/11/2019  8:30 PM              0 20191211T2030184759.txt
-a----        12/11/2019  8:30 PM              0 20191211T2030184784.txt
-a----        12/11/2019  8:30 PM              0 20191211T2030184804.txt
-a----        12/11/2019  8:30 PM              0 20191211T2030184850.txt
-a----        12/11/2019  8:30 PM              0 20191211T2030184866.txt
-a----        12/11/2019  8:30 PM              0 20191211T2030184883.txt
-a----        12/11/2019  8:30 PM              0 20191211T2030184899.txt

Not one naming collision using only four milliseconds. I’m sold. I won’t ever forget you FileDateTime.

4 thoughts on “PowerShell’s Get-Date FileDateTime for Safe Filenames

  1. Göran

    Just a detail, I think you mean 4 decimal digits, not 4 milliseconds. The first 3 decimal digits (when measuring seconds) corresponds to milliseconds. 4 decimal digits could be said to measure hundreds of microseconds, but that’s not very practical.

    An interesting test would be to run the test in a folder on a RAM disk, would it still take more than 100us between each file creation? If not, the naming breaks.

    Reply
    1. tommymaynard Post author

      Thank you for your reply! I can see how that may be confusing, so I edited the post. Thank you!

      Reply
  2. Göran

    Also, I think I know why you chose 7 decimal digits. It seems to be the maximum. 🙂
    I would prefer your 7 decimal digits every day over the default 4.

    Reply
    1. tommymaynard Post author

      This is _very_ likely; thank you for pointing it out. While I’d prefer 7 digits over 4 too, I’ll take the trade off of letting PowerShell do the work vs. me remembering/finding the format string. Maybe someday it’ll be added (FileDateTime7, or something).

      Reply

Leave a Reply

Your email address will not be published. Required fields are marked *