问题:

问题:

我正在通过Media Created以下方式从文件资源管理器中检索列字段:

$mCreated = $shellfolder.GetDetailsOf($shellfile, 208);

一切正常。它返回字符串“5/‎7/‎2017 ‏‎4:09 PM”

问题:

当我尝试将字符串转换为格式化的日期时,出现此错误:

Exception calling "ParseExact" with "3" argument(s): "String was not recognized as a valid DateTime."
At C:\Client\testVideos\anotherTest.ps1:28 char:9
+         $formattedDate = [Datetime]::ParseExact("$mCreated".Trim(), ' ...
+         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : FormatException

我尝试过的:

单独尝试了这些但都给出了相同的错误:

$formattedDate = [Datetime]::ParseExact("$mCreated".Trim(), 'yyyyMMddTHHmmss', $null)
$formattedDate = [Datetime]::ParseExact("$mCreated".Trim(), 'yyyyMMddTHHmmss', [Globalization.CultureInfo]::InvariantCulture)

# This line actually gives me a different error
$formattedDate = Get-Date "$mCreated".Trim() -Format "yyyyMMddTHHmmss"

# ERROR: Get-Date : The input object cannot be bound to any parameters for the command either because the command does not take pipeline input or the input and its properties do not match any of the parameters that take pipeline input

有效的方法:

我也一直Created Date在使用相同的代码并以相同的方式格式化它,并且它可以起作用!

创建日期为“2021 年 2 月 12 日下午 1:10”、“2021 年 2 月 4 日下午 3:39”、“2021 年 2 月 2 日上午 9:00”或“2021 年 2 月 4 日下午 3:54”

# This formats it successfully with no error
$createdDate = $shellfolder.GetDetailsOf($shellfile, 4);
$formattedDate = $createdDate | Get-Date -Format "yyyyMMddTHHmmss"

相关但最终无益的:

https://stackoverflow.com/questions/42784919/parseexact-string-was-not-recognized-as-a-valid-datetime https://stackoverflow.com/questions/48637312/convert-string-to-powershell-datetime

答案1

我以前也遇到过同样的问题,该Folder.GetDetailsOf()方法返回了各种日期。我发现问题是Unicode 格式字符

PS C:\> $TestFile = 'C:\Users\keith\Music\ABBA\Hits\03 Dancing Queen.wma'

>> $ofolder  = $Shell.NameSpace((Split-Path $TestFIle))
>> $oFile    = $oFolder.ParseName((Split-Path $TestFile -Leaf))
>>
>> $MediaCreated = $oFolder.GetDetailsOf($oFile, 208)
>> $MediaCreated
>> $MediaCreated.Length
>> [Int[]][Char[]]$MediaCreated -join '-'
>>
‎6/‎19/‎2010 ‏‎11:54 PM
23
8206-54-47-8206-49-57-47-8206-50-48-49-48-32-8207-8206-49-49-58-53-52-32-80-77
PS C:\>>[DateTime]$MediaCreated
Cannot convert value "‎6/‎19/‎2010 ‏‎11:54 PM" to type "System.DateTime". Error:
"String was not recognized as a valid DateTime."
At line:1 char:1
 + [DateTime]$MediaCreated
 + ~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [], RuntimeException
    + FullyQualifiedErrorId : InvalidCastParseTargetInvocationWithFormatProvider

我的解决方案是在正则表达式中将有效的 DateTime 字符列入“白名单”。因此,正则表达式匹配的“好”字符如下:

  • \w任何单词字符(0..9、“A”、“P”和“M”)
  • \:冒号(时间分隔符)
  • /斜线(日期分隔符)
  • 空间

分隔符可能因地区而异。为了简单、简洁和省事,我硬编码为美国。

这些可以组合起来并用括号括起来以创建一个字符类将匹配有效的人物。:

  • [\w\:/ ]

反转类别并匹配无效的字符,在类定义前添加一个插入符号:

  • [^\w\:/ ]

然后我们可以使用-更换操作员 删除它们:

  • [DateTime]($MediaCreated -replace '[^\w\:/ ]','')
PS C:\> $MediaCreated = [DateTime]($MediaCreated -replace '[^\w\:/ ]','')
PS C:\>>$MediaCreated

Saturday, June 19, 2010 11:54:00 PM


PS C:\>>$MediaCreated.GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     DateTime                                 System.ValueType

最近才了解到替代方案:ShellFolderItem.ExtendedProperty()

从项目的属性集中获取属性的值。可以通过名称或属性集的格式标识符 (FMTID) 和属性标识符 (PID) 指定属性。

返回值类型:Variant*

此方法返回时,包含属性的值(如果指定项存在)。该值将具有完整类型 — 例如,日期将以日期形式返回,而不是字符串。

如果属性有效但对于指定的项目不存在,则此方法返回零长度字符串,否则返回错误代码。

备注 指定属性有两种方法。第一种方法是将属性的已知名称(如“Author”或“Date”)分配给 sPropName。但是,每个属性都是组件对象模型 (COM) 属性集的成员,也可以通过指定其格式 ID (FMTID) 和属性 ID (PID) 来标识。FMTID 是标识属性集的 GUID,PID 是标识属性集中特定属性的整数。

通过属性的 FMTID/PID 值指定属性通常比使用其名称更有效。要将属性的 FMTID/PID 值与 ExtendedProperty 一起使用,必须将它们组合成 SCID。SCID 是一个字符串,其中包含“FMTID**PID”格式的 FMTID/PID 值,其中 FMTID 是属性集 GUID 的字符串形式。例如,摘要信息属性集的作者属性的 SCID 为“{F29F85E0-4FF9-1068-AB91-08002B27B3D9} 4”。

我找不到“Media Created”的正确名称,但 * FMTID/PID* 对是"{2E4B640D-5019-46D8-8881-55414CC5CAA0}100"

PS C:\>>$oFile.ExtendedProperty("MediaCreated")
PS C:\> $oFile.ExtendedProperty("Media Created")
PS C:\> $oFile.ExtendedProperty("MediaEncoded")
PS C:\> $oFile.ExtendedProperty("MediaCreationDate")
PS C:\> $oFile.ExtendedProperty("System.MediaEncoded")
PS C:\>>$oFile.ExtendedProperty("{2E4B640D-5019-46D8-8881-55414CC5CAA0}100")

Sunday, June 20, 2010 04:54:26 AM


PS C:\>>($oFile.ExtendedProperty("{2E4B640D-5019-46D8-8881-55414CC5CAA0}100")).GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     DateTime                                 System.ValueType

答案2

继续我的评论,顺便说一句,您也可以这样做进行格式化。

($mCreated = (Get-Date -Format g).ToString())
# Results
<#
2/16/2021 11:10 AM
#>

($mCreated).GetType() | 
Format-Table -AutoSize
# Results
<#
IsPublic IsSerial Name   BaseType     
-------- -------- ----   --------     
True     True     String System.Object
#>

$mCreated | 
Get-Member
# Results
<#
TypeName: System.String

Name             MemberType            Definition                                                                                                     
----             ----------            ----------                                                                                                     
...                                                                     
Chars            ParameterizedProperty char Chars(int index) {get;}                                                                                   
Length           Property              int Length {get;} 
#> 

                                                                                        

将日期字符串转换为日期时间对象

([DateTime]$mCreated = ((Get-Date -Format g).ToString()))
# Results
<#
Tuesday, February 16, 2021 11:12:00 AM
#>

($mCreated).GetType() | 
Format-Table -AutoSize
# Results
<#
IsPublic IsSerial Name     BaseType        
-------- -------- ----     --------        
True     True     DateTime System.ValueType
#>

$mCreated | 
Get-Member
# Results
<#
TypeName: System.DateTime

Name                 MemberType     Definition                                                                                                        
----                 ----------     ----------                                                                                                        
...                                                    
ToUniversalTime      Method         datetime ToUniversalTime()                                                                                        
Date                 Property       datetime Date {get;}                                                                                              
Day                  Property       int Day {get;}                                                                                                    
DayOfWeek            Property       System.DayOfWeek DayOfWeek {get;}                                                                                 
DayOfYear            Property       int DayOfYear {get;}                                                                                              
Hour                 Property       int Hour {get;}                                                                                                   
Kind                 Property       System.DateTimeKind Kind {get;}                                                                                   
Millisecond          Property       int Millisecond {get;}                                                                                            
Minute               Property       int Minute {get;}                                                                                                 
Month                Property       int Month {get;}                                                                                                  
Second               Property       int Second {get;}                                                                                                 
Ticks                Property       long Ticks {get;}                                                                                                 
TimeOfDay            Property       timespan TimeOfDay {get;}                                                                                         
Year                 Property       int Year {get;}                                                                                                   
DateTime             ScriptProperty System.Object DateTime {get=if ((& { Set-StrictMode -Version 1; $this.DisplayHint }) -ieq  "Date")... 
#>

更多详情请见:

至于具有 parseexact 的字符串。它受系统日期设置方式的影响,并且 yeat 必须位于时间戳的开头或结尾。请在此处查看详细信息:

[datetime]::ParseExact("20181010134412",'yyyyMMddHHmmss',$null)
# Results
<#
Wednesday, October 10, 2018 1:44:12 PM
#>

($mCreated).GetType() | 
Format-Table -AutoSize
# Results
<#
IsPublic IsSerial Name   BaseType     
-------- -------- ----   --------     
True     True     String System.Object
#>

[datetime]::ParseExact($mCreated,'yyyyMMddHHmmss',$null)
[datetime]::ParseExact($($mCreated),'yyyyMMddHHmmss',$null)
# Results
<#
Exception calling "ParseExact" with "3" argument(s): "String was not recognized as a valid DateTime."
#>

$mCreated
# Results
<#
2/16/2021 11:24 AM
#>

[datetime]::ParseExact('20210216112400','yyyyMMddHHmmss',$null)
[datetime]::ParseExact('02161124002021','MMddHHmmssyyyy',$null)
# Results
<#
Tuesday, February 16, 2021 11:24:00 AM
Tuesday, February 16, 2021 11:24:00 AM
#>

或者你最终会到达这里:

$mCreated = '16/02/2021 9:11 AM'
([datetime]::ParseExact($mCreated,'dd/MM/yyyy h:mm tt',$null))
$mCreated = '02/16/2021 9:11 AM'
([datetime]::ParseExact($mCreated,'MM/dd/yyyy h:mm tt',$null))
# Results
<#
Tuesday, February 16, 2021 9:11:00 AM
Tuesday, February 16, 2021 9:11:00 AM
#>

详细信息请见此处:

尝试使用调用中的日期字符串时,存在无法打印/不可见字符的问题。

$FileInformation    = Get-ItemProperty -Path 'F:\Videos\2020 03 19 Competitive Intel.mp4'
$ShellApplication   = New-Object -ComObject Shell.Application

$ShellFolder        = $ShellApplication.Namespace($FileInformation.Directory.FullName)
$ShellFile          = $ShellFolder.ParseName($FileInformation.Name)

$MetaDataProperties = [ordered] @{}

0..400 | 
ForEach-Object -Process {
    $DataValue     = $ShellFolder.GetDetailsOf($null, $_)
    $PropertyValue = (Get-Culture).TextInfo.ToTitleCase($DataValue.Trim()).Replace(' ', '')

    if ($PropertyValue -ne '') 
    {$MetaDataProperties["$_"] = $PropertyValue}
}

$MetaDataProperties.Values -Match 'media'
# Results
<#
MediaCreated
#>

###
($MediaCreated = $ShellFolder.GetDetailsOf($ShellFile , 208))
($DateCreated  = $ShellFolder.GetDetailsOf($ShellFile , 4))
($MediaCreated).GetType()
($DateCreated).GetType()
# Results
<#
19-‎Mar-‎20 ‏‎17:30
03-Dec-20 13:05

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


($TestDate = Get-Date(Date) -Format g) 
($TestDate1 = Get-Date(Date) -Format g) -replace '-|\s|:'
# Results
<#
17-Feb-21 16:41
17Feb211641
#>

([datetime]::ParseExact($TestDate,'dd-MMM-yy HH:mm',$null))
([datetime]::ParseExact($TestDate1,'dd-MMM-yy HH:mm',$null))
# Results
<#
Wednesday, 17 February, 2021 16:54:00
Wednesday, 17 February, 2021 16:54:00
#>

(('17-Feb-21 16:41').ToCharArray()).Count
# Results
<#
15
#>


([datetime]::ParseExact($MediaCreated,'dd-MMM-yy HH:mm',$null))
# Results
<#
Exception calling "ParseExact" with "3" argument(s): "String was not recognized 
as a valid DateTime."
#>

在常规 cmd.exe(而不是来自 PowerShell(ISE/consolehost)或通过 Windows 终端的 cmd.exe)中,存在记事本/consolehost/ISE/VSCode/Windows 终端中不会出现的不可打印/不可见字符。

在此处输入图片描述

(($MediaCreated).ToCharArray()).Count
# Results
<#
20  # multiple hidden/non-printable characters
#>

($MediaCreated).ToCharArray() 
# Results
<#
1
9
-
M
a
r
-
2
0

1
7
:
3
0 

#>

(($MediaCreated).ToCharArray())[0]
(($MediaCreated).ToCharArray())[1]
(($MediaCreated).ToCharArray())[2]
(($MediaCreated).ToCharArray())[3]
# Results
<#
1
9
-

#>

($MediaCreated).ToCharArray() | 
ForEach{ [int][char]$PSItem }
# Results
<#
8206
49
57
45
8206
77
97
114
45
8206
50
48
32
8207
8206
49
55
58
51
48
#>

这就是 Keiths 的正则表达式有效的原​​因......

([datetime]::ParseExact(($MediaCreated -replace '[^\w\:/ ]'),'ddMMMyy HH:mm',$null))
# Results
<#
Thursday, 19 March, 2020 17:30:00
#>

...因此我们可以更直接地获得它,以允许 parseexact 工作,而不必改变数据类型:

$FileInformation  = Get-ItemProperty -Path 'F:\Videos\2020 03 19 Competitive Intel.mp4'
$ShellApplication = New-Object -ComObject Shell.Application

$ShellFolder      = $ShellApplication.Namespace($FileInformation.Directory.FullName)
$ShellFile        = $ShellFolder.ParseName($FileInformation.Name)

($MediaCreated    = $ShellFolder.GetDetailsOf($ShellFile , 208))
($DateCreated     = $ShellFolder.GetDetailsOf($ShellFile , 4))
# Results
<#
‎19-‎Mar-‎20 ‏‎17:30
03-Dec-20 13:05
#>

($MediaCreated).GetType()
($DateCreated).GetType()

# Results
<#
IsPublic IsSerial Name     BaseType     
-------- -------- ----     --------     
True     True     String   System.Object
True     True     String   System.Object 
#>        

([datetime]::ParseExact(($MediaCreated -replace '[^\w\:/ ]'),'ddMMMyy HH:mm',$null))
([datetime]::ParseExact(($DateCreated -replace '[^\w\:/ ]'),'ddMMMyy HH:mm',$null))
# Results
<#

Thursday, 19 March, 2020 17:30:00
Thursday, 3 December, 2020 13:05:00
#>

($MediaCreated).GetType()
($DateCreated).GetType()
# Results
<#

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

相关内容