Что нового

Получить время в качестве переменной для проверки условия

Malderin

Новичок
Сообщения
68
Репутация
1
Задача стоит такая.
Есть текстовый файл ,например такой, log.log:
Код:
[History]
10.09.2014 15:23:43= Старт(2)
10.09.2014 15:23:44=Текст для поиска
10.09.2014 15:38:58 Кол=2
10.09.2014 15:38:49= Старт (11)
10.09.2014 15:54:01=Текст для поиска
10.09.2014 15:38:58 Кол=22
10.09.2014 15:55:49= Старт (23)
11.09.2014 7:15:01=Текст для поиска
11.09.2014 7:38:58 Кол=22
11.09.2014 7:55:49= Старт (12)

Строки, аналогично представленным выше, записываются в файл с текущим датой и временем, т.е. пополняются периодически.
Требуется найти последнее упоминание фразы "Текст для поиска" и взять от него в переменную дату и время для проверки условия.
Условие должно быть, например, такое:
если с момента последней записи с искомым текстом прошло более 30 минут, то выполнить какое то действие.

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

Код:
#Include <File.au3>
#include <Array.au3>

Global $i
Global $path = @ScriptDir&"\Log.log"
Local $sStartDateTime, $stat
$Path = @ScriptDir&"\log.log"

If @error Then 
	MsgBox(4096, "", "Лог создан")
	$sStartDateTime = StringFormat("%02d.%02d.%04d %02d:%02d:%02d ", @MDAY, @MON, @YEAR, @HOUR, @MIN, @SEC)
	IniWrite("log.log", "History", $sStartDateTime, " log.log создан")
	EndIf

dim $stat = IniReadSection($Path,"History")
For $i = 1 To $stat[0][0]
	If (StringInStr($stat[$i][1], 'Текст для поиска')) Then
	$i1=StringFormat ($stat[$i][0])
	EndIf
Next
MsgBox(4096, "", "Последнее совпадение "&$i1)
	_ArrayDisplay($stat)


Но вот как составить условие с временем не знаю, пытался искать но не нашел ничего что помогло бы понять как это сделать.
 

oesoes

xor eax,eax
Сообщения
171
Репутация
9
Что-то если честно, на вид ваш код даже не рабочий... но могу ошибаться... По делу: Берешь время нужной записи, сразу же делаешь слепок даты текущей в таком формате:

Код:
_DateTimeFormat(@YEAR & "." & @MON & "." & @MDAY & " " & @HOUR & ":" & @MIN & ":" & @SEC, 0)


Ну и функцией из _DateDiff_2.au3 вычисляешь разницу. Если разница в минутах на 30, то и делаешь свои дела.

#include <_DateDiff_2.au3> - там функция для вычисления разницы между двух дат (времени). Спасибо тов. AZJIO. Пример есть в справке по Custom UDFs.
 
Автор
M

Malderin

Новичок
Сообщения
68
Репутация
1
oesoes сказал(а):
Что-то если честно, на вид ваш код даже не рабочий... но могу ошибаться... По делу: Берешь время нужной записи, сразу же делаешь слепок даты текущей в таком формате:

Код:
_DateTimeFormat(@YEAR & "." & @MON & "." & @MDAY & " " & @HOUR & ":" & @MIN & ":" & @SEC, 0)


Ну и функцией из _DateDiff_2.au3 вычисляешь разницу. Если разница в минутах на 30, то и делаешь свои дела.

#include <_DateDiff_2.au3> - там функция для вычисления разницы между двух дат (времени). Спасибо тов. AZJIO. Пример есть в справке по Custom UDFs.

К сожалению в моей версии автоита _DateDiff_2.au3 не оказалось, поэтому проверить твою идею пока не могу. А скрипт у меня вполне рабочий, тебя что то смущает ?
 

oesoes

xor eax,eax
Сообщения
171
Репутация
9
Ну во первых, меня смущает то, что лог создается только тогда, когда макрос @error установлен, что уже как-то не странновато.

Код:
If  @error Then
    MsgBox(4096, "", "Лог создан")
    $sStartDateTime = StringFormat("%02d.%02d.%04d %02d:%02d:%02d ", @MDAY, @MON, @YEAR, @HOUR, @MIN, @SEC)
    IniWrite("log.log", "History", $sStartDateTime, " log.log создан")
EndIf


У меня конечно же @error не установлен с самого начала, соответственно лог у меня не создастся, соответственно данные не запишутся в файл. Потом неправильно сработает функция IniReadSection, так как файла, который она ожидает на входе просто не существует и переменная $stat не станет массивом. Соответственно, если $stat не массив, то на строке:

Код:
For $i = 1 To $stat[0][0]


Вывалимся с ошибкой. Вот, что меня смущает. Вот файл с функцией: https://yadi.sk/d/5EgMS1E2bRKhP
 
Автор
M

Malderin

Новичок
Сообщения
68
Репутация
1
inververs сказал(а):
Или через
Код:
_DateDiff

Этот вариант заработал, разницу в минутах, как я и хотел, в переменную выдает, но вот только для работы функции требуется формат даты "год/месяц/день" а в моем файле "день/месяц/год".
Может есть функция позволяющая сконвертировать одно в другое ? Хотя если даже и нет задача в принципе решена, буду в следующий раз сразу указывать даты в нужном формате.
Спасибо!


Добавлено:
Сообщение автоматически объединено:

oesoes, действительно, прошу прощения.
Этот кусок кода просто забыл удалить, попал из основного скрипта и к вопросу этой темы он отношения не имеет.
 

oesoes

xor eax,eax
Сообщения
171
Репутация
9
исправь так и все:
Код:
$sStartDateTime = StringFormat("%04d.%02d.%02d %02d:%02d:%02d ", @YEAR, @MON,@MDAY , @HOUR, @MIN, @SEC)
 
Автор
M

Malderin

Новичок
Сообщения
68
Репутация
1
oesoes сказал(а):
исправь так и все:
Код:
$sStartDateTime = StringFormat("%04d.%02d.%02d %02d:%02d:%02d ", @YEAR, @MON,@MDAY , @HOUR, @MIN, @SEC)
C уже существующим логом, описанном в первом посте не прокатит.
А вообще основной скрипт я уже так и переделал, все записи в лог пишутся так, как понятно функции _DateDiff, т.е. год/месяц/день.
 

---Zak---

Скриптер
Сообщения
455
Репутация
120
А вообще основной скрипт я уже так и переделал, все записи в лог пишутся так, как понятно функции _DateDiff, т.е. год/месяц/день.

Мой вариант...

Если в лог пишется так:
Код:
[History]
2014/09/10 15:23:43= Старт(2)
2014/09/10 15:23:44=Текст для поиска
2014/09/10 15:38:58 Кол=2
2014/09/10 15:38:49= Старт (11)
2014/09/10 15:54:01=Текст для поиска
2014/09/10 15:38:58 Кол=22
2014/09/10 15:55:49= Старт (23)
2014/09/11 7:15:01=Текст для поиска
2014/09/11 7:38:58 Кол=22
2014/09/11 7:55:49= Старт (12)

То можно сделать так:
Код:
#include <Date.au3>

$FindSTR = "Текст для поиска"
$Path = @ScriptDir&"\log.log"

Local $aArray = FileReadToArray($Path) ;~ читаем файл в массив
	If @error Then
		MsgBox(0, '', 'Не могу прочитать файл...')
		Exit
    Else
        For $i = UBound($aArray) - 1 To 0 Step -1 ;~ читаем файл с конца в начало
			If StringInStr($aArray[$i], $FindSTR) Then ;~ если есть такая строка
				$aArray = $aArray[$i] ;~ запоминаем ее
				ExitLoop ;~ выходим из цикла
			EndIf
        Next
    EndIf

$iDateCalc = _DateDiff( 'n', $aArray, _NowCalc()) ;~ возвращаем разницу во времени
	If ($iDateCalc >= 30) Then ;~ если больше или равно 30 минут
		MsgBox(0, '', 'С последнего момента прошло более '&$iDateCalc&' минут !!!')
	EndIf
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
Malderin,
Мой вариант.
Код:
#include <Date.au3>

Global $iLastDiff

HotKeySet('{Esc}', '_Exit')

While 1
	$iLastDiff = _MyGetDiffMin()
	ToolTip($iLastDiff & ' min', 0, 0)
	Sleep(5000)
WEnd

Func _MyGetDiffMin()
	Local $s_File = @ScriptDir & '\log.log', $a_Tmp

	$a_Tmp = StringRegExp(FileRead($s_File), '[\r\n]([ \d.:]+)=Текст для поиска', 3)
	If @error Then Return 0
	Return _DateDiff('n', StringRegExpReplace($a_Tmp[UBound($a_Tmp) - 1], '^(\d{2})\.(\d{2})\.(\d{4})(.+)$', '$3/$2/$1$4'), _NowCalc())
;~ 	Return (_DateDiff('n', StringRegExpReplace($a_Tmp[UBound($a_Tmp) - 1], '^(\d{2})\.(\d{2})\.(\d{4})(.+)$', '$3/$2/$1$4'), _NowCalc()) > 30)
EndFunc   ;==>_MyGetDiffMin

Func _Exit()
	Exit
EndFunc   ;==>_Exit
 
Автор
M

Malderin

Новичок
Сообщения
68
Репутация
1
Всем спасибо за предложенные варианты их пока не пробовал поскольку есть одна непонятка с уже имеющимся и в принципе работающим кодом.
Лог переделал в формат под _DateDiff, т.е. "год/месяц/день часы/минуты/секунды", пишется в секцию "Sost"

Вычисление разницы в минутах вынес в отдельную функцию, вот она.

Код:
#Include <File.au3>
#Include <Constants.au3>
#include <Date.au3>

Global $path = @ScriptDir&"\Log.log" ;Путь к файлу Log
Global $diff

Local $sStartDateTime, $sost_time, $i

Func Sost() 
	IniReadSection($Path, "Sost")
	If @error Then
	$sStartDateTime = StringFormat("%04d.%02d.%02d %02d:%02d:%02d", @YEAR, @MON, @MDAY, @HOUR, @MIN, @SEC)		
    IniWrite("log.log", "Sost", $sStartDateTime &" ", " Старт")
	EndIf
dim $stat = IniReadSection($Path,"Sost")
For $i = 1 To $stat[0][0]
	If (StringInStr($stat[$i][1], 'Текст для поиска')) Then
		$sost_time=StringFormat ($stat[$i][0])
		$diff = _DateDiff("n", $sost_time, _NowCalc())
	Else 
		$diff = 32 ;Значение переменной, при которой выполняется некое действие
	EndIf
Next
EndFunc


Все переменные объявлены как local все кроме $diff и $path (они global). $Path используется в разных функциях, а $diff нужна для внедрения в другую (основную) функцию.
Функция Sost() вызывается в другой функции, в которой есть проверка условия по переменной $diff типа:

Код:
If $diff>31 Then действие


Здесь все срабатывает так как надо.
Далее включается цикл While (все в этой же основной функции) где снова вызывается функция Sost() для обновления значения переменной $diff, т.е. внутри цикла While есть if ... then условие на переменной $diff, по достижении которого по истечении времени выполняется какое то действие (например выход из while).
И вот тут то и проблема. Внутри цикла While при повторном вызове функции Sost(), $diff принимает значение -1. Соотвественно ничего не работает, т.к. в $diff ничего не попадает.
Мудрено написал, но надеюсь суть ясна, почему приходит $diff = -1 при повторном вызове функции Sost() ?
Наверное я что то по незнанию не учёл, подскажите.


Добавлено:
Сообщение автоматически объединено:

В общем не нашёл ничего лучше, как добавить в основной скрипт ещё одну функцию Sost1(), полностью аналогичную функции Sost() описанной выше, только переменные внутри ёё были переименованы, т.е. функция sost() выдает на на выходе $diff, а функция sost1() выдает на на выходе $diff1. Ну и переменную $diff1 вставил в цикл while, теперь скрипт работает.
Хотя такое решение мне не нравится, потому что не понятно почему предыдущий вариант не работал, ну и плюс пришлось вводить новые переменные, что тоже не очень хорошо по моему.
Надеюсь что все таки кто то объяснит что было не так в первом варианте.
 
Верх