Имя пользователя:
Пароль:  
Помощь | Регистрация | Забыли пароль?  | Правила  

Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Скриптовые языки администрирования Windows » PowerShell - Посчитать время с учётом рабочих часов

Ответить
Настройки темы
PowerShell - Посчитать время с учётом рабочих часов

Новый участник


Сообщения: 22
Благодарности: 0

Профиль | Отправить PM | Цитировать


Изображения
Тип файла: png Screenshot 2022-12-21 at 12.10.14.png
(17.8 Kb, 6 просмотров)
Всем привет!

Стоит задача посчитать сколько было затрачено времени в текущей задаче. В целом всё просто, использовал командлет Timespan, взял время старта, время конца, сложил и получил ответ:

Код: Выделить весь код
$FIRST_RESPONSE_TIME = New-TimeSpan -Start "$START_TIME_TICKET" -End "$END_TIME_TICKET"
Во вложении вывод.

Однако, есть нюанс, который заключается в SLA. Время останавливается на нерабочих часах. То есть должно на 19:00 время остановиться и в 9:00 следующего дня утром снова возобновиться. По итогу вывод должен быть не на 2 часа 17 минут, а просто на 1 час 32 минуты. Следовательно, если время будет начинаться, скажем с 20:00 часов, то считать он должен с 9:00 и до времени, когда будет $END_TIME_TICKET (например конечная дата 12:00 и того 3 часа итог, а не 16 часов, как он посчитается всё время).

И вот как посчитать время с учётом рабочих часов, вообще никаких идей нет, может у кого будут мысли как это сделать.

Заранее спасибо!!!

p.s. а и да, ещё нужно как-то учесть производственный календарь... в общем время должно считать строго в пороге от 9:00 до 19:00 буднего дня, а оставшееся выкидывать

Отправлено: 12:22, 21-12-2022

 

Аватара для YuS_2

Crazy


Contributor


Сообщения: 1231
Благодарности: 515

Профиль | Отправить PM | Цитировать


Ну и всё упрощает работа с производственным календарем... единственный минус - необходимо следить за наличием и содержанием самих календарей, собственно.
script_calendar.ps1
Код: Выделить весь код
# Пример работы со временем. Учет времени только в рабочее время (например 9:00 - 19:00),
# исключая выходные и праздничные дни по производственному календарю.
# в данном варианте использовались календари в текстовом виде, со списком выходных и праздничных
# дней. (http://xmlcalendar.ru/data/ru/2023/calendar.txt) (http://xmlcalendar.ru/)
# .\script_calendar.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),
	[string]$calendarpath = '.\Calendars\RUS' 
)
function get-timework {
	param (
		[datetime]$stt, # старт
		[datetime]$ett, # стоп
		[timespan]$start, # начало рабочего периода
		[timespan]$end, # конец рабочего периода
		# Каталог календарей в виде текстового списка (*.txt) с датами формата YYYY.MM.DD
		[string]$pathcr
	)
	if ($ett -le $stt) {
		write-host Ошибка! Проверьте данные '$stt - старт/ $ett - стоп' -for red
		break
	}
	$x = ($ett.date - $stt.date).days # количество дней между стартом и стопом
	# Считываем производственные календари (списки выходных и праздничных дней)
	$cal = gc ($pathcr + '\' + '*.txt')|%{get-date($_)}
	if ($stt.year -notin $cal.year -or $ett.year -notin $cal.year){
		write-host Отсутствует производственный календарь на год начала или конца периода! -for red
		break
	}
	$m = new-timespan -h ($end - $start).totalhours # Вычисляем рабочее время за день
	# укорачиваем код до названия переменных:
	$rs,$re = $stt.timeofday.totalminutes,$ett.timeofday.totalminutes
	$s,$e = $start.totalminutes,$end.totalminutes
	$minutes = $m.totalminutes
	# Если старт в вых. или праздник, перенос на ближайший р.день в большую сторону
	# и время обнуляется
	if ($x -and $stt.date -in $cal){
		$stt = $stt.addminutes(-$stt.timeofday.totalminutes)
		while ($stt.date -in $cal){
			$stt = $stt.adddays(1)
		}
	}
	# Если стоп в вых. или праздник, перенос на ближайший р.день в большую сторону
	# и время обнуляется
	if ($x -and $ett.date -in $cal){
		$ett = $ett.addminutes(-$ett.timeofday.totalminutes)
		while ($ett.date -in $cal){
			$ett = $ett.adddays(1)
		}
	}
	# переинициализация старта и стопа
	$rs,$re = $stt.timeofday.totalminutes,$ett.timeofday.totalminutes
	$x = ($ett.date - $stt.date).days # пересчет дней между стартом и стопом 
	$j = 0
	for ($i = 0; $i -le $x;$i++){
		#счетчик вых. и празд. по календарю
		if ($stt.adddays($i).date -in $cal){
			$j++
		}
	}
	# Вычисляем окончательное количество рабочих дней
	$x = $x - $j
	# Реализация логики подсчета для будней:
	if (!$x -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) {
		# Если старт и стоп в разные дни,
		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 -pathcr $calendarpath

-------
scio me nihil scire. Ѫ


Последний раз редактировалось YuS_2, 25-12-2022 в 07:27.

Это сообщение посчитали полезным следующие участники:

Отправлено: 14:40, 24-12-2022 | #11



Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети.

Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля.


Новый участник


Сообщения: 22
Благодарности: 0

Профиль | Отправить PM | Цитировать


Цитата YuS_2:
Ещё вариант, в котором поправлены ошибки и добавлен учет выходных: »
ох.. ёмаё, спасибо!!!
помотрю, проверю

господи, ты просто бомба!)

Отправлено: 13:45, 27-12-2022 | #12



Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Скриптовые языки администрирования Windows » PowerShell - Посчитать время с учётом рабочих часов

Участник сейчас на форуме Участник сейчас на форуме Участник вне форума Участник вне форума Автор темы Автор темы Шапка темы Сообщение прикреплено

Похожие темы
Название темы Автор Информация о форуме Ответов Последнее сообщение
2019 - [решено] Excel. Неправильное суммирование рабочих часов Tolea3 Microsoft Office (Word, Excel, Outlook и т.д.) 12 28-04-2020 17:20
[решено] Как посчитать время работа программы vk_k14m@vk Хочу все знать 6 04-06-2019 15:47
Flash - Как посчитать время записи файлов на флешку alleclf Накопители (SSD, HDD, USB Flash) 1 01-11-2016 18:39
Слетает дата и время на рабочих станциях Diman1989_19 Microsoft Windows NT/2000/2003 7 09-07-2014 09:45
сбрасывается время РОВНО на 9 часов назад! whattaff Непонятные проблемы с Железом 4 15-10-2010 21:26




 
Переход