【问题标题】:Conversion from string "‎8/‎5/‎2014" to type 'Date' is not valid从字符串“‎8/‎5/‎2014”到类型“日期”的转换无效
【发布时间】:2014-08-29 22:21:32
【问题描述】:

我的代码已从图像文件中检索到“拍摄日期”属性并将其存储为字符串。然后,它将该字符串传递回 Main Sub,并在其中尝试将其与其他日期(系统时间)进行比较。我收到一条错误消息,提示我无法将字符串日期转换为日期。 (从字符串“‎8/‎5/‎2014”到类型“日期”的转换无效。)

在下面的代码中有两行被注释掉。执行这些行时,程序按预期工作(字符串转换为日期)。注释行中的日期与(视觉上)程序化获取的日期完全匹配;虽然如果我从监视窗口复制和粘贴它也会失败。

    Imports System.IO
    Imports System.Globalization

Module Module1

    Sub Main()

        Dim topLevelFolder As New DirectoryInfo("C:\Users\amitchell\Desktop\test1\")
        Dim cutoffDate As DateTime = DateTime.Now.AddDays(-30)
        Dim Dtaken As String
        Dim PassFile
        Dim Dtaken2

        Using outputFile As New StreamWriter("output_file.txt")
            For Each currentFile In topLevelFolder.EnumerateFiles("*.*", SearchOption.AllDirectories)
                PassFile = currentFile.FullName
                Dtaken = GetProperty(PassFile, 12)
                'Dtaken = "8/5/2014"
                'Dtaken2 = IsDate(Dtaken)
                If Dtaken > cutoffDate Then
                    outputFile.WriteLine(currentFile.FullName)
                End If
            Next
        End Using

    End Sub

    Function GetProperty(strFile, n)
        Dim objShell As Object
        Dim objFolder
        Dim objFolderItem
        Dim i
        Dim strPath
        Dim strName
        Dim intPos

        On Error GoTo ErrHandler

        intPos = InStrRev(strFile, "\")
        strPath = Left(strFile, intPos)
        strName = Mid(strFile, intPos + 1)
        objShell = CreateObject("shell.application")
        objFolder = objShell.NameSpace(CObj(strPath))
        objFolderItem = objFolder.ParseName(strName)
        If Not objFolderItem Is Nothing Then
            GetProperty = objFolder.GetDetailsOf(objFolderItem, n)
            GetProperty = Left(GetProperty, InStrRev(GetProperty, " ") - 1)
            GetProperty = Left(GetProperty, InStrRev(GetProperty, " ") - 1)
        End If

ExitHandler:
        objFolderItem = Nothing
        objFolder = Nothing
        objShell = Nothing
        Exit Function

ErrHandler:
        MsgBox(Err.Description, vbExclamation)
        Resume ExitHandler
    End Function


End Module

【问题讨论】:

  • 为什么不将日期保存为 DateTime 而不是将其存储为字符串?我还建议打开 OPTION STRICT ON 以帮助您将 VB.NET 和看起来像 VBscript 的东西结合起来。
  • 请不要把vb.net写成vb6。
  • 当我将 Function GetProperty(strFile, n) 设置为 DateTime 时,我收到相同的错误:从字符串“‎8/‎5/‎2014 ‏‎4:21 PM”转换为“日期”无效。我不确定这段代码的哪些部分是 VB.NET 和 VBscript 我会寻找并打开这个选项。

标签: vb.net date visual-studio-2012 date-conversion


【解决方案1】:

那个代码让我很难过。它遵循一些对 vb6/vbscript 时代有意义的约定,但对 .Net 代码不是很好。结果是大部分代码都在复制 .Net Framework 为您处理(并且做得更好)的工作。我会为你拥抱Using 块而表扬你,所以有希望。

此代码更好地利用了 .Net 框架。它从不将任何日期值呈现为字符串,从而完全回避了您的问题。

Imports System.IO

Module Module1

    Sub Main()
        Dim topLevelFolder As New DirectoryInfo("C:\Users\amitchell\Desktop\test1\")
        Dim cutoffDate As DateTime = DateTime.Now.AddDays(-30).Date

        Using outputFile As New StreamWriter("output_file.txt")
            Dim files = topLevelFolder.EnumerateFileSystemInfos("*.*", SearchOption.AllDirectories).
                   Where( Function(f) f.CreationTime > cutoffDate )
            For Each file in files
                outputFile.WriteLine(file.FullName)
            Next file
        End Using
    End Sub

End Module

【讨论】:

  • 你的代码肯定比我的优雅得多,但它是基于 CreationTime 的。对我的目的而言,重要的是它与 DateTaken 属性无关。您的代码还会拾取文件夹,我可以稍后将其删除。我也很抱歉我的代码让你难过......但我很高兴你看到了我的一线希望。
【解决方案2】:

您在其中一个 cmets 中提供的日期字符串在每个日期部分 (?8/?5/?2014) 的开头包含三个 U+0000 字符,其中 ? 表示出现 U+0000

您需要去掉这些才能使日期生效。

【讨论】:

  • 如何删除这些多余的字符?我尝试使用字符串操作工具,但它们的作用是如果没有额外的字符。示例:Left(Dtaken, InStrRev(Dtaken, "?") - 1)
  • 它们实际上不是? 标记。您可以只使用 Regexp 替换所有不是数字或 / 的字符。
  • 我确信 Joel 的解决方案是更好的解决方案,但这是我能够开始工作的解决方案。我用Dtaken = System.Text.RegularExpressions.Regex.Replace(Dtaken, "[^\d /]", "")
【解决方案3】:

我不知道为什么一个String 能在另一个不能工作的地方工作。您通常必须将 String 转换为 DateTime 才能比较它们。请尝试以下操作:

Dim dt As DateTime = DateTime.Parse(Dtaken)

然后

If dt > cutoffDate Then

编辑:我将 Joel 的答案投票为最可能的解决方案,但为了附上 cmets,我将把它保留在这里。

【讨论】:

  • 我收到了与我从许多其他尝试纠正此问题时收到的相同错误:字符串未被识别为有效的日期时间。这是从监视窗口复制的 Dtaken 的值:‎8/‎5/‎2014 我看不出该字符串未被识别为日期的任何原因,但这个是:8/5/2014
  • 我将它们复制到 Notepad++ - 第一个字符串是 8/?5/?2014,第二个字符串是 8/5/2014
  • 感谢您发现不同之处。我尝试添加以下行: Dtaken = Date.ParseExact(Dtaken, "dd/MM/yyyy", System.Globalization.DateTimeFormatInfo.InvariantInfo) 但这没有影响。
猜你喜欢
  • 2015-03-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-03
  • 2011-12-18
  • 1970-01-01
  • 1970-01-01
  • 2011-07-30
  • 2015-02-09
相关资源
最近更新 更多