When i'm trying to parse a line in a IIS log file and pulling the datetime on the line, I'm getting the following error
Exception calling "ParseExact" with "3" argument(s): "String was not recognized as a valid DateTime." At line:9 char:1
- $dateTime = [datetime]::ParseExact($dateTimeString, 'yyyy-MM-dd HH:mm ...
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException + FullyQualifiedErrorId : FormatException
here is my powershell code:
$line = '2020-12-23 02:01:16.244 -06:00 [Information] 2020-12-23T08:01:16.2446161Z: [Error] Oracle.ManagedDataAccess.Client.OracleException (0x80004005): Connection request timed out'
$dateTimeString = [regex]::Matches($line, '\d\d\d\d-\d\d-\d\d\s\d\d:\d\d:\d\d')[0].Groups[1].Value
write-host "datetimestr:" $dateTimeString
$provider = New-Object System.Globalization.CultureInfo "en-US"
$dateTime = [datetime]::ParseExact($dateTimeString, 'yyyy-MM-dd HH:mm:ss', $provider)
write-host $dateTime
$dateTime -f 'MM/dd/yyyy HH:mm:ss' | write-host
i guess i need some fresh eyes to see what i'm missing.
notes:
Just to offer a simpler solution that doesn't require a complex regex:
$line = '2020-12-23 02:01:16.244 -06:00 [Information] 2020-12-23T08:01:16.2446161Z: [Error] Oracle.ManagedDataAccess.Client.OracleException (0x80004005): Connection request timed out'
[datetime] ((-split $line)[0..1] -join ' ')
-split
, the string-splitting operator is used to split the line into whitespace-separated tokens, and the first two tokens ([0..1]
) are joined back with a space.
[datetime]
is a culture-invariant way of converting a date-time string into a [datetime]
(System.DateTime
) instance; this culture-invariant way is based on the InvariantCulture
, which is based on the US-English culture.
You can use
$dateTimeString = [regex]::Match($line, '\d{4}-\d\d-\d\d\s\d\d:\d\d:\d\d').Value
Your [regex]::Matches($line, '\d\d\d\d-\d\d-\d\d\s\d\d:\d\d:\d\d')[0].Groups[1].Value
code matches a datetime substring into Group 0. You are trying to get Group 1 value by using .Groups[1].Value
, but there is no capturing group defined in the pattern.
Note there is no need using Matches
that fetches all occurrences in the string since all you need is the first match, which can be done with a mere Match
.
Also, repeating \d
four times in a regex is really redundant, you may use a {4}
limiting quantifier.
If you want to only find a match at the start of the string, add ^
at the beginning: '^\d{4}-\d\d-\d\d\s\d\d:\d\d:\d\d'
.
User contributions licensed under CC BY-SA 3.0