AXForum  
Вернуться   AXForum > Microsoft Dynamics AX > DAX: Программирование
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 01.09.2006, 13:41   #1  
Gustav is offline
Gustav
Moderator
Аватар для Gustav
SAP
Лучший по профессии 2009
 
1,858 / 1152 (42) ++++++++
Регистрация: 24.01.2006
Адрес: Санкт-Петербург
Записей в блоге: 19
? Время созданного "сейчас" файла меньше 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) );
}
Запускаю джоб 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
1-й вопрос: что это за 4 часа разницы, т.е. 13-9 ? Гринвич? UNIX-time? (любопытно, какая разница получится у других часовых поясов - отличная от 4?)
И как бороться? Просто тупо учитывать константой "4 часа" в коде или есть какая-нибудь специальная функция для такой коррекции?

Это еще не всё. По ходу возник второй вопрос. Напомню, что файл уже существует и я хочу его удалить и создать заново.
Запускаю джоб 2-й раз. Получаю в инфологе:
Код:
C:\testtime.txt
Даты в формате ГГ ММ ДД
 
 
 
Время в формате ЧЧ ММ СС
00 00 00
00 00 00
00 00 00
Время "сейчас" в формате ЧЧ ММ СС
13 22 23
Иду смотреть файл в Проводнике. Он существует, но как-то "странно"... На попытку удалить в Проводнике ругается, что занят другим процессом. Выхожу из Аксапты - файл запоздало исчезает.
2-й вопрос: Как этот файл освободить, не выходя из Аксапты?


Всем откликнувшимся заранее большое спасибо.
Старый 01.09.2006, 13:50   #2  
Lucky13 is offline
Lucky13
Участник
1C
 
714 / 198 (8) ++++++
Регистрация: 21.10.2004
1. В функции getFileCreatedTime используется ф-ция fileTimeToSystemTime, а SystemTime всегда Гринвич. Можно использовать fileTimeToLocalTime, тогда разницы не будет
2. Есть какая-то ф-ция в WinAPI, позволяющая высталять флаги у файла, точно уже не помню, SetFileSecurity кажется
За это сообщение автора поблагодарили: Gustav (3).
Старый 01.09.2006, 15:32   #3  
Gustav is offline
Gustav
Moderator
Аватар для Gustav
SAP
Лучший по профессии 2009
 
1,858 / 1152 (42) ++++++++
Регистрация: 24.01.2006
Адрес: Санкт-Петербург
Записей в блоге: 19
Цитата:
Сообщение от 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  
Alex_KD is offline
Alex_KD
Участник
AxAssist
MCBMSS
Соотечественники
 
522 / 362 (14) ++++++
Регистрация: 06.07.2006
Адрес: Melbourne, Down Under
Замени
Код:
 
    if (WinAPI::fileExists( fileName ))
        WinAPI::deleteFile( fileName );
WinAPI::createFile( fileName);
на
Код:
 
    #winapi
    WinAPI::createFile( fileName, #CREATE_ALWAYS );
За это сообщение автора поблагодарили: Gustav (3).
Старый 01.09.2006, 14:15   #5  
Gustav is offline
Gustav
Moderator
Аватар для Gustav
SAP
Лучший по профессии 2009
 
1,858 / 1152 (42) ++++++++
Регистрация: 24.01.2006
Адрес: Санкт-Петербург
Записей в блоге: 19
Спасибо, господа.

Цитата:
Сообщение от Alex_KD
#winapi
WinAPI::createFile( fileName, #CREATE_ALWAYS );
Да, это хорошо. Правда, CreatedTime остается от самого первого создания, но, думаю, это не особо принципиально

Щас с Гринвичем еще поразбираюсь...
Старый 01.09.2006, 14:58   #6  
gl00mie is offline
gl00mie
Участник
MCBMSS
Most Valuable Professional
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,684 / 5798 (201) ++++++++++
Регистрация: 28.11.2005
Адрес: Москва
Записей в блоге: 3
Цитата:
Сообщение от Gustav
Напомню, что файл уже существует и я хочу его удалить и создать заново. Запускаю джоб 2-й раз. Иду смотреть файл в Проводнике. Он существует, но как-то "странно"... На попытку удалить в Проводнике ругается, что занят другим процессом. Выхожу из Аксапты - файл запоздало исчезает. Как этот файл освободить, не выходя из Аксапты?
ОС откладывает удаление файла, пока не будут закрыты все его дескрипторы (handles). До той поры он находится в состоянии "deletion pending", а попытки его заново открыть/создать завершаются отказом в доступе. Отсюда вывод: дескрипторы надо закрывать
PHP код:
FileName fileName = @'c:\testtime.txt';
int      hFile;
;
hFile WinAPI::createFile(fileName);
WinAPI::closeHandle(hFile); 
Старый 01.09.2006, 15:21   #7  
Gustav is offline
Gustav
Moderator
Аватар для Gustav
SAP
Лучший по профессии 2009
 
1,858 / 1152 (42) ++++++++
Регистрация: 24.01.2006
Адрес: Санкт-Петербург
Записей в блоге: 19
Да, я уже тоже попробовал этот способ с закрыванием хэндла - разбираясь со временем, обнаружил, что все функции так примерно и делают. Только CreatedTime все равно остается от самого первого создания. Почему интересно? Если я через год воссоздам файл в этой же папке с тем же именем, то он мне нарисует дату создания файла годичной давности?
Старый 01.09.2006, 16:58   #8  
gl00mie is offline
gl00mie
Участник
MCBMSS
Most Valuable Professional
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,684 / 5798 (201) ++++++++++
Регистрация: 28.11.2005
Адрес: Москва
Записей в блоге: 3
Цитата:
Сообщение от Gustav
CreatedTime все равно остается от самого первого создания. Почему интересно? Если я через год воссоздам файл в этой же папке с тем же именем, то он мне нарисует дату создания файла годичной давности?
У меня дата создания сменилась после того, как я удалил файл и подождал примерно минуту перед подвторным запуском job'а и, соответственно, созданием файла. А вообще, можно озвучить постановку задачи? для чего все эти манипуляции?
За это сообщение автора поблагодарили: Gustav (5).
Старый 01.09.2006, 17:08   #9  
Gustav is offline
Gustav
Moderator
Аватар для Gustav
SAP
Лучший по профессии 2009
 
1,858 / 1152 (42) ++++++++
Регистрация: 24.01.2006
Адрес: Санкт-Петербург
Записей в блоге: 19
спасибо, AndyD, ругаться перестало, но результат пока неверный получается...

Я опять-таки тупо заменил на:
DLLFunction _fileTimeToSystemTime = new DLLFunction(_winApiDLL, 'FileTimeToLocalFileTime')

теперь файл пересоздается, я это вижу в Проводнике и свойства его меняются, но в инфологе похожая картина, что и при втором прогоне исходного джоба:
Код:
C:\testtime.txt
Даты в формате ГГ ММ ДД
 
Время в формате ЧЧ ММ СС
00 00 00
Время "сейчас" в формате ЧЧ ММ СС
17 04 15
Что еще где-то надо подправить, наверное, но моральное истощение уже наступило и с WinAPI на эту тему ковыряться надоело... чувствую, что, видимо, прибегну через COM к безотказному Scripting.FileSystemObject. Он нормальные человеческие даты у файлов показывает

Последний раз редактировалось Gustav; 01.09.2006 в 19:23.
Старый 01.09.2006, 17:25   #10  
Gustav is offline
Gustav
Moderator
Аватар для Gustav
SAP
Лучший по профессии 2009
 
1,858 / 1152 (42) ++++++++
Регистрация: 24.01.2006
Адрес: Санкт-Петербург
Записей в блоге: 19
Цитата:
Сообщение от 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  
AndyD is offline
AndyD
Участник
КОРУС Консалтинг
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
 
2,560 / 2479 (88) +++++++++
Регистрация: 20.08.2005
функция называется FileTimeToLocalFileTime
и втором аргаментом возвращается такая же структура, как и во входящем параметре
__________________
Axapta v.3.0 sp5 kr2
За это сообщение автора поблагодарили: Gustav (2).
Старый 04.09.2006, 08:48   #12  
KiselevSA is offline
KiselevSA
Злыдни
Аватар для KiselevSA
Злыдни
Лучший по профессии 2015
 
958 / 333 (13) ++++++
Регистрация: 25.01.2002
Адрес: Москва
Для удаления файлов по времени необходимо использовать не дату и время создания, а дату последней модификации.
Пример:
'==========================================================================
'
' 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  
Gustav is offline
Gustav
Moderator
Аватар для Gustav
SAP
Лучший по профессии 2009
 
1,858 / 1152 (42) ++++++++
Регистрация: 24.01.2006
Адрес: Санкт-Петербург
Записей в блоге: 19
Цитата:
Сообщение от KiselevSA
необходимо использовать не дату и время создания, а дату последней модификации.
За примерчик спасибо, но я бы не был столь категоричным. Вопрос философский, и мы нашей маленькой творческой группой сейчас его обдумываем - какую именно из трех дат (Created, Modified или Accessed) взять за основу. Дело в том, что в подавляющем большинстве случаев пользователь не будет модифицировать созданный отчет (т.е. будет Modified = Created) , а вот несколько раз после создания посмотреть его вполне может (Accessed)...
Старый 04.09.2006, 10:32   #14  
gl00mie is offline
gl00mie
Участник
MCBMSS
Most Valuable Professional
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,684 / 5798 (201) ++++++++++
Регистрация: 28.11.2005
Адрес: Москва
Записей в блоге: 3
Цитата:
Сообщение от Gustav
мы нашей маленькой творческой группой сейчас его обдумываем - какую именно из трех дат (Created, Modified или Accessed) взять за основу. в подавляющем большинстве случаев пользователь не будет модифицировать созданный отчет (т.е. будет Modified = Created) , а вот несколько раз после создания посмотреть его вполне может (Accessed)...
Achtung! Где хранятся эти самые отчеты, на клиенте? А то в свое время для ускорения работы NTFS еще под WinNT4 было популярно прописывание такой вот фишки в реестре:
X++:
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem]
"NtfsDisableLastAccessUpdate"=dword:00000001
со всеми вытекающими для рассматриваемого вопроса последствиями. Так что имеет смысл проконсультироваться с сисадминами или самостоятельно посмотреть, не прописано ли такое в реестре на машинах, где предполагается проводить чистки, либо использовать created или modified дату/время файла. И еще на счет last accessed надо учеть, что, к примеру, на FAT32 сохраняется только дата последнего доступа, а время там всегда нулевое. Впрочем, я искренне надеюсь, что FAT32 у вас нигде, кроме флэшек, не используется
Старый 04.09.2006, 16:04   #15  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,689 / 1192 (43) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Если еще актуальна тема с Гринвичем, то я определял часовой пояс так:

PHP код:
static void MVB_GetTimeZone(Args _args)
{
    
#define.MAX_PATH(260)
    
Dll             kernel32;
    
DllFunction     getTimeZoneInformation;
    
int             secondsTimeZone;
    
int             retVal;
    
binary          lpTimeZoneInformation = new Binary(#MAX_PATH);
    
;
    
kernel32        = new Dll("kernel32.dll");

    
//---------------------------------------------------------------------------------- Чтение информации о часовом поясе
    
getTimeZoneInformation  = new DllFunction(kernel32"GetTimeZoneInformation");
    
getTimeZoneInformation.returns(ExtTypes::DWORD);
    
getTimeZoneInformation.arg(ExtTypes::POINTER);

    
retVal getTimeZoneInformation.call(lpTimeZoneInformation);

    
// Из всей информации нужен только сдвиг часового пояса к Гринвичу. Он указывается в минутах
    
secondsTimeZone  lpTimeZoneInformation.dWord(0)*60;

    print 
secondsTimeZone," секунд";
    
pause;


Старый 04.09.2006, 17:33   #16  
Gustav is offline
Gustav
Moderator
Аватар для Gustav
SAP
Лучший по профессии 2009
 
1,858 / 1152 (42) ++++++++
Регистрация: 24.01.2006
Адрес: Санкт-Петербург
Записей в блоге: 19
Цитата:
Сообщение от Владимир Максимов
Если еще актуальна тема с Гринвичем, то я определял часовой пояс так:
Да, спасибо. Это может пригодиться.
Надо только найти еще один час. Я так понимаю, это следствие летнего перевода часов. И учесть знак.

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  
gl00mie is offline
gl00mie
Участник
MCBMSS
Most Valuable Professional
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,684 / 5798 (201) ++++++++++
Регистрация: 28.11.2005
Адрес: Москва
Записей в блоге: 3
Цитата:
Сообщение от 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
При том что текущее время у меня на компе - 18:29 (UTC +03:00 +1 час за счет летнего времени).
Старый 04.09.2006, 18:59   #18  
Gustav is offline
Gustav
Moderator
Аватар для Gustav
SAP
Лучший по профессии 2009
 
1,858 / 1152 (42) ++++++++
Регистрация: 24.01.2006
Адрес: Санкт-Петербург
Записей в блоге: 19
Цитата:
Сообщение от gl00mie
Пойдем от обратного. Зачем нам заморачиваться с часовыми поясами, если и система считает время по Гринвичу, и файловые времена хранятся по Гринвичу?
Да, это душевно. Спасибо. Это мне нравится.

Чего-то такого мне и хотелось: либо правильную дельту между timenow и SystemTime, либо, действительно, просто SystemTime как точку отсчета "возраста назад" (всё равно вычитать будем в скрытом от внешних глаз методе). И удивительно, вообще, что эту функцию не вбабахали в стандарт класса WinAPI...

(ну, а полный зачОт по теме уже поставил раньше)
Теги
time, winapi, время, файл

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Закупка на проект "Время и расходы" Sentry DAX: Функционал 6 19.02.2016 14:09
"An unexpected exception occurred" во время установки. Hub DAX: Администрирование 2 19.12.2009 12:09
Время по графику и фактическое время работы в табеле nicko DAX: Функционал 0 09.02.2005 15:24
Поле с типом "Время" Кирилл DAX: Программирование 9 06.05.2004 10:53
Установить время файла? SnowMan DAX: Программирование 5 01.10.2003 14:42

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 02:38.
Powered by vBulletin® v3.8.5. Перевод: zCarot
Контактная информация, Реклама.