【问题标题】:Format string to add leading zero in 24 hour time格式化字符串以在 24 小时内添加前导零
【发布时间】:2016-08-25 23:06:35
【问题描述】:

我正在使用 PowerShell 的 -match 运算符和正则表达式 \b(Thu|Fri|Sat|Sun).([012]?[0-9][:]\d{2}) 来获取重启应该发生的日期和时间。

样本数据:

Patching - Prod - Fri 2:00
Patching - Prod - Fri 22:00
Patching - Prod - Thu 22:00
Patching - Prod - Fri 22:00
Patching - Prod - Sat 18:00
Patching - Prod - Sun 2:00
Patching - Prod - Sun 00:00
Patching - Prod - Sat 2:00

$Rebootinfo = "Patching - Prod - Sat 2:00"

"$Rebootinfo" -match "\b(Thu|Fri|Sat|Sun).([012]?[0-9][:]\d{2})" | Out-Null

这很好用,但我发现当时间是 2:00 AM 时我得到 2:00 并且我希望用 02:00 的前导零填充该结果,如果时间是午夜,结果将是 0 而不是所需的 00:00

我一直在尝试this article 的建议,但没有成功。

"Prod - Sun 2:00" -match "\b(Thu|Fri|Sat|Sun).([012]?[0-9][:]\d{2})" | Out-Null

$a = $Matches[2]
$a.ToString("00:00")

返回错误找不到“ToString”的重载和参数计数:“1”。

我这样做的目标是将数据传递到 PowerShell 以获取距离重启时间的天数。例如,如果在周六运行,周日凌晨 2 点需要增加 1 天。

【问题讨论】:

    标签: string powershell datetime


    【解决方案1】:

    您不能对字符串使用数字格式,因此您需要先将小时/分钟转换为 int。举几个例子:

    #Convert 2:00 to 200 int-number and format it to 00:00-style -> 02:00.
    #18:00 -> 1800 -> 18:00
    "{0:00:00}" -f ([int]$a.Replace(":",""))
    

    或者

    #Capture hour and minutes in their own groups
    "Prod - Sun 2:00" -match "\b(Thu|Fri|Sat|Sun).([012]?[0-9])[:](\d{2})" | Out-Null
    #Format 00 only works with digits, so convert to int
    "{0:00}:{1:00}" -f [int]$Matches[2], [int]$Matches[3]
    

    或者您可以将其解析为 DateTime 并转换回具有正确格式的字符串(或者如果您愿意,可以使用 DateTime-object)。

    $date = [datetime]::ParseExact($Matches[0], "ddd H:mm", [cultureinfo]::InvariantCulture)
    $date.ToString("ddd HH:mm", [cultureinfo]::InvariantCulture)
    

    【讨论】:

    • @user4317867 鉴于您的问题历史,我建议使用第三种方法,而不将 DateTime 值转回字符串。这将为您提供下一个维护窗口的时间作为实际时间戳。
    【解决方案2】:

    你可以这样做:

    "Prod - Sun 2:00" -match "\b(Thu|Fri|Sat|Sun).([012]?[0-9][:]\d{2})" |外空 $a = $Matches[2] $ts = [时间跨度]::Parse($a) $formatted = $ts.ToString("c").Substring(0, 5) $格式化

    它为$formatted 输出02:00

    【讨论】:

    • 我最终将它与另一个代码 sn-p 一起使用,得到了我想要的价值,再次感谢!
    【解决方案3】:

    您的帖子似乎没有问题(目标,但不是问题)。所以我猜你的问题是“为什么正则表达式不返回'02:00AM'”?

    由于源字符串在 2 之前不包含零,因此您无法获得包含不在源字符串中的零的匹配项。您需要将其添加为单独的步骤。

    使用 .NET 内置的日期时间解析可以避免一些麻烦:[datetime]::parseexact。不幸的是,如果 Sun 不是当天,ParseExact 无法处理像“Sun 2:00AM”这样的字符串,因此需要做一些额外的工作。这是一些相同的示例代码。

    $Rebootinfo = "Patching - Prod - Thu 2:00AM"
    
    $splitUp = $Rebootinfo -split "\b(Thu|Fri|Sat|Sun)"
    # $splitUp[-1] now contains time and $splitUp[-2] contains day of week
    
    $cult = [Globalization.CultureInfo]::InvariantCulture
    try {
       $rebootTime = [datetime]::parseexact( $splitUp[-1], " h:mmtt", $cult)
    } catch {
       # put your own error handling here
       throw "Date time parse failed"
    }
    
    $weekDayToWeekDayNumber = @{Sun=0;Mon=1;Tue=2;Wed=3;Thu=4;Fri=5;Sat=6}
    $rebootWeekDayNumber = $weekDayToWeekDayNumber[$splitUp[-2]]
    $todayWeekDayNumber = $weekDayToWeekDayNumber[[datetime]::today.DayOfWeek.tostring().substring(0,3)]
    # This calculation fails if the reboot day of the week is same as current
    # day of week and reboot time is before current time. However I'm guessing 
    # this won't be a problem because if this
    # happens you've already missed the boot or the boot is almost a week away.
    # Assuming the later: since you only have days of the week (and not dates) 
    # I'm guessing that
    # boots almost a week away aren't a concern. The reason is that if you 
    # handle boots almost a
    # week away, there's no guarantee (that I see) that the boot won't be a 
    # little more than a week away (since you don't know exactly when the boot 
    # is, hence the script). And if boots can be more than a week away you won't 
    # be able to distinguish between boots this week and boots next week (since
    # you only have the day of the week).
    # However if this is a problem, just compare $rebootTime to [datetime]::now
    # and if less, then add 7 more days to $rebootTime.
    $rebootTime = $rebootTime.AddDays( ($rebootWeekDayNumber - $todayWeekDayNumber + 7) % 7)
    
    write-host Amount of time till reboot ($rebootTime - [datetime]::now)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-06-18
      • 2012-02-06
      • 2016-02-12
      • 1970-01-01
      • 2017-08-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多