|
01.09.2006, 13:41 | #1 |
Moderator
|
Время созданного "сейчас" файла меньше timenow на 4 часа
Уважаемые коллеги, такая проблема. Даже две.
Есть такой тестовый джоб: X++: static void KKu_Job_6901_TestFileTime(Args _args) { FileName fileName = 'C:\\testtime.txt'; ; if (WinAPI::fileExists( fileName )) WinAPI::deleteFile( fileName ); WinAPI::createFile( fileName ); info( fileName ); info( 'Даты в формате ГГ ММ ДД' ); info( date2str(WinAPI::getFileCreatedDate ( fileName ) ,321,2,1,2,1,2) ); info( date2str(WinAPI::getFileModifiedDate( fileName ) ,321,2,1,2,1,2) ); info( date2str(WinAPI::getFileAccessedDate( fileName ) ,321,2,1,2,1,2) ); info( 'Время в формате ЧЧ ММ СС' ); info( time2str(WinAPI::getFileCreatedTime ( fileName ) ,3,1) ); info( time2str(WinAPI::getFileModifiedTime( fileName ) ,3,1) ); info( time2str(WinAPI::getFileAccessedTime( fileName ) ,3,1) ); info( 'Время "сейчас" в формате ЧЧ ММ СС' ); info( time2str( timenow(),3,1) ); } Код: C:\testtime.txt Даты в формате ГГ ММ ДД 06 09 01 06 09 01 06 09 01 Время в формате ЧЧ ММ СС 09 21 06 09 21 06 09 21 06 Время "сейчас" в формате ЧЧ ММ СС 13 21 06 И как бороться? Просто тупо учитывать константой "4 часа" в коде или есть какая-нибудь специальная функция для такой коррекции? Это еще не всё. По ходу возник второй вопрос. Напомню, что файл уже существует и я хочу его удалить и создать заново. Запускаю джоб 2-й раз. Получаю в инфологе: Код: C:\testtime.txt Даты в формате ГГ ММ ДД Время в формате ЧЧ ММ СС 00 00 00 00 00 00 00 00 00 Время "сейчас" в формате ЧЧ ММ СС 13 22 23 2-й вопрос: Как этот файл освободить, не выходя из Аксапты? Всем откликнувшимся заранее большое спасибо. |
|
01.09.2006, 13:50 | #2 |
Участник
|
1. В функции getFileCreatedTime используется ф-ция fileTimeToSystemTime, а SystemTime всегда Гринвич. Можно использовать fileTimeToLocalTime, тогда разницы не будет
2. Есть какая-то ф-ция в WinAPI, позволяющая высталять флаги у файла, точно уже не помню, SetFileSecurity кажется |
|
|
За это сообщение автора поблагодарили: Gustav (3). |
01.09.2006, 15:32 | #3 |
Moderator
|
Цитата:
Сообщение от Lucky13
Можно использовать fileTimeToLocalTime, тогда разницы не будет
Меняю тупо в WinAPI::fileTimeToSystemTime строку DLLFunction _fileTimeToSystemTime = new DLLFunction(_winApiDLL, 'FileTimeToSystemTime'); на строку DLLFunction _fileTimeToSystemTime = new DLLFunction(_winApiDLL, 'FileTimeToLocalTime'); и нифига... А длл ту же нужно: DLL _winApiDLL = new DLL('KERNEL32'); или другую?? |
|
01.09.2006, 13:59 | #4 |
Участник
|
Замени
Код: if (WinAPI::fileExists( fileName )) WinAPI::deleteFile( fileName ); WinAPI::createFile( fileName); Код: #winapi WinAPI::createFile( fileName, #CREATE_ALWAYS ); |
|
|
За это сообщение автора поблагодарили: Gustav (3). |
01.09.2006, 14:15 | #5 |
Moderator
|
Спасибо, господа.
Цитата:
Сообщение от Alex_KD
#winapi
WinAPI::createFile( fileName, #CREATE_ALWAYS ); Щас с Гринвичем еще поразбираюсь... |
|
01.09.2006, 14:58 | #6 |
Участник
|
Цитата:
Сообщение от Gustav
Напомню, что файл уже существует и я хочу его удалить и создать заново. Запускаю джоб 2-й раз. Иду смотреть файл в Проводнике. Он существует, но как-то "странно"... На попытку удалить в Проводнике ругается, что занят другим процессом. Выхожу из Аксапты - файл запоздало исчезает. Как этот файл освободить, не выходя из Аксапты?
PHP код:
|
|
01.09.2006, 15:21 | #7 |
Moderator
|
Да, я уже тоже попробовал этот способ с закрыванием хэндла - разбираясь со временем, обнаружил, что все функции так примерно и делают. Только CreatedTime все равно остается от самого первого создания. Почему интересно? Если я через год воссоздам файл в этой же папке с тем же именем, то он мне нарисует дату создания файла годичной давности?
|
|
01.09.2006, 16:58 | #8 |
Участник
|
Цитата:
Сообщение от Gustav
CreatedTime все равно остается от самого первого создания. Почему интересно? Если я через год воссоздам файл в этой же папке с тем же именем, то он мне нарисует дату создания файла годичной давности?
|
|
|
За это сообщение автора поблагодарили: Gustav (5). |
01.09.2006, 17:08 | #9 |
Moderator
|
спасибо, AndyD, ругаться перестало, но результат пока неверный получается...
Я опять-таки тупо заменил на: DLLFunction _fileTimeToSystemTime = new DLLFunction(_winApiDLL, 'FileTimeToLocalFileTime') теперь файл пересоздается, я это вижу в Проводнике и свойства его меняются, но в инфологе похожая картина, что и при втором прогоне исходного джоба: Код: C:\testtime.txt Даты в формате ГГ ММ ДД Время в формате ЧЧ ММ СС 00 00 00 Время "сейчас" в формате ЧЧ ММ СС 17 04 15 Последний раз редактировалось Gustav; 01.09.2006 в 19:23. |
|
01.09.2006, 17:25 | #10 |
Moderator
|
Цитата:
Сообщение от gl00mie
У меня дата создания сменилась после того, как я удалил файл и подождал примерно минуту перед подвторным запуском job'а и, соответственно, созданием файла.
Да, я получил такой же эффект, уже набросав процедурку на VBA с использованием Scripting.FileSystemObject. Цитата:
Сообщение от gl00mie
А вообще, можно озвучить постановку задачи? для чего все эти манипуляции?
Хочу удалять из некоторой папки файлы, которые старше определенного "возраста". "Возраст" задается заранее и, грубо говоря, лежит в пределах от нескольких часов до нескольких дней (ну, месяц, например, максимум). Физически - это файлы некоторых отчетов пользователя (xls), которые он "нарезает" в процессе работы с Аксаптой. Вы спросите, зачем сохранять xls-файлы, если пользователь может сам решить в Excel'е, сохранять или нет? В данном случае это принципиальное условие задачи. Если подход окажется удачным, я предполагаю распространить его не только на xls-файлы. Файлы сохраняются под страшными именами, включающими userID, дату, время, sessionID и, возможно, некий reportID, например, GUST_060901_174918_3_115.xls (хм... или reportID можно сразу после ника: GUST_115_060901_174918_3.xls - с точки зрения сортировки так наверное даже логичнее...) Ну вот чтобы их не скапливалось в его персональной папке слишком много, я и решил приделать такую процедуру, которая будет его спрашивать "Не желаете ли уже почиститься, любезный?" А "возраст" дается ему для того, чтобы он мог за это время "перекинуть" особо важные отчеты в какую-нибудь другую свою личную папку уже на длительное хранение по своему желанию. "Возраст" предполагается отсчитывать "в прошлое" от момента, определяемого timenow() при попытке запуска очередного отчета и, соответственно, проверять содержимое папки на наличие старых файлов. P.S. В принципе, конечно, можно "забить" на эти 4 часа и использовать только целые дни (даты), отсчитываемые назад, начиная со "вчерашнего", но, как говорится, "народ хочет разобраться!" Последний раз редактировалось Gustav; 01.09.2006 в 18:04. |
|
01.09.2006, 15:55 | #11 |
Участник
|
функция называется FileTimeToLocalFileTime
и втором аргаментом возвращается такая же структура, как и во входящем параметре
__________________
Axapta v.3.0 sp5 kr2 |
|
|
За это сообщение автора поблагодарили: Gustav (2). |
04.09.2006, 08:48 | #12 |
Злыдни
|
Для удаления файлов по времени необходимо использовать не дату и время создания, а дату последней модификации.
Пример: '========================================================================== ' ' VBScript Source File -- Created with SAPIEN Technologies PrimalScript 3.0 ' ' NAME: Удаление устаревших файлов ' ' AUTHOR: ** , ** ' DATE : 30.12.2005 ' ' COMMENT: ' '========================================================================== Dim fso, WshShell Dim oFolder, oFile Const DPath = "Ваш путь" Set fso = createobject("Scripting.FileSystemObject") Set WshShell = CreateObject("WScript.Shell") Set oFolder = fso.GetFolder(DPath) Set oFile = oFolder.Files If (Not fso.FolderExists(DPath)) Then WSH.Echo("Отсутствует директория или не назначен диск") Else For Each i In oFile file = oFolder.Path & "\" & i.Name If (i.DateLastModified < (Date - 15)) Then fso.DeleteFile file, True End If Next End If |
|
04.09.2006, 10:16 | #13 |
Moderator
|
Цитата:
Сообщение от KiselevSA
необходимо использовать не дату и время создания, а дату последней модификации.
|
|
04.09.2006, 10:32 | #14 |
Участник
|
Цитата:
Сообщение от Gustav
мы нашей маленькой творческой группой сейчас его обдумываем - какую именно из трех дат (Created, Modified или Accessed) взять за основу. в подавляющем большинстве случаев пользователь не будет модифицировать созданный отчет (т.е. будет Modified = Created) , а вот несколько раз после создания посмотреть его вполне может (Accessed)...
X++: [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem]
"NtfsDisableLastAccessUpdate"=dword:00000001 |
|
04.09.2006, 16:04 | #15 |
Участник
|
Если еще актуальна тема с Гринвичем, то я определял часовой пояс так:
PHP код:
|
|
04.09.2006, 17:33 | #16 |
Moderator
|
Цитата:
Сообщение от Владимир Максимов
Если еще актуальна тема с Гринвичем, то я определял часовой пояс так:
Надо только найти еще один час. Я так понимаю, это следствие летнего перевода часов. И учесть знак. print secondsTimeZone дает -10 800 секунд (т.е. 3 часа), а нам, получается, надо иметь -14 400 (т.е. 4 часа)... Есть ли какие-нибудь соображения насчет этого дополнительного часа? (или будем пользоваться алгоритмом только при зимнем времени?) P.S. Вроде, что-то вот отсюда можно взять... Цитата:
Сообщение от туда
UTC НИКОГДА не переходит на летнее время.
Да действительно, изучил вопрос и понял. Летом у нас GMT+4. Последний раз редактировалось Gustav; 04.09.2006 в 17:59. |
|
04.09.2006, 18:26 | #17 |
Участник
|
Цитата:
Сообщение от Gustav
Надо только найти еще один час. Есть ли какие-нибудь соображения насчет этого дополнительного часа?
X++: // дополнение к классу WinAPI client server static Binary getSystemTime() { DLL _winApiDLL = new DLL(#KernelDLL); DLLFunction _getSystemTime = new DLLFunction(_winApiDLL, @'GetSystemTime'); Binary systemTime = new Binary(#offset16); _getSystemTime.returns(ExtTypes::void); _getSystemTime.arg(ExtTypes::Pointer); _getSystemTime.call(systemTime); return systemTime; } static void KKu_Job_6901_TestFileTime(Args _args) { FileName fileName = @'c:\testtime.txt'; int hFile; ; if (WinAPI::fileExists( fileName )) WinAPI::deleteFile( fileName ); hFile = WinAPI::createFile( fileName ); WinAPI::closeHandle( hFile ); info( fileName ); info( 'Даты/вреям в формате ГГ ММ ДД / ЧЧ ММ СС' ); info( strfmt("created date/time %1/%2", date2str(WinAPI::getFileCreatedDate(fileName), 321,2,1,2,1,2), time2str(WinAPI::getFileCreatedTime(fileName), 3,1))); info( strfmt("modified date/time %1/%2", date2str(WinAPI::getFileModifiedDate(fileName),321,2,1,2,1,2), time2str(WinAPI::getFileModifiedTime(fileName),3,1))); info( strfmt("accessed date/time %1/%2", date2str(WinAPI::getFileAccessedDate(fileName),321,2,1,2,1,2), time2str(WinAPI::getFileAccessedTime(fileName),3,1))); info( 'Время "сейчас" в формате ЧЧ ММ СС' ); info( time2str( WinAPI::systemTimeToTimeOfDay(WinAPI::getSystemTime()),3,1) ); } Код: c:\testtime.txt Даты/вреям в формате ГГ ММ ДД / ЧЧ ММ СС created date/time 06 09 04/14 29 12 modified date/time 06 09 04/14 29 12 accessed date/time 06 09 04/14 29 12 Время "сейчас" в формате ЧЧ ММ СС 14 29 12 |
|
04.09.2006, 18:59 | #18 |
Moderator
|
Цитата:
Сообщение от gl00mie
Пойдем от обратного. Зачем нам заморачиваться с часовыми поясами, если и система считает время по Гринвичу, и файловые времена хранятся по Гринвичу?
Чего-то такого мне и хотелось: либо правильную дельту между timenow и SystemTime, либо, действительно, просто SystemTime как точку отсчета "возраста назад" (всё равно вычитать будем в скрытом от внешних глаз методе). И удивительно, вообще, что эту функцию не вбабахали в стандарт класса WinAPI... (ну, а полный зачОт по теме уже поставил раньше) |
|