如何在PowerShell中接收随机格式的日期
我有一个登录跟踪日志文件,它是多个源的合并。这些数据源(有很多)使用多种日期格式。我正在使用生成的$objList对象将它们移交给SQL数据库。当我尝试使用SQL查询时,我丢失了数据 以下是2007年9月的一小部分原始输入:如何在PowerShell中接收随机格式的日期,powershell,formatting,Powershell,Formatting,我有一个登录跟踪日志文件,它是多个源的合并。这些数据源(有很多)使用多种日期格式。我正在使用生成的$objList对象将它们移交给SQL数据库。当我尝试使用SQL查询时,我丢失了数据 以下是2007年9月的一小部分原始输入: 登录;用户名;Server01;10/09/2007 09:56:40 登录;用户名;Server02;10/09/2007 11:26:20 登录;用户名;服务器03;2007年9月11日上午10:16:27 登录;用户名;服务器04;11/09/2007 12:28:4
IF ($SplitUsr.Count -eq '4')
{
$varAction = $SplitUsr[0]
IF ($varAction -eq 'Logon')
{
$varActionx = $SplitUsr[0].Trim()
$varUser = $SplitUsr[1].Trim()
$varHostname = $SplitUsr[2].Trim()
$varTime = $SplitUsr[3].Trim()
try {$datetime = [dateTime]::Parse("$varTime",([Globalization.CultureInfo]::CreateSpecificCulture('en-GB')))}
catch [System.Management.Automation.MethodInvocationException]
{
$datetime = [dateTime]::Parse("$varTime",([Globalization.CultureInfo]::CreateSpecificCulture('en-US')))
}
$objLogon = New-Object PSObject
$objLogon | Add-Member -Membertype NoteProperty -Name "Entry" -Value $intCount
$objLogon | Add-Member -Membertype NoteProperty -Name "Logon" -Value '1'
$objLogon | Add-Member -Membertype NoteProperty -Name "User" -Value $varUser
$objLogon | Add-Member -Membertype NoteProperty -Name "Hostname" -Value $varHostname
$objLogon | Add-Member -Membertype NoteProperty -Name "Date" -Value $datetime
$objList += $objLogon
不幸的是,这将它们解析为
$dates = @( '10/09/2007 09:56:40',
'09/10/2007 11:26:20',
'10/09/2007 10:16:27 AM',
'10/09/2007 12:28:45' )
$cultureUS = [CultureInfo]::CreateSpecificCulture("en-US")
$cultureEU = [CultureInfo]::CreateSpecificCulture("en-GB")
$maxDays = 2 # Max. allowed difference between current date and former date in days
for( $i = 0; $i -lt $dates.Count; $i++ ) {
$currentDate = [DateTime]::Parse( $dates[ $i ],$cultureEU )
if( $i -gt 0 ) {
$diffPast = New-TimeSpan -Start $lastDate -End $currentDate
}
else {
$diffPast = New-TimeSpan -Start $currentDate -End $currentDate
}
if( $diffPast.Days -gt $maxDays ) {
# check if month of current date is day of last date => culture issue
if( $currentDate.Day -eq $lastDate.Month -or $currentDate.Month -eq $lastDate.Day ) {
$currentDate = [DateTime]::Parse( $dates[ $i ],$cultureUS )
}
}
$currentDate
$lastDate = $currentDate
}
不幸的是,并非所有的AM/PM都表示美国日期格式
没有其他信息,您无法解决问题,因为固有的模糊性:
9/11/2007 10:16:27 AM
无法判断这是指9月11日(第一个月)的en-US
(美国)时间戳,还是指11月9日(第一天)的en-GB
(英国)时间戳
只有当第一个或第二个组件恰好为13
或更高时,才会隐含en-US
或en-GB
,并且只有这样的时间戳才会被问题中的try
/catch
逻辑正确处理
如果您提供了所有日期都必须满足的附加约束,则可以找到解决方案。 例如,如果您知道所有日期都属于给定的月份: 上述结果表明,所有日期都被解析为月份
9
(9月)日期:
2007年9月11日星期二下午5:02:15
2007年9月11日星期二下午5:02:44
2007年9月11日星期二下午5:03:01
使用
[datetime]::tryparse
方法可能会更幸运。而且,您的示例没有跟踪。你在最后说“你可以看到”关于得到12&7反转,但我看不到,因为你没有发布任何与错误对应的原始数据让我追溯它。你的一小部分原始数据来自9月,但你的“明显”例子来自7月或12月。请阅读创建一个好的例子,看看你是否能编辑你的文章。我发布的第一个例子也是不正确的。在九月输出的中间有一个十一月,它是9和11倒置的。我只添加了七月和十二月的例子,因为它们在视觉上更加突出,因为单词本身的长度不同。为了让这一点更清楚,我要重申一下。为了使这一点起作用,你必须查看你的数据,并制定一套始终有效的规则。如果它看起来像这样,那么就这样解释它。如果它看起来像另一件事,那么用另一种方式来解释它。因为您可以访问完整的列表,所以您更有可能找出一组有效的规则。一旦你这样做了,为每种类型的数据写一个转换器,你就得到了答案。我希望你能明白这一点。请允许我给你给新来者的标准建议:如果一个答案解决了你的问题,请点击大复选标记(✓) 在它旁边,也可以选择向上投票(向上投票需要至少15个信誉点)。如果您发现其他答案有帮助,请向上投票。接受(为此您将获得2个信誉点)向上投票有助于未来的读者。如果您的问题还没有完全回答,请提供反馈或。我尝试了一下。不幸的是,并非所有的AM/PM都表示美国日期格式。我从尝试中发现了一些。我将它们添加到了原始帖子中。@RickRDR如果不是所有的AM/PM都是美国格式,那么如果2020年1月2日是2月1日,程序怎么知道呢是一月二日还是一月二日?@f6a4这正是我希望在这里得到的答案。我所知道的是,对于一个人来说,有一大串的台词是显而易见的(例如)12月,无论日期是以何种方式编写的。我希望得到一些逻辑,可以帮助我通过PoSh以编程方式执行同样的操作。请重试。此脚本检查前一个日期是否接近当前日期。如果不接近,请检查是否是日期区域性问题。假设:第一个日期是EU区域性!!!这让我更接近逻辑c我可以使用。因为这些都是特定用户的登录,所以我必须考虑年假或b之类的事情
# The month that all log entries are expected to fall into:
$refMonth = 9 # September, for example.
# Create an array of the cultures to use for parsing:
[cultureinfo[]] $cultures = 'en-GB', 'en-US'
'11/9/2007 17:02:15',
'9/11/2007 05:02:44 PM',
'11/9/2007 05:03:01 PM' | ForEach-Object {
$ok = $false; [datetime] $dt = 0
foreach ($culture in $cultures) {
$ok = [datetime]::TryParse($_, $culture, 'None', [ref] $dt) -and $dt.Month -eq $refMonth
if ($ok) { break }
}
if (-not $ok) { Write-Error "Not recognized as a date in the expected month: $_" }
else { $date } # Output the resulting date.
}