Подводный камень FoxPro - еще можно избежать катастрофы

Вся полемика о проблеме Y2k, много лет раздуваемая за рубежом, кажется нам чем-то искусственным, и большинство программистов, особенно молодых, пришедших в отрасль со времени появления Win95, относятся к ней весьма легкомысленно.

(c) Компьютерная газета

Основным мотивом такого беспечного поведения служат те же западные источники, сообщающие о масштабных мерах по переделке программ, написанных еще лет 20 назад на низкоуровневых языках (Assembler, C++,...) для устаревшей техники, в основном, мейнфреймов - вроде наших ЕС.

И машин таких у нас нет, и программ, естественно, тоже не имеется, поскольку эпоха повальной компьютеризации у нас началась гораздо позже, чем у них. А из современного ПО новости затрагивают лишь операционные системы, которые можно легко исправить патчами фирмы-производителя ОС.

Однако, перспективы не очень радужные. Несмотря на то, что большая часть прикладного ПО разрабатывалась уже в 90-е годы, психология программистов изменялась незначительно, напоминая известный принцип: "Пока гром не грянет" или "После нас хоть потоп" - как кому нравится. Спустя несколько лет эксплуатации многие программы приходилось переделывать полностью.

А переделывать чужую программу отнюдь не легче, чем писать заново. Те, кто считает это легким делом, рискуют напороться на рифы Y2k.

Никогда раньше не попробовал себя в роли лоцмана, но хочу предложить Вам карту известных ошибок и возможные варианты решений для программистов на FoxPro (а также других диалектов xBase - dBase и Clipper).

1. Ошибка ввода даты. При вводе даты, когда на год отводится два знакоместа, все версии FoxPro, от самой первой до Visual FoxPro 6.0, естественно считают, что {01.01.00} это 1 января 1900 года и что это понедельник, хотя первый день XXI века начинается в субботу. Это не ошибка СУБД FoxPro, это просто такое его свойство.

Самое простое решение - программно включить установку SET CENTURY ON в головной процедуре запуска приложения (либо в методе INIT головной формы в приложении Visual FoxPro). Это всем известный способ. При использовании этой установки поля ввода даты расширяются на два знака. Но это не 100% защита. Остаются небольшие дыры, обусловленные использованием дополнительных свойств полей ввода, PICTURE и FUNCTION - в ранних версиях FoxPro, INPUTMASK - в Visual FoxPro. Дело в том, что если была задана маска ввода даты с двумя знаками на год 99.99.99, то результат ввода будет неправильным. Найдите все подобные участки кода и расширьте маску ввода до 99.99.9999.

2. Ошибка преобразования даты. При преобразовании даты в строку и обратно функциями DTOC и CTOD FoxPro будет снова интерпретировать 1.01.00 как 1 января 1900 года. Как и в предыдущем случае, спасает включение установки SET CENTURY ON. Однако это снова не 100% защита. В программировании сложных приложений очень часто встречается участок кода, формирующий строку даты, вроде

str(_DAY, 2)+'.'+ str(_MONTH, 2)+'.'+ str(_YEAR, 2)

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

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

FUNCTION YEARVALID
PARA _YEAR
RETURN (_YEAR+ IIF(_YEAR<50, 1900,;
IIF(_YEAR< 100, 2000, 0)))Во-вторых, преобразовать число года в строку шириной 4 знака.

Тогда предыдущее выражение будет иметь следующий вид:

str(_DAY, 2)+'.'+ str(_MONTH, 2)+'.'+ str(YEARVALID(_YEAR), 4)

Хранение даты в полях БД соответствующего типа проблем никаких не вызывает. Несмотря на то, что тип "ДАТА" требует 8 знаков и при просмотре FoxPro отображает значение в виде DD.MM.YY, хранится значение в базе в виде YYYYMMDD.

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

FUNCTION DATEVALID
PARA _DATE
PRIVATE _day, _month, _year
_day= DAY(_DATE)
_month= MONTH(_DATE)
_year= YEAR(_DATE)
_year= YEARVALID(_year) && См. выше
RETURN CTOD(str(_DAY, 2)+'.'+ str(_MONTH, 2)+'.'+ str(_YEAR, 4))

Команда проверки поля даты MYDATE в открытой базе примет следующий вид:

replace all MYDATE with DATEVALID(MYDATE)

3. Ошибка периода. Во многих бухгалтерских программах часто используются не даты, а периоды, указывающие только год и месяц, т. к. конкретная дата бывает просто не нужна. В приложениях, с которыми мне приходилось сталкиваться, периоды имели вид YYMM - два знакоместа на год и два на месяц. С этой проблемой разобраться сложнее всего. Если есть возможность - обратитесь к поставщику за новой версией программы. Если нет, готовьтесь решить следующие задачи.

a) Необходимо преобразовать структуру баз данных для хранения периода в новом формате. Это значит, что дополнительно придется переделать все подпрограммы чтения/записи информации в БД.

b) Если есть возможность, необходимо переконвертировать старые данные, которые хранятся в сокращенном формате. Если это невозможно, то напишите функцию преобразования периода из сокращенного в расширенный формат и используйте ее во всех операциях сравнения и алгоритмах расчетов.

В моем случае она выглядит следующим образом:

FUNCTION FULLPERIOD
PARA PERIOD
PRIVATE _month, _year
_month= int(PERIOD/100)
_year= (PERIOD— _month)/100
_year= YEARVALID(_year) && См. выше
RETURN (_year*100+ _month)

Если в качестве параметра передан расширенный период, то он останется без изменений.

c) Проверьте, есть ли участки программы, где сокращенный период преобразовывается в строку. Преобразование периода 0001 в строку даст результат ' 1'. Использование такой строки с лидирующими пробелами в некоторых случаях приведет к явной ошибке и аварийному завершению программы. Приходилось переделывать программу еще на FoxPro 2.0 под DOS, где ежемесячно формировались временные файлы вида zptYYMM.dbf. Конечно, DOS никоим образом не хотела создавать файл ZPT 1.DBF, а вот ZPT0001.DBF - пожалуйста.

На этом вроде бы и все. Остальные случаи слишком специфичны для каждой программы (или программиста), поэтому пока еще не поздно, надо засучить рукава и браться за работу.

Конечно, эта статья несколько запоздала. Однако время еще есть. Ведь проблема Y2k не закончится с приходом нового года. Большая часть прикладного ПО - бухгалтерские программы, использующие помесячную отчетность. Поэтому наиболее критические времена наступят в конце января - начале февраля. Конечно, программисты это знают, чего не скажешь об их начальниках. Уважаемые руководители предприятий, проблема не решается одним росчерком пера либо нажатием нужной кнопки. Она требует времени и... денег (ну как же без этого). Иначе проблемы будут проявляться в самый неподходящий момент. Кроме того, существует небольшая вероятность ошибок при переходе к 2001 году, хотя категорически утверждать сие не берусь.

С Новым годом, коллеги!

Виктор Маковчик


Компьютерная газета. Статья была опубликована в номере 50 за 1999 год в рубрике программирование :: разное

©1997-2024 Компьютерная газета