Search code examples
powershellopensslcertificate

Why ParseExact is not converting my variable to DateTime


I am trying to convert a string value to a Datetime value with powershell, but I getting this error:

Excepción al llamar a "ParseExact" con los argumentos "3": "No se puede reconocer la cadena como valor DateTime válido."
En línea: 6 Carácter: 1
+ $CertDate = [DateTime]::ParseExact("$Cert", 'MMM-d-HH:mm:ss-yyyy', $n ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : FormatException

This is my code:

$certificatePath = "C:\Users\user\certificate.pem"
$opensslPath = "C:\Program Files\OpenSSL-Win64\bin\openssl.exe"

$Cert = & $opensslPath x509 -in  $certificatePath -noout -enddate
$Cert = $Cert.split("=")[1]
$Cert = $Cert.replace(" ","-")
$Cert = $Cert.replace("--","-")
$Cert = $Cert.replace("-GMT","")
$CertDate = [DateTime]::ParseExact("$Cert", 'MMM-d-HH:mm:ss-yyyy', $null)
$CurrentDate = Get-Date
$DateTime = $CertDate - $CurrentDate
$Date = $DateTime.Days

The output of the variable $cert is:

PS C:\WINDOWS\system32> $Cert
Oct-8-11:05:03-2025

And the variable $Cert is a String Type:

PS C:\WINDOWS\system32> $cert.GetType()

IsPublic IsSerial Name                                     BaseType                                                                                                                                                    
-------- -------- ----                                     --------                                                                                                                                                    
True     True     String                                   System.Object 

The $Cert output match with the format indicated in the ParseExact: 'MMM-d-HH:mm:ss-yyyy'

Any idea of what I am doing wrong?

Thanks and BR!

Tried different formts and doesn't worked


Solution

  • Assuming there are no invisible characters that could be causing this issue, by simply changing the Provider argument from $null to InvariantCulture the issue should be solved.

    & {
        $Cert = 'Oct-8-11:05:03-2025'
        [System.Threading.Thread]::CurrentThread.CurrentCulture =
            [cultureinfo]::GetCultureInfo('es-AR')
    
        [DateTime]::ParseExact($Cert, 'MMM-d-HH:mm:ss-yyyy', [cultureinfo]::InvariantCulture)
        # Correctly parses into: `miércoles, 8 de octubre de 2025 11:05:03`
    }
    

    In ParseExact Remarks section you can read the following:

    If provider is null, the CultureInfo object that corresponds to the current culture is used.

    In Spanish culture a month in the MMM format would end with a ., i.e.: Oct.. This is why using $null fails to parse and also this is proven by, if you add the . it parses correctly:

    & {
        # With the `.` after `Oct` this parses corretly in Spanish culture
        $Cert = 'Oct.-8-11:05:03-2025'
        [System.Threading.Thread]::CurrentThread.CurrentCulture =
            [cultureinfo]::GetCultureInfo('es-AR')
    
        [DateTime]::ParseExact($Cert, 'MMM-d-HH:mm:ss-yyyy', $null)
    }