Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Perl: Общие вопросы > Преобразование формата даты из DBF


Автор: tapio 28.1.2009, 11:09
Всем привет! У меня такая проблема.  Есть dbf файл (Rst_0.dbf), я к нему обращаюсь напрямую из перла, дата в этом файле в формате 7.11.2008, при выполние вот этого кода:

use DBD::Xbase;
my $xbase_dbh = DBI->connect("DBI:XBase:.", undef, undef, {RaiseError =>1});
my $sel = "select RESULTDATE from Rst_0.dbf";
my $sel_csr = $xbase_dbh->prepare($sel);
$sel_csr->execute();
while (my ($dt) = $sel_csr->fetchrow_array()) {
    print " $dt\n";
    print "<br>";
}

 дата выдается как 200811, т.е. выдается год и месяц, а день отсекается. Предполагаю, что нужно здесь использовать преобразование формата как для MySQL:
my $sel = "select DATE_FORMAT(RESULTDATE,'%d.%m.%y %H:%i') from Rst_0.dbf"; 
но не прокатывает! Может кто нибудь сможет помочь? 

Автор: amg 28.1.2009, 13:23
Цитата(tapio @  28.1.2009,  11:09 Найти цитируемый пост)
while (my ($dt) = $sel_csr->fetchrow_array()) {
дата выдается как 200811, т.е. выдается год и месяц, а день отсекается.
Может, недостающая информация в следующих элементах массива?

Автор: tapio 28.1.2009, 15:24
Поигрался с датой, пришел к такому выводу: Если в dbf файле дата до 10 числа, т.е. 01.11.2008 .......09.11.2008, то в результате выполнения данного скрипта выводится дата как 200811. А если дата в файле 10.11.2008 или 11.11.2008 и т.д. то выводится корректно: 20081110. Следственно баг в самом модуле XBase, либо у меня руки кривые smile  Какие мысли будут уважаемые? Можно ли обойти эту проблему? 

Автор: shamber 28.1.2009, 15:26
tapio, у вас база не очень большая? может выложите, а я у себя бы проверил. просто под рукой нет dbf баз

Автор: tapio 28.1.2009, 15:37
shamber
файл на 5 мегабайт.

Автор: shamber 28.1.2009, 15:52
посмотрите в структуре создается запись
   0TKGRP INCOMING OFFICE TRAFFIC           200811 701:30:00
тогда как для 
  0TKGRP INCOMING OFFICE TRAFFIC           2008111007:30:00  
вместо нуля пустое место. 
Из-за этого проблемы

Автор: tapio 28.1.2009, 15:57
Спасибо! Начинает ситуация прояснятся. А вы как просматриваете этот dbf файл? 
Просто я в Access его открываю, там дата отражается как 07.11.2008.

Автор: shamber 28.1.2009, 16:31
tapio, а я человек простой  smile я блокнот использую(AkelPad) smile
пробовал тупо заменить регуляркой $_ =~ s/(\d{6})\s(\d)/$1$num$2/g; где $num =0

но файл на 1 байт получается больше, не могу понять почему

Автор: tapio 28.1.2009, 17:00
Моя мысль копия твоей, тоже пытаюсь регуляркой заменить, но пока безрезультатно :( 

Автор: tapio 28.1.2009, 17:33
shamber
Цитата

но файл на 1 байт получается больше, не могу понять почему

 Так в файл 0 добавляем, вот и получается. Или я гоню?

Автор: shamber 28.1.2009, 21:10
Цитата(tapio @  28.1.2009,  17:33 Найти цитируемый пост)
Или я гоню?

Гонишь. потому что заменяется пробел на 0

200811 9 -> 200081109

Автор: shamber 28.1.2009, 22:08
Все разобрался
Я забыл что файл не текстовый, а бинарный smile
Я ваш файл обработал этим скриптом, а после этого у меня совершенно спокойно появилось число 20081107 smile
Код

use strict;

open(File,'<'.'rst_1.dbf');
open(TEMP,'>'."file.dbf");

binmode File;# то что я забыл в первый раз
binmode TEMP; # добавить :)

my $num ='0';
while(<File>){
$_ =~ s/(\d{6})\s(\d)/$1$num$2/g;
print TEMP $_;
}
close File;
close TEMP;


Автор: tapio 29.1.2009, 12:41
shamber
Спасибо тебе огромное! Очень помог мне! 
Я решил без временного файла делать, а перезаписывать этот.
Код

 open(FILE,'+<'."$local_file");
        binmode FILE;
        my $num = 0;
        my $out = '';
        while(<FILE>){
            $_ =~ s/(\d{6})\s(\d)/$1$num$2/g;
            $out .= $_;
        }
        truncate(FILE, 0);
        seek(FILE, 0, 0);
        print FILE $out;
        close FILE;


Автор: shamber 29.1.2009, 21:44
Всегда пожалуйста smile

ЗЫ отмечайте вопрос как решенный smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)