0

Although I was able to achieve my objective, I don't understand why and I am concerned I'm still doing something wrong.

The context is to retrieve a datetime value for comparison to another date using FTP to retrieve a file's timestamp. The datetime is received as a string using this:

$FTPrequest = [System.Net.FtpWebRequest]::Create($FTPTargetFile)
$FTPrequest.Method = [System.Net.WebRequestMethods+FTP]::GetDateTimestamp
$FTPrequest.Credentials = $Credentials
$response = $FTPrequest.GetResponse().StatusDescription
$tokens = $response.Split(" ")
if ($tokens[0] -eq 213) {
    $Timestampdata = $tokens[1]
} else {
    Write-Output "FTP timestamp request for " + $FTPTargetFile + " returned an error"
}

Almost every available resource I found made it clear that ParseExact uses a string to derive a datetime as in the following line of script:

$d = [DateTime]::ParseExact($Timestampdata,"yyyyMMddHHmmss",$null)

But whether in a script or at the command prompt, the line above consistently returns the following error:

Exception calling "ParseExact" with "3" argument(s): "String was not recognized
as a valid DateTime."
At C:\hw-sw\powershell\FTPupload option - getFileInfo.ps1:38 char:1
+ $d = [DateTime]::ParseExact($Timestampdata,"yyyyMMddHHmmss",$null)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : FormatException

There were 2 links I found (lin1, link2 - 2nd link addresses a slighty different problem but the point is still made) that suggested ParseExact() uses an intXX instead, as in the following line of script:

$d = [DateTime]::ParseExact([convert]::ToInt64($Timestampdata),"yyyyMMddHHmmss",$null)

And yes, the line above runs without error.

While I am grateful for having found a potential solution to my scripting problem, I am unsettled because I don't understand why ParseExact is working with an int64, and not a string as I would have expected.

Is there some setup in PowerShell that changes how it works? I believe I must be making some simple mistake, but I can't figure it out.

3
  • Have you got whitespace in your string? Try $d = [datetime]::parseexact($Timestampdata.Trim(),"yyyyMMddHHmmss",$null). Commented Oct 25, 2017 at 15:00
  • Excellent thought. But yes, I did try .Trim(). No change in behavior. Commented Oct 25, 2017 at 15:13
  • Can't reproduce. Please provide sample input. Commented Oct 25, 2017 at 15:28

1 Answer 1

1
static datetime ParseExact(string s, string format, System.IFormatProvider provider)
static datetime ParseExact(string s, string format, System.IFormatProvider provider, System.Globalization.DateTimeStyles style)
static datetime ParseExact(string s, string[] formats, System.IFormatProvider provider, System.Globalization.DateTimeStyles style)

These are the overloaded methods for ParseExact on PSv5.1. You're passing it a $null provider.

Additional information

Your use case

After more reading, ensure your first argument doesn't have spaces or it will fail. Also make sure your current culture is correct for the behavior you're expecting.

Sign up to request clarification or add additional context in comments.

10 Comments

[System.DateTime]::ParseExact('20171025110130',"yyyyMMddHHmmss",$null) works for me. [System.DateTime]::ParseExact('20171025110130',"yyyyMMddHHmmss",[System.Globalization.CultureInfo]::InvariantCulture.DateTimeFormat) might be more correct, but $null works just fine with this format.
@BaconBits The DateTime.ParseExact(String, String, IFormatProvider) method parses the string representation of a date, which must be in the format defined by the format parameter. It also requires that the <Date> and <Time> elements of the string representation of a date and time appear in the order specified by format, and that s have no white space other than that permitted by format. Although, I see this note: If provider is null, the CultureInfo object that corresponds to the current culture is used. Not very fond of default behaviors
@BaconBits. I had the same result, which is maddening. When I specify a literal string, it works! As soon as I substitute my variable name, in this case $Timestampdata (even with Trim() as you noted above), it doesn't work.
@Alan You cannot have ANY spaces in $Timestampdata. .Trim() only removes whitespace from the ends. Try this: $Timestampdata = $Timestampdata -replace '\s'
@TheIncorrigible1. I believe I understand your points, but I may be missing something basic. I made sure there is no white space. I also made sure the string variable is in the proper format for my formatting template. That was a long lesson because FTP returns a 24 hr format and I had to learn the hard way the difference between hh and HH in the formatting string; but I'm certain that's now correct. The overloads from the links you posted still define the argument handed in as a string, yet my empirical results seem to require intXX, hence my confusion.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.