locked
DateTimePicker - String was not recognized as a Valid DateTime

    Question

  • I am trying to read one of Exif Tag properties - DateTimeOriginal. The following is part of the code:

    ....
    Dim
    img As Image = Image.FromFile(Me.strFileName)
    Dim iPI As PropertyItem

    DateTimePicker.CustomFormat = "yyyy:MM:dd hh:mm:ss tt"

    iPI = img.GetPropertyItem(36867)         '36867 is corresponding to ExifDTOrig (DatePictureTaken)

    DateTimePicker.Text = System.Text.ASCIIEncoding.ASCII.GetString(iPI.Value)

    The string output from System.Text.ASCIIEncoding.ASCII.GetString(iPI.Value) displayed the correct date and time in following format: "2007:06:19 09:05:35". However the dateTimePicker can't recognize it as a valid DateTime format. Would someone please help?

    • Edited by Margaret_Huang Tuesday, July 29, 2008 10:07 PM forgot to check the field
    Tuesday, July 29, 2008 9:30 PM

Answers

  • Hi Margaret.  You might want to try DateTime.TryParseExact to get a date variable out of a custom string format.  I tried the code below and was able to get the date to stick with your hard-coded value...

        iPI = img.GetPropertyItem(36867) '36867 is corresponding to ExifDTOrig (DatePictureTaken)
        Dim strDate As String = System.Text.ASCIIEncoding.ASCII.GetString(iPI.Value)
        Dim d As Date
        If DateTime.TryParseExact(strDate, "yyyy:MM:dd hh:mm:ss tt", New Globalization.CultureInfo("en-US"),
    Globalization.DateTimeStyles.AllowInnerWhite, d)
    Then
              DateTimePicker1.Value = d
        End If

    I'm not sure if the AllowInnerWhite is necessary but it seemed to be a good fit and it worked for me.

    EDIT:  I should Point out that your hard-coded example does not have the PM/AM at the end of it.  I added it but it seems to work without it there as well.

    • Edited by Dig-Boy Wednesday, July 30, 2008 12:24 AM see note
    • Marked as answer by Margaret_Huang Wednesday, July 30, 2008 8:42 PM
    Wednesday, July 30, 2008 12:22 AM
  • Got me.  Perhaps the textbox is encoding the string in a differnet way than ASCII   - in other words re-encoding it?  Or does the textbox have any formatting done on it?  If not then I would try a few different encoding formats to see if one of them is a magic bullet.  However ASCII seems intuitively correct to me.

    Hey, if you have to you could just create a textbox at runtime as a static variable in the containing method for this code to use as an ad hoc formatter ;)

    I'll try this stuff when I get on my home computer which has camera photos.

    • Edited by Dig-Boy Wednesday, July 30, 2008 8:27 PM minor stuff
    • Marked as answer by Margaret_Huang Wednesday, July 30, 2008 8:41 PM
    Wednesday, July 30, 2008 8:26 PM

All replies

  • Hi Margaret.  You might want to try DateTime.TryParseExact to get a date variable out of a custom string format.  I tried the code below and was able to get the date to stick with your hard-coded value...

        iPI = img.GetPropertyItem(36867) '36867 is corresponding to ExifDTOrig (DatePictureTaken)
        Dim strDate As String = System.Text.ASCIIEncoding.ASCII.GetString(iPI.Value)
        Dim d As Date
        If DateTime.TryParseExact(strDate, "yyyy:MM:dd hh:mm:ss tt", New Globalization.CultureInfo("en-US"),
    Globalization.DateTimeStyles.AllowInnerWhite, d)
    Then
              DateTimePicker1.Value = d
        End If

    I'm not sure if the AllowInnerWhite is necessary but it seemed to be a good fit and it worked for me.

    EDIT:  I should Point out that your hard-coded example does not have the PM/AM at the end of it.  I added it but it seems to work without it there as well.

    • Edited by Dig-Boy Wednesday, July 30, 2008 12:24 AM see note
    • Marked as answer by Margaret_Huang Wednesday, July 30, 2008 8:42 PM
    Wednesday, July 30, 2008 12:22 AM
  • Dig-Boy, 

    Would you check the TryParseExact method? I tried the following code, and okDate.ToString return me a false vaule. Would you please help? Thank you so much for your help!!! 

    Dim strDate1 As String = "2007:06:19 13:05:50 AM"

    Dim d As Date

    Dim okDate As Boolean

    okDate = DateTime.TryParseExact(strDate1, "yyyy:MM:dd hh:mm:ss tt", New Globalization.CultureInfo("en-us"), Globalization.DateTimeStyles.AllowInnerWhite, d)

    TextBox.Text = okDate.ToString


    mh
    Wednesday, July 30, 2008 6:37 PM
  • close...


    Dim strDate1 As String = "2007:06:19 13:05:50 AM"

    Dim d As Date

    Dim okDate As Boolean

    okDate = DateTime.TryParseExact(strDate1, "yyyy:MM:dd HH:mm:ss tt", New Globalization.CultureInfo("en-us"), Globalization.DateTimeStyles.AllowInnerWhite, d)

    TextBox.Text = okDate.ToString

    Wednesday, July 30, 2008 6:39 PM
  • That worked; the okDate is returning true after hh -> HH.  Thank you so much!!!

    Now back to my first post. The string output from System.Text.ASCIIEncoding.ASCII.GetString(iPI.Value) is displaying in following format: "2007:06:19 09:05:35". That is without AM/PM. If I set

    Dim strDate1 As String = System.Text.ASCIIEncoding.ASCII.GetString(iPI.Value), I am getting okDate to false again.

    Thank you again for your swift reply!


    mh
    Wednesday, July 30, 2008 7:29 PM
  • I think I must be doing sth. very silly. Here is part of my code. okDate is false. Would you please help?

    Dim
    img As Image = Image.FromFile(Me.strFileName)
    Dim iPI As PropertyItem
    Dim strDate1 As String 
    Dim d As Date
    Dim okDate As Boolean

    iPI = img.GetPropertyItem(36867)
    strDate1 = System.Text.ASCIIEncoding.ASCII.GetString(iPI.Value)

    okDate = DateTime.TryParseExact(strDate1,
    "yyyy:MM:dd HH:mm:ss", New Globalization.CultureInfo("en-us"), Globalization.DateTimeStyles.AllowInnerWhite, d)

    TextBox.Text = okDate.ToString

    If I output strDate1 to a text box, it is 2007:06:19 09:05:35. Thanks in advance!


    mh
    Wednesday, July 30, 2008 8:01 PM
  • Well, unfortunately if I use your hard-coded value at the bottom of the post (2007:06:19 09:05:35) it returns true.  I tried using some images on my desktop to get the property on my own but none of them have the property 36867.  What is the origin of the images you are working with?  Is it something replicable on my end?

    Wednesday, July 30, 2008 8:12 PM
  • It has to be photos files that are taken from a digital camera.
    If I am doing one extra step:


    strDate1 = System.Text.ASCIIEncoding.ASCII.GetString(iPI.Value) 

    Textbox1.text = strDate1

    okDate = DateTime.TryParseExact(Textbox1.text,
    "yyyy:MM:dd HH:mm:ss", New Globalization.CultureInfo("en-us"), Globalization.DateTimeStyles.AllowInnerWhite, d)

    It works just fine. Why? 

    mh
    • Edited by Margaret_Huang Wednesday, July 30, 2008 8:21 PM Removed the confuse sentence.
    Wednesday, July 30, 2008 8:20 PM
  • Got me.  Perhaps the textbox is encoding the string in a differnet way than ASCII   - in other words re-encoding it?  Or does the textbox have any formatting done on it?  If not then I would try a few different encoding formats to see if one of them is a magic bullet.  However ASCII seems intuitively correct to me.

    Hey, if you have to you could just create a textbox at runtime as a static variable in the containing method for this code to use as an ad hoc formatter ;)

    I'll try this stuff when I get on my home computer which has camera photos.

    • Edited by Dig-Boy Wednesday, July 30, 2008 8:27 PM minor stuff
    • Marked as answer by Margaret_Huang Wednesday, July 30, 2008 8:41 PM
    Wednesday, July 30, 2008 8:26 PM
  • I tried every other format, but none of them is working. Like you suggested, I am just using a textbox as an ad hoc for now. Thank you so much for all your time.

    Thanks a bounch!!! You made my day!


    mh
    Wednesday, July 30, 2008 8:45 PM
  • Hi Margaret -- back on my home computer now and I've spent a frustrating hour trying to get this to work.  I believe strongly that you have discovered a bug with wither the DateTime.TryParseExact function (same for Date class as well) or with the way that the ASCII encoder handles an image's CreationDate property bytes.

    I have tested this in over a dozen scenarios and could not get the string that is produced by System.Text.ASCIIEncoding.ASCII.GetString to be parsable directly through the function.  In fact there were times when the textbox filtering seemed to fail (there were so many variations that I tried I cannot be sure now what the limiting factor was).  Some of the things I tried were:

    --  Using a stringbuilder to Append each of the bytes in the property value's array through CHR function and then spitting out the result by it's ToString function (boy I thought this would work too - like the textbox, as a proxy.)

    -- Passing the string on to other strings through various versions of implicit and explicit conversions.

    -- Using a function to receive the property value's string as an argument and return a "converted" string from it.

    -- Trying all the DateTimeStyles enumerations in the TryParseExact function.

    -- Other encodings (I admit I didn;t try all of them, but some are just rediculously inappropriate)

    -- Trimming, removing the space, replacing the space with another character and then changing the format string accordingly.


    In all cases if I pass the string literal in it would work.  In fact I got into the absurd situation of having a datatimepicker control (set to the custom format string) displaying its hardcoded value identical to the "error" message string I was trying to pass into it.  Apparently two identical strings may not be the same.

    In the end I had to resort to a function to manually parse out the string.  So here's my final answer below but I just don't think it should have to come down to this.  I hope that someone else can confirm this and, if true, report it as a bug to MS.

     
     Private Sub Button1_Click(ByVal sender As System.ObjectByVal e As System.EventArgs) Handles Button1.Click  
     
            Dim result As String = "" 
            Try 
                Dim ofd As New OpenFileDialog  
                If ofd.ShowDialog = Windows.Forms.DialogResult.OK Then 
     
                    Dim img As Image = Image.FromFile(ofd.FileName)  
                    Dim prop As System.Drawing.Imaging.PropertyItem = img.GetPropertyItem(36867)  
                    If prop IsNot Nothing Then 
                        Dim d As Date = GetImageCreateDate(System.Text.ASCIIEncoding.ASCII.GetString(prop.Value))  
                        If d <> Nothing Then 
                            result = "Creation Date:  " & d.ToString("MM/dd/yyyy") & " " & d.ToShortTimeString  
                        Else 
                            result = "The creation date is not parsable" 
                        End If 
                    End If 
                    MessageBox.Show(result)  
                End If 
     
            Catch ex As Exception  
                MessageBox.Show(ex.Message)  
            End Try 
        End Sub 
     
        Private Function GetImageCreateDate(ByVal strDate As StringAs String 
     
            Dim d As DateTime = Nothing 
            Dim parts As String() = strDate.Split(" ")  
            If parts.Length = 2 AndAlso DateTime.TryParseExact(parts(0), "yyyy:MM:dd"New System.Globalization.CultureInfo("EN-US"), Globalization.DateTimeStyles.None, d) Then 
                Dim timeparts As String() = parts(1).Split(":")  
                If timeparts.Length = 3 Then 
                    Try 
                        Dim ts As New TimeSpan(Int32.Parse(timeparts(0)), Int32.Parse(timeparts(1)), Int32.Parse(timeparts(2)))  
                        d += ts  
                    Catch 
                        'Allow just date part to pass through  
                    End Try 
                End If 
            End If 
     
            Return d  
        End Function 
     

    EDIT:  This code is definitely not "fool proof" (i.e. no testing for file type, assumptions in strDate argument) so make it stronger to your liking.  I would suggest having the function take in the image as an argument and then returning the date (with Nothing or Now() as a default).


    On a lighter note, thank you for asking the question because I had never tried to extract image properties before but was mildly interested in the possibility.  I'm sire I'll use this info in the future.  For that I marked your original post as helpful.
    • Edited by Dig-Boy Thursday, July 31, 2008 2:23 AM see note
    Thursday, July 31, 2008 2:19 AM