格式化字符串以在24小时内添加前导零

时间:2016-04-30 23:01:54

标签: string powershell datetime

我正在使用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而不是所需的"Prod - Sun 2:00" -match "\b(Thu|Fri|Sat|Sun).([012]?[0-9][:]\d{2})" | Out-Null $a = $Matches[2] $a.ToString("00:00")

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

  def changeset(model, params \\ :empty) do
    model
    |> cast(params, @required_fields, @optional_fields)
    |> validate_length(:description, min: 280)
    |> my_awesome_validation(:email)
  end

  def my_awesome_validation(email) do 
    # ??
  end

返回错误无法找到“ToString”的重载和参数count:“1”。

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

3 个答案:

答案 0 :(得分:3)

您无法在字符串上使用数字格式,因此您需要先将小时/分钟转换为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)

答案 1 :(得分:1)

你可以这样做:

"Prod - Sun 2:00" -match "\b(Thu|Fri|Sat|Sun).([012]?[0-9][:]\d{2})" | Out-Null
$a = $Matches[2]
$ts = [TimeSpan]::Parse($a)
$formatted = $ts.ToString("c").Substring(0, 5)
$formatted

02:00输出$formatted

答案 2 :(得分:0)

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

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

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

$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)
相关问题