2

I have the below data which is an object type variable named $timestamps

Sat Jan 15 16:21:24
Sat Jan 15 01:31:22
Fri Jan 14 20:58:09
Fri Jan 14 20:51:02

enter image description here

I'm having trouble converting it to Datetime object because of the weird date format. How would you handle this?

I would like it as a datetime object because I plan to convert from current (UTC) to EST.

TIA

2
  • 2
    $timestamps is an array. If you want to know the type of each element in the array, it must be referenced directly. $timestamps[0].GetType()
    – lit
    Commented Jan 15, 2022 at 18:46
  • Note that without a year in your input, time zone conversions could be incorrect. The dates that US Eastern Time shifts from EST to EDT and back vary from year to year. You might assume the current year, but that won't work well at the start of the year looking back at the previous year's data, or at the end of the year looking ahead to the next year. Commented Jan 16, 2022 at 18:44

2 Answers 2

6

You can use the the ParseExact() method provided by the [datetime] class for this:

[datetime]::ParseExact('Fri Jan 14 20:58:09','ddd MMM dd HH:mm:ss',$null)

# returns a - datetime - object of:
# Friday, January 14, 2022 8:58:09 PM
  • dd - for the day.
  • MM - for the month.
  • HH - for the hour - Capitalized for the 24 hour time format.
  • mm - for the minutes.
  • ss - for the seconds.

Edit: as suggested by mklement0, we can use [cultureinfo]::InvariantCulture to make the parsing specific to an English date time format. Also, changing dd to d as a more robust solution for days without 2 digits; which should cover both singular, and double digit days.

Seeing $timestamps is an array of strings, you can use a loop (of your choice - in this case the Foreach-Object cmdlet) to iterate through each string parsing the text to return a datetime object:

$timestamps | ForEach-Object {
    $culture = [cultureinfo]::InvariantCulture
    $format  = 'ddd MMM d HH:mm:ss'
    $date = [datetime]::ParseExact($_,$format,$culture,'AssumeUniversal, AdjustToUniversal')
    [System.TimeZoneInfo]::ConvertTimeBySystemTimeZoneId($date, 'Eastern Standard Time')
}
  • Using 'AssumeUniversal, AdjustToUniversal' ensures a UTC output.

Assuming from your comment that you'd like to do a conversion to Eastern Time, passing the newly created datetime object to [System.TimeZoneInfo]::ConvertTimeBySystemTimeZoneId() with an argument of the desired time zone, you can get your result in the new time zone.


When using $null, the CultureInfo object that corresponds to the current culture is used.

10
  • 1
    @MattyS, is your $timestamps variable an array of strings? Commented Jan 15, 2022 at 18:13
  • 1
    @MattyS, regrettably, PowerShell quietly converts an array to a string by space-concatenating its elements when calling .NET methods (which is virtually useless). Simply call the solution shown for each element.
    – mklement0
    Commented Jan 15, 2022 at 18:22
  • 2
    @MattyS: $timestamps = "Sat Jan 15 16:21:24", "Sat Jan 15 01:31:22", "Fri Jan 14 20:58:09", "Fri Jan 14 20:51:02"; $timestamps.ForEach({ [datetime]::ParseExact($_, 'ddd MMM d HH:mm:ss', [cultureinfo]::InvariantCulture, 'AssumeUniversal, AdjustToUniversal') })
    – mklement0
    Commented Jan 15, 2022 at 18:50
  • 2
    @lit, $null is a placeholder for the current culture ($PSCulture == [cultureinfo]::CurrentCulture). The invariant culture is based on (US-)English, but is distinct from it (distinct from any real-world culture, including [cultureinfo] 'en-US'); notably, its format is guaranteed to never change.
    – mklement0
    Commented Jan 15, 2022 at 18:54
  • 2
    You're welcome, @Abraham; thanks for updating. Looks good; the only thing I'd add: AssumeUniversal interprets the input as UTC - by itself, that would be translated to a local time; adding AdjustToUniversal outputs a UTC instance.
    – mklement0
    Commented Jan 15, 2022 at 19:44
1

The DateTime.ParseExact() method is probably what you're looking for.

PS C:\TEMP>$timestamp = 'Sat Jan 15 16:21:24'
PS C:\TEMP>$format    = 'ddd MMM dd HH:mm:ss'
PS C:\TEMP>[datetime]::ParseExact($timestamp, $format, $null)

Saturday, January 15, 2022 04:21:24 PM


PS C:\TEMP>
1
  • 1
    Yes (with caveats), but your answer in essence duplicates an earlier one.
    – mklement0
    Commented Jan 15, 2022 at 18:51

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