Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Converting strings to datetime objects that have variable digits for days

I have the following in an array variable

Mon May  1 08:13:18 2017
Sat Apr 29 19:07:14 2017

In order to update the format and timezone, I have to run these two ParseExact commands first.

$time | ForEach-Object {$_ = [datetime]::ParseExact($_,'ddd MMM  d HH:mm:ss yyyy',[System.Globalization.CultureInfo]::InvariantCulture)} 

$time | ForEach-Object {$_ = [datetime]::ParseExact($_,'ddd MMM dd HH:mm:ss yyyy',[System.Globalization.CultureInfo]::InvariantCulture)}

I get an error on the one that fails (which is expected)

Exception calling "ParseExact" with "3" argument(s): "String was not recognized as a valid DateTime."
At D:\UPDATING.ps1:
+ ... ach-Object {$_ = [datetime]::ParseExact($_ ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : FormatException

Everything works in the long run and I can do my formatting, but I would like to know if there is a better of doing this rather than using 2 parseExacts

like image 297
mattnicola Avatar asked Jul 10 '26 22:07

mattnicola


2 Answers

There are multiple overloads of ParseExact method. One of them allows you to specify multiple patterns of date to parse:

$time = 'Sat Apr 29 19:07:14 2017', 'Mon May  1 08:13:18 2017'
$time | % { [DateTime]::ParseExact($_, [String[]]('ddd MMM  d HH:mm:ss yyyy',
                                                  'ddd MMM dd HH:mm:ss yyyy'), [CultureInfo]::InvariantCulture, 'None') }

Also there are overloads, which allow you to specify additional parse options, like [Globalization.DateTimeStyles]::AllowInnerWhite, to allow additional whitespace characters inside parsed string:

$time | % { [DateTime]::ParseExact($_, 'ddd MMM d HH:mm:ss yyyy', [CultureInfo]::InvariantCulture, 'AllowInnerWhite') }
like image 77
user4003407 Avatar answered Jul 14 '26 03:07

user4003407


There is an extra space in your first date and a single digit day, so the pattern would actually need to be ddd MMM d HH:mm:ss yyyy.

Full command:

[datetime]::ParseExact($_,'ddd MMM  d HH:mm:ss yyyy',[System.Globalization.CultureInfo]::InvariantCulture)

However, this isn't the case for your second date. A single d will still work for this but the changing in space is an issue you might need to program around. One solution would be to replace all double spaces with singles first.

This seems to work for both dates, here's a proof of concept:

$dates = "Sat Apr 29 19:07:14 2017","Mon May  1 08:13:18 2017"
$dates = $dates -replace '  ',' '

$dates | ForEach-Object {
    [datetime]::ParseExact($_,'ddd MMM d HH:mm:ss yyyy',[System.Globalization.CultureInfo]::InvariantCulture)
}
like image 30
Mark Wragg Avatar answered Jul 14 '26 05:07

Mark Wragg



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!