[備忘録] PowerShell 日付・時刻データの変換と計算テクニック

## はじめに

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/86ec3772-2690-4412-8065-c8272647444b.png)

システム管理やデータ処理において、日付・時刻の操作は避けて通れない重要なスキルです。PowerShellを使って、日付・時刻データの変換や計算を効率的に行う方法を、実践的な例とともに備忘録します。

動作確認: Win11 Powershell 5.1 

## 基本的な日付・時刻の取得と表示

PowerShellでは`Get-Date`コマンドレットを使って現在の日付・時刻を取得できます。

```powershell
# 現在の日付・時刻を取得
$now = Get-Date
Write-Output $now

# 特定の形式で表示
Get-Date -Format "yyyy/MM/dd HH:mm:ss"
Get-Date -Format "yyyy年MM月dd日 dddd"

# ミリ秒まで含めた精密な時刻
Get-Date -Format "yyyy/MM/dd HH:mm:ss.fff"
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/6e551ff4-97ad-4eb0-9af2-4b0a52685fc3.png)


## 日付文字列の解析とDateTime型への変換

文字列形式の日付データをDateTime型に変換する方法を見てみましょう。

```powershell
# 標準的な日付形式の変換
$dateString = "2024-12-15 14:30:00"
$dateTime = [datetime]$dateString
Write-Output $dateTime.GetType()

# より厳密な変換（ParseExact）
$exactDate = [datetime]::ParseExact("20241215", "yyyyMMdd", $null)
Write-Output "変換結果: $exactDate"

# 複数の日付形式を処理
$dateStrings = @("2024-12-15", "12/15/2024", "15-Dec-2024")

foreach ($dateStr in $dateStrings) {
    try {
        $converted = [datetime]$dateStr
        Write-Output "$dateStr → $($converted.ToString('yyyy/MM/dd'))"
    }
    catch {
        Write-Warning "変換に失敗: $dateStr"
    }
}
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/9f9b8d9b-5f8c-4015-9f95-e50e765c963d.png)


## 日付・時刻の計算と操作

PowerShellでは、日付の加算・減算や期間の計算が簡単に行えます。

```powershell
# 特定の日付を基準とした計算
$baseDate = [datetime]"2024-06-01"
$tomorrow = $baseDate.AddDays(1)
$nextWeek = $baseDate.AddDays(7)
$nextMonth = $baseDate.AddMonths(1)

Write-Output "基準日: $($baseDate.ToString('yyyy/MM/dd'))"
Write-Output "翌日: $($tomorrow.ToString('yyyy/MM/dd'))"
Write-Output "1週間後: $($nextWeek.ToString('yyyy/MM/dd'))"

# 2つの日付間の期間を計算
$startDate = [datetime]"2024-01-01"
$endDate = [datetime]"2024-12-31"
$timeSpan = $endDate - $startDate

Write-Output "期間: $($timeSpan.Days) 日"
Write-Output "時間換算: $($timeSpan.TotalHours) 時間"
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/31745725-e74c-4707-868a-dbebde805315.png)

## 実践的な応用例

### 営業日の計算

```powershell
function Get-BusinessDays {
    param(
        [datetime]$StartDate,
        [datetime]$EndDate
    )
    
    $businessDays = 0
    $currentDate = $StartDate
    
    while ($currentDate -le $EndDate) {
        # 土曜日(6)と日曜日(0)を除外
        if ($currentDate.DayOfWeek -ne [System.DayOfWeek]::Saturday -and 
            $currentDate.DayOfWeek -ne [System.DayOfWeek]::Sunday) {
            $businessDays++
        }
        $currentDate = $currentDate.AddDays(1)
    }
    
    return $businessDays
}

# 使用例
$start = [datetime]"2024-12-01"
$end = [datetime]"2024-12-31"
$workDays = Get-BusinessDays -StartDate $start -EndDate $end
Write-Output "12月の営業日数: $workDays 日"
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/ded11dbd-68bd-4c17-9ac2-665be94e9b42.png)


### ログファイルの日付フィルタリング

```powershell
function Filter-LogByDate {
    param(
        [string]$LogPath,
        [datetime]$StartDate,
        [datetime]$EndDate
    )
    
    Get-Content $LogPath | ForEach-Object {
        if ($_ -match '(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})') {
            $logDate = [datetime]$matches[1]
            if ($logDate -ge $StartDate -and $logDate -le $EndDate) {
                $_
            }
        }
    }
}

# 使用例（過去7日間のログを抽出）
$sevenDaysAgo = (Get-Date).AddDays(-7)
$filteredLogs = Filter-LogByDate -LogPath "C:\logs\app.log" -StartDate $sevenDaysAgo -EndDate (Get-Date)
```

### ファイルの作成日時による整理

```powershell
function Organize-FilesByDate {
    param([string]$SourcePath)
    
    Get-ChildItem $SourcePath -File | ForEach-Object {
        $fileDate = $_.CreationTime
        $yearMonth = $fileDate.ToString("yyyy-MM")
        $destPath = Join-Path $SourcePath $yearMonth
        
        if (-not (Test-Path $destPath)) {
            New-Item -ItemType Directory -Path $destPath -Force
        }
        
        Write-Output "対象ファイル: $($_.Name) → $yearMonth フォルダ"
    }
}
```

## タイムゾーンの処理

```powershell
# UTC時刻への変換
$localTime = [datetime]"2024-06-15 14:30:00"
$utcTime = [System.TimeZoneInfo]::ConvertTimeToUtc($localTime)
Write-Output "ローカル時刻: $($localTime.ToString('yyyy/MM/dd HH:mm:ss'))"
Write-Output "UTC時刻: $($utcTime.ToString('yyyy/MM/dd HH:mm:ss'))"

# 特定のタイムゾーンに変換
$nyCTZ = [System.TimeZoneInfo]::FindSystemTimeZoneById("Eastern Standard Time")
$nyTime = [System.TimeZoneInfo]::ConvertTime($localTime, $nyCTZ)
Write-Output "ニューヨーク時刻: $($nyTime.ToString('yyyy/MM/dd HH:mm:ss'))"
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/e1b5d8d9-3a2a-47f4-90cf-df37d2b345c2.png)

## まとめ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/f3105678-c62b-45b9-ab53-5cb1e6fa6fdb.png)

PowerShellを使った日付・時刻データの操作は、システム管理からデータ分析まで幅広い場面で活用できる重要なスキルです。今回紹介した基本的な変換から実践的な応用例まで、これらのテクニックを組み合わせることで、複雑な日付計算やデータ処理も効率的に行えるようになります。

特に営業日計算やログ解析などの実務的な処理では、大幅な時間短縮が期待できるでしょう。継続的な学習として、.NET Frameworkの`DateTime`クラスの詳細な機能も併せて学習することをお勧めします。