modules/Helper/DateTimeFormula.psm1
class DateTimeFormula{ hidden [string[]] $UNITS = 'Y', 'Q', 'M', 'W', 'D', 'h', 'm', 's' hidden [string] $referentUnit hidden [bool] $isReferentNegative hidden [int] $referentValue hidden [string] $timespanUnit [bool] $isDateTimeFormula [bool] $isTimeSpanFormula [string] $formula [datetime] $datetime DateTimeFormula(){ } hidden [datetime] applyTimeSpanFormula([datetime] $datetime, [string]$formula){ $this.datetime = $datetime $ts = $this.getTimeSpanValue($formula) return ($datetime + $ts) } [datetime] getDateTimeValue([string] $formula){ $this.formula = $formula $this.identifyUnits() if ($this.isDateTimeFormula){ try { $this.datetime = $this.parseDateTime() } catch { $this.isDateTimeFormula = $false } } return $this.datetime } [timespan] getTimeSpanValue([string]$formula){ $ref = Get-Date $retValue = $ref try { $exp = $this.splitTimespanFormula($formula) foreach ($node in $exp.nodes) { switch -CaseSensitive ($node.unit) { 'Y' { $retValue = $retValue.AddYears($node.number) } 'Q' { $retValue = $retValue.AddMonths(3 * $node.number) } 'M' { $retValue = $retValue.AddMonths($node.number) } 'W' { $retValue = $retValue.AddDays(7 * $node.number) } 'D' { $retValue = $retValue.AddDays($node.number) } 'h' { $retValue = $retValue.AddHours($node.number) } 'm' { $retValue = $retValue.AddMinutes($node.number) } 's' { $retValue = $retValue.AddSeconds($node.number) } } } $this.isTimeSpanFormula = ($exp.nodes.Count -gt 0) } catch { $this.isTimeSpanFormula = $false } return ($retValue - $ref) } hidden [void] identifyUnits() { if ($this.formula.SubString(0,1) -eq '-') { $this.isReferentNegative = $true $this.formula = $this.formula.SubString(1) } elseif ($this.formula.SubString(0,1) -eq '+') { $this.isReferentNegative = $false $this.formula = $this.formula.SubString(1) } else { $this.isReferentNegative = $false } if ($this.formula.SubString(0, 2) -ceq 'WD') { $this.referentUnit = $this.formula.SubString(0, 2) if ($this.formula.Length -gt 2){ $this.referentValue = $this.formula.SubString(2, 1) $this.timespanUnit = $this.formula.SubString(3) } else { $this.referentValue = '0' $this.timespanUnit = '' } $this.isDateTimeFormula = $true } elseif ($this.formula.SubString(0, 1) -cin $this.UNITS) { #('Y', 'M', 'D', 'h', 'm') $this.referentUnit = $this.formula.SubString(0, 1) $haveValue = $false for($i=1; $i -lt $this.formula.Length; $i++){ if ($this.formula[$i] -cin ($this.UNITS + @('+', '-'))) { $this.referentValue = $this.formula.SubString(1, $i-1) $this.timespanUnit = $this.formula.SubString($i) $haveValue = $true break } } if (-not $haveValue){ $this.referentValue = $this.formula.SubString(1) $this.timespanUnit = '' } $this.isDateTimeFormula = $true } elseif ($this.formula.SubString(0, 1) -ceq 'C') { $this.referentUnit = $this.formula.SubString(0, 2) $this.timespanUnit = $this.formula.SubString(2) $this.isDateTimeFormula = $true } else { $this.isDateTimeFormula = $false } } hidden [datetime] parseDateTime(){ $retValue = [datetime]::MinValue $retValue = $this.getReferentDate($this.referentUnit) if ($this.timespanUnit) { $ts = $this.getTimeSpanValue($this.timespanUnit) $retValue = $retValue + $ts } return $retValue } hidden [datetime] getReferentDate([string]$value){ $date = Get-Date switch -CaseSensitive ($value){ 'CT' { $date = (Get-Date) } 'CY' { $date = (Get-Date -Year $date.Year -Month 1 -Day 1 -Hour 0 -Minute 0 -Second 0 -Millisecond 0) } 'CQ' { $date = (Get-Date -Year $date.Year -Month (3 * [Math]::Floor($date.Month / 3)) -Day 1 -Hour 0 -Minute 0 -Second 0 -Millisecond 0) } 'CM' { $date = (Get-Date -Year $date.Year -Month $date.Month -Day 1 -Hour 0 -Minute 0 -Second 0 -Millisecond 0) } 'CW' { $date = (Get-Date -Year $date.Year -Month $date.Month -Day $date.Day -Hour 0 -Minute 0 -Second 0 -Millisecond 0).AddDays(-$date.DayOfWeek) } 'CD' { $date = (Get-Date -Year $date.Year -Month $date.Month -Day $date.Day -Hour 0 -Minute 0 -Second 0 -Millisecond 0) } 'Ch' { $date = (Get-Date -Year $date.Year -Month $date.Month -Day $date.Day -Hour $date.Hour -Minute 0 -Second 0 -Millisecond 0) } 'Cm' { $date = (Get-Date -Year $date.Year -Month $date.Month -Day $date.Day -Hour $date.Hour -Minute $date.Minute -Second 0 -Millisecond 0) } 'Y' { if ($this.isReferentNegative) { $date = (Get-Date -Year $date.Year -Month 1 -Day 1 -Hour 0 -Minute 0 -Second 0 -Millisecond 0).AddYears(-$this.referentValue) } else { $date = (Get-Date -Year $this.referentValue -Month 1 -Day 1 -Hour 0 -Minute 0 -Second 0 -Millisecond 0) } } 'Q' { if ($this.isReferentNegative) { $date = (Get-Date -Year $date.Year -Month $date.Month -Day 1 -Hour 0 -Minute 0 -Second 0 -Millisecond 0).AddMonths(-3 * $this.referentValue) } else { $date = (Get-Date -Year $date.Year -Month 1 -Day 1 -Hour 0 -Minute 0 -Second 0 -Millisecond 0).AddMonths(3 * $this.referentValue) } } 'M' { if ($this.isReferentNegative) { $date = (Get-Date -Year $date.Year -Month $date.Month -Day 1 -Hour 0 -Minute 0 -Second 0 -Millisecond 0).AddMonths(-$this.referentValue) } else { $date = (Get-Date -Year $date.Year -Month $this.referentValue -Day 1 -Hour 0 -Minute 0 -Second 0 -Millisecond 0) } } 'W' { if ($this.isReferentNegative) { $date = (Get-Date -Year $date.Year -Month $date.Month -Day $date.Day -Hour 0 -Minute 0 -Second 0 -Millisecond 0).AddDays(-7 * $this.referentValue) } else { $date = (Get-Date -Year $date.Year -Month 1 -Day 1 -Hour 0 -Minute 0 -Second 0 -Millisecond 0).AddDays(7 * $date.DayOfWeek) } } 'D' { if ($this.isReferentNegative) { $date = (Get-Date -Year $date.Year -Month $date.Month -Day $date.Day -Hour 0 -Minute 0 -Second 0 -Millisecond 0).AddDays(-$this.referentValue) } else { $date = (Get-Date -Year $date.Year -Month $date.Month -Day $this.referentValue -Hour 0 -Minute 0 -Second 0 -Millisecond 0) } } 'h' { if ($this.isReferentNegative) { $date = (Get-Date -Year $date.Year -Month $date.Month -Day $date.Day -Hour $date.Hour -Minute 0 -Second 0 -Millisecond 0).AddHours(-$this.referentValue) } else { $date = (Get-Date -Year $date.Year -Month $date.Month -Day $date.Day -Hour $this.referentValue -Minute 0 -Second 0 -Millisecond 0) } } 'm' { if ($this.isReferentNegative) { $date = (Get-Date -Year $date.Year -Month $date.Month -Day $date.Day -Hour $date.Hour -Minute $date.Minute -Second 0 -Millisecond 0).AddMinutes(-$this.referentValue) } else { $date = (Get-Date -Year $date.Year -Month $date.Month -Day $date.Day -Hour $date.Hour -Minute $this.referentValue -Second 0 -Millisecond 0) } } 's' { if ($this.isReferentNegative) { $date = (Get-Date -Year $date.Year -Month $date.Month -Day $date.Day -Hour $date.Hour -Minute $date.Minute -Second $date.Second -Millisecond 0).AddSeconds(-$this.referentValue) } else { $date = (Get-Date -Year $date.Year -Month $date.Month -Day $date.Day -Hour $date.Hour -Minute $date.Minute -Second $this.referentValue -Millisecond 0) } } 'WD' { if ($this.isReferentNegative) { $date = (Get-Date -Year $date.Year -Month $date.Month -Day $date.Day -Hour 0 -Minute 0 -Second 0 -Millisecond 0).AddDays(-7).AddDays(-($date.DayOfWeek-$this.referentValue)) } else { $date = (Get-Date -Year $date.Year -Month $date.Month -Day $date.Day -Hour 0 -Minute 0 -Second 0 -Millisecond 0).AddDays(-($date.DayOfWeek-$this.referentValue)) } } default { $date = $null } } return $date } hidden [PSCustomObject] splitTimespanFormula([string] $value){ $retValue = [PSCustomObject]@{expression=$value; nodes=@()} $prev=0 for($i=0; $i -lt $value.Length; $i++){ if ($value[$i] -cin $this.UNITS){ $number = $value.Substring($prev, $i-$prev) $unit = $value.Substring($i, 1) $prev = $i + 1 $retValue.nodes += [PSCustomObject]@{number=[int]$number; unit=$unit} } } return $retValue } } |