1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

「PowerShellでカンタンに勤務時間を割り出す方法」を自分用に魔改造

Posted at

元記事:PowerShellでカンタンに勤務時間を割り出す方法 - Qiita

勤怠管理は会社ごとに微妙に違う気がするので、結局自分で魔改造することになるんじゃないかと思った。

コード(原型がほぼない)

.ps1
# powershell -NoProfile -ExecutionPolicy RemoteSigned .\oreGWT.ps1 2016 05
# powershell -NoProfile -ExecutionPolicy RemoteSigned .\oreGWT.ps1 2016 05 -MakeEven

Param
(
    [Parameter(Mandatory=$True,HelpMessage="対象年を指定してください。")]
    [ValidateRange(0001,9999)]
    [int] $Year,

    [Parameter(Mandatory=$True,HelpMessage="対象月を指定してください。")]
    [ValidateRange(01,12)]
    [int] $Month,

    [ValidateRange(01,31)]
    [int] $Day = 01,

    [ValidateRange(00,23)]
    [int] $Hour = 04,

    [ValidateRange(00,59)]
    [int] $Minute = 00,

    [ValidateRange(00,59)]
    [int] $Second = 00,

    [string[]] $LogName = @('System', 'Application'), #, 'Security'),

    [string] $Delimiter = ',',

    [switch] $MakeEven
)
 
Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'

# 主処理
filter main
{
    $yyyyMM = '{0:0000}/{1:00}' -f $Year, $Month
    $dd     = '{0:00}' -f $Day
    $HHmmss = '{0:00}:{1:00}:{2:00}' -f $Hour, $Minute, $Second

    # イベントログの取得開始日時を指定
    $after = try   {Get-Date "${yyyyMM}/${dd} ${HHmmss}"}
             catch {Get-Date "${yyyyMM}/01 ${HHmmss}" | %{$_.AddMonths(1).AddDays(-1)}} # 月末日

    # ヘッダ出力
    @(
        '#起動日時',
        '#終了日時',
        '#経過時間',
        '#経過時間-休憩(1H)'
    ) -join $Delimiter

    # ShortDate ごとに明細を出力
    $LogName |
        ForEach-Object {Get-EventLog -LogName $_ -After $after -Before $after.AddMonths(1)} | # 一ヶ月分のイベントログ
        Select-Object -ExpandProperty TimeWritten | # 書込日時
        Group-Object -Property {Get-ShortDate $_} | # ShortDate ごとに集約
        Sort-Object Name | # ShortDate で並び替え
        ForEach-Object {New-Record $_.Group} # 明細出力
}

# 時刻補正後に日付の文字列を取得
filter Get-ShortDate ($date)
    {$date.AddHours(- $Hour).AddMinutes(- $Minute).AddSeconds(- $Second).ToShortDateString()}

# 新たな明細を作成
filter New-Record ($group)
{
    $min, $max = Get-MinMaxDate $group
            
    if ($MakeEven)
    {
        $min = Get-EvenDate $min
        $max = Get-EvenDate $max
    }

    @(
        (Get-Date $min -Format 'yyyy/MM/dd HH:mm:ss'),
        (Get-Date $max -Format 'yyyy/MM/dd HH:mm:ss'),
        ($max - $min),
        ($max - $min.AddHours(1)) # 休憩一時間
    ) -join $Delimiter
}

# 最小日時と最大日時を取得
filter Get-MinMaxDate ($times)
{
    # $times | Measure-Object -Maximum -Minimum | %{$_.Minimum, $_.Maximum}

    $min = Get-Date '9999/12/31 23:59:59'
    $max = Get-Date '0001/01/01 00:00:00'

    foreach ($t in $times)
    {
        if ($t -lt $min) {$min = $t}
        if ($t -gt $max) {$max = $t}
    }

    $min, $max
}

# 単位分への切り捨て、切り上げ
filter Get-EvenDate ($date, $unitMinute = 15)
{
    $zero = Get-Date $date -Format 'yyyy/MM/dd HH:00:00' | Get-Date
    $near = $zero

    0..[math]::Floor(60 / $unitMinute) |
        ForEach-Object {$_ * $unitMinute} |
        ForEach-Object {$zero.AddMinutes($_)} |
        Where-Object {($date - $_).Duration() -le ($date - $near).Duration()} |
        ForEach-Object {$near = $_}

    $near
}

main

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?