PowerShell - Посчитать время с учётом рабочих часов

Ответить
 • Просмотры: 1
Аватара пользователя
YuS_2

Re: PowerShell - Посчитать время с учётом рабочих часов

Сообщение YuS_2 »

Ещё вариант, в котором поправлены ошибки и добавлен учет выходных:



script.ps1

[spoiler]Код:
[/spoiler]

Код: Выделить всё

# Пример работы со временем. Учет времени только в рабочее время (9:00 - 19:00),
# исключая выходные (суб., вск.).
# .\script.ps1 -stime $(get-date("21.12.2022 19:50")) -etime $(get-date("22.12.2022 17:00"))
param (
	[datetime]$stime = $(get-date("21.12.2022 8:00")),
	[datetime]$etime = $(get-date("22.12.2022 8:00")),
	[timespan]$startwork = $(new-timespan -h 9 -min 0),
	[timespan]$endwork = $(new-timespan -h 19 -min 0)
)
function get-timework {
	param (
		[datetime]$stt, # старт
		[datetime]$ett, # стоп
		[timespan]$start, # начало рабочего периода
		[timespan]$end # конец рабочего периода
	)
	function get-weekend {
		param (
			[datetime]$sd,
			[datetime]$ed,
			[int[]]$weekend = @(6,0)
		)
		$sub = ($ed.date - $sd.date).days
		$arr = @()
		for ($i = 0; $i -le $sub;$i++){
			#формируем массив выходных за период, для дальнейшего подсчета пар
			if ($sd.adddays($i).dayofweek.value__ -in $weekend){
				$arr += $sd.adddays($i).dayofweek.value__
			}
		}
		if ($arr){
			$out = ($arr.where({$_ -eq $weekend[0]},5)|%{$_.count}|sort -d)[0]
		} else {$out = 0}
		return $out
	}
	if ($ett -le $stt) {
		write-host Ошибка! Проверьте данные '$stt - старт/ $ett - стоп' -for red
		break
	}
	$m = new-timespan -h ($end - $start).totalhours
	$x = ($ett.date - $stt.date).days # количество дней между стартом и стопом
	$w, $h = @(1,2,3,4,5), @(6,0) # будни, выходные (суббота и воскресенье)
	# укорачиваем код до названия переменных:
	$sdw,$edw = $stt.dayofweek.value__,$ett.dayofweek.value__ # номер дня недели для старт и стоп
	$rs,$re = $stt.timeofday.totalminutes,$ett.timeofday.totalminutes
	$s,$e = $start.totalminutes,$end.totalminutes
	$minutes = $m.totalminutes
	# Для выходных:
	if ($edw -in $h){
		# Если стоп в выходной день (перенос стопа на пон. 0:00)
		if (!$edw){$ds = 1} else {$ds = 2}
		$ett = $ett.addminutes(-$ett.timeofday.totalminutes)
		$ett = $ett.adddays($ds)
		$edw,$re = $ett.dayofweek.value__,$ett.timeofday.totalminutes
		$x = ($ett.date - $stt.date).days
	}
	if ($sdw -in $h){
		# Если старт в выходной день (перенос старта на пон. 0:00)
		if (!$sdw){$ds = 1} else {$ds = 2}
		$stt = $stt.addminutes(-$stt.timeofday.totalminutes)
		$stt = $stt.adddays($ds)
		$sdw,$rs = $stt.dayofweek.value__,$stt.timeofday.totalminutes
		$x = ($ett.date - $stt.date).days
	}
	$kw = get-weekend $stt $ett # количество пар выходных между стартом и стопом
	if ($stt.dayofweek.value__ -in $h -and $kw){$kw--}
	if ($x -and $sdw -in $w -and $edw -in $w){
		# Если есть полный переход через выходные, 
		# старт/стоп в рабочие дни, вычитаем выходные полностью:
		$x = $x - 2*$kw
	}
	# Реализация логики подсчета для будней:
	if (!$x -and $sdw -in $w -and $edw -in $w -and $re -ge $rs){
		# Если и старт, и стоп в один день
		if($rs -lt $s -and $re -gt $e){
			$time = new-timespan -min ($minutes)
		} elseif (($rs -ge $s -and $rs -le $e) -and $re -gt $e){
			$time = new-timespan -min ($e - $rs)
		} elseif (($rs -gt $e -and $re -gt $e) -or ($rs -lt $s -and $re -lt $s)){
			$time = new-timespan
		} elseif ($rs -lt $s -and ($re -ge $s -and $re -le $e)) {
			$time = new-timespan -min ($re - $s)
		} elseif (($rs -ge $s -and $rs -le $e) -and ($re -ge $s -and $re -le $e)){
			$time = new-timespan -min ($re - $rs)
		}
	} elseif ($x -and $sdw -in $w -and $edw -in $w) {
		# Если старт и стоп в разные дни,
		if ($rs -lt $s -and $re -gt $e){
			$time = new-timespan -min ($minutes * ($x+1))
		} elseif (($rs -ge $s -and $rs -le $e) -and $re -gt $e){
			$time = new-timespan -min ($e - $rs + $minutes*$x)
		} elseif (($rs -gt $e -and $re -gt $e) -or ($rs -lt $s -and $re -lt $s)){
			$time = new-timespan -min ($minutes * $x)
		} elseif ($rs -lt $s -and ($re -ge $s -and $re -le $e)){
			$time = new-timespan -min ($re - $s + $minutes*$x)
		} elseif (($rs -ge $s -and $rs -le $e) -and ($re -ge $s -and $re -le $e)){
			$time = new-timespan -min ($re - $s + $e - $rs + $minutes*($x-1))
		} elseif ($rs -gt $e -and ($re -ge $s -and $re -le $e)) {
			$time = new-timespan -min ($re - $s + $minutes*($x-1))
		} elseif (($rs -ge $s -and $rs -le $e) -and $re -lt $s){
			$time = new-timespan -min ($e - $rs + $minutes*($x-1))
		} elseif ($rs -gt $e -and $re -lt $s) {
			$time = new-timespan -min ($minutes*($x-1))
		} 
	} else {
		write-host Условия не сработали... для будущей разработки. -for cyan
	}
	return $time
}
get-timework -stt $stime -ett $etime -start $startwork -end $endwork
Аватара пользователя
Njem

Re: PowerShell - Посчитать время с учётом рабочих часов

Сообщение Njem »

Цитата YuS_2:



Ещё вариант, в котором поправлены ошибки и добавлен учет выходных:
PowerShell - Посчитать время с учётом рабочих часов




ох.. ёмаё, спасибо!!!

помотрю, проверю



господи, ты просто бомба!)
Ответить

Вернуться в «Скриптовые языки администрирования Windows»