Почему формат даты и чисел изменился, когда я переместил свою программу Perl из Linux в Windows? - PullRequest
1 голос
/ 06 октября 2010

Я перемещаю некоторые сценарии из коробки Linux в коробку Windows, но теперь любые напечатанные числа или даты потеряли свое форматирование (т. Е. Числа были округлены до 2 десятичных разрядов, а даты - 1 июня 2010 года ...).

Я довольно новичок в Perl и не могу понять, откуда они взяли свое форматирование, поскольку в сценарии, похоже, ничего нет.

Я также искал в Google глобальные настройки и переменные среды, но не могу найти ссылки на что-либо, что могло бы сделать это?

До сих пор мне удавалось добавить форматирование чисел вручную, но я все еще немного удивлен, как правильно отформатировать даты, но оба они, кажется, были сделаны в другом месте, где раньше ...

Примеры

В настоящее время у меня есть эта строка:

 $text->text("$r_detail->{distance}");

где "$r_detail->{distance}") - это число, и оно исходит из базы данных, я использовал sprintf('%.1f',$r_detail->{distance}) для его форматирования.

теперь это 12.0988790 после форматирования это 12.10

Дата также поступает из базы данных, и строка, в которой она используется, похожа на:

&wh($th,$td,$hrow,30,"SurveyDate:","$r_survey->{sdate}");

Я вообще не могу понять, как это отформатировать.

Даты теперь выглядят так: !2003-06-23 09:40:00! прежде чем они были !Jun 23 2002 09:40AM!

(он создает PDF в конце)

Детали базы данных и возможные выводы
Даты хранятся в базе данных в формате: «2003-06-23 09:40:00», они находятся в столбце «smalldatetime». Числа хранятся как числа с плавающей запятой и имеют 1 или 2 десятичных знака. т.е. 2,10 или 15,8

Так, как предложено ниже (и, как я только что вспомнил, изначально он подключался к БД с помощью DBD :: Sybase, но мне пришлось изменить это на DBI), именно подключение к базе данных изменило мое форматирование.

Как я в итоге отформатировал дату

use Date::Parse;
use POSIX; 

my $date ="2002-03-18 10:05:00";
my $parsedDate = str2time($date);
my $formattedDate=strftime "%d %b %Y %I:%M%p", localtime $parsedDate;

Я получил свой ответ еще где, когда я был полностью сбит с толку! Я не осознавал, что мне нужно сначала разобрать дату!

Ответы [ 3 ]

3 голосов
/ 06 октября 2010

Поскольку strftime всегда имеет определенный формат, я полагаю, вы берете дату из какого-либо внешнего источника (например, дата не отформатирована в Perl-скрипте).

Формат даты системных утилит контролируетсяLC_TIME переменная окружения.Поэтому, если вы анализируете в своих сценариях perl вывод какой-либо утилиты, вы можете сначала установить это свойство (например, сделать его общесистемным параметром):

# export LC_TIME=de_DE
# date
Mi 6. Okt 14:54:22 CEST 2010
# export LC_TIME=POSIX
# date
Wed Oct  6 14:54:26 CEST 2010

Попробуйте изменить настройки в Панель управления Региональные и языковые настройки .Если это влияет на формат даты, у вас есть зависящее от среды форматирование даты.Затем вам нужно проверить ваш клиент БД: как он обрабатывает поля даты, извлеченные из таблицы.Вы получаете $r_detail от DBI?

2 голосов
/ 06 октября 2010

Что-то еще изменилось, может быть, база данных также была перенесена из Linux в Windows? Возможно, вы видите, как база данных возвращает значения даты. В этом случае вам следует искать решение в конфигурации базы данных или, по крайней мере, в конфигурации клиентской библиотеки базы данных.

Эта цитата из документации DBI , вероятно, имеет отношение

Даты и время возвращаются как символьные строки в текущем формат по умолчанию соответствующего движок базы данных. Эффекты часового пояса зависит от базы данных / драйвера.

1 голос
/ 06 октября 2010

Perl 5 не имеет форматов по умолчанию для чисел или дат.Можете ли вы опубликовать пример кода и вывода в Linux и MS Windows?

Лучший способ контролировать формат чисел - использовать printf (печать в файл)или sprintf (возвращает строку).

#!/usr/bin/perl

use strict;
use warnings;

my $n = 16;

printf "%08b %03o %02x %2.5f %010d\n", $n, $n, $n, $n, $n;

Лучший способ управления форматом даты - использовать один из модулей даты или POSIX 's strftime function.

#!/usr/bin/perl

use strict;
use warnings;

use POSIX qw/strftime/;

my @date = localtime;
for my $format (qw(%Y-%m-%d %m/%d/%Y %d/%m/%Y)) {
    print strftime($format, @date), "\n";
}

Учитывая ваше обновление, я не думаю, что проблема в Perl 5, это в вашей базе данных.Вы либо изменили, с какой базой данных вы разговариваете, либо среда, которая управляет базой данных, отличается в Linux и MS Windows.Это определенно проблема с датой, поскольку Perl 5 не знает, что это дата (он просто видит ее как строку).И это также верно для чисел, если вы не занимаетесь математикой с ними.Число, которое возвращается из базы данных, на самом деле является строкой, а не числом.Он остается строкой до тех пор, пока вы с ней не выполните математику (в это время Perl 5 автоматически преобразует ее в число).

Поскольку ваша дата не в формате даты, вам необходимо преобразовать ее в формат даты,К счастью, формат, в котором он находится, легко преобразовать в тот же формат localtime возвращает:

#!/usr/bin/perl

use strict;
use warnings;

use POSIX qw/strftime/;

my $input = "2010-06-10 08:50:18.797";

#convert input string into a tm structure like localtime returns
my @localtime = reverse split /[- :]/, $input;
$localtime[5] -= 1900;
$localtime[4]--;

print strftime("%d %b %Y %I:%M%p", @localtime), "\n";
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...