【问题标题】:Why did the date and number formats change when I moved my Perl program from Linux to Windows?当我将我的 Perl 程序从 Linux 移到 Windows 时,为什么日期和数字格式会发生变化?
【发布时间】:2010-10-07 21:38:45
【问题描述】:

我正在将一些脚本从 Linux 机器移动到 Windows 机器,但现在打印的任何数字或日期都失去了格式(即,数字四舍五入到小数点后 2 位,日期为 2010 年 6 月 1 日..)。

我对 Perl 很陌生,无法弄清楚他们从哪里获得格式,因为脚本中似乎没有任何内容。

我也一直在谷歌搜索全局设置和环境变量,但我找不到任何可以这样做的参考?

到目前为止,我已经设法手动添加数字格式,但仍然对如何正确设置日期格式感到有些困惑,但这两项似乎在以前的其他地方已经完成..

示例

目前我有这条线:

 $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;

我在其他地方得到了答案,因为我完全糊涂了! 我没有意识到我必须先解析日期!

【问题讨论】:

  • @daxim 哇,这还不如 RTFM 有用。
  • 嗯....这对我有帮助吗???!!!
  • 是的,它应该可以帮助您理解,如果您希望得到有用的答案,您应该发布一些相关的源代码(只说“第 17 行”既不好也不礼貌,但它很简洁)。
  • @Bex “第 17 行”的想法是,您应该通过滥用学习,如果没有代码示例,就不可能回答这样的问题。我认为有更好的方式告诉你(我在下面的回答中尝试这样做)。

标签: windows perl


【解决方案1】:

由于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

尝试在控制面板区域和语言设置中更改您的设置。如果它影响日期的格式,则您具有依赖于环境的日期格式。然后您需要检查您的数据库客户端:它如何处理从表中获取的日期字段。你从 DBI 收到$r_detail 吗?

【讨论】:

  • 是的 $r_detail 来自 DBI,这有什么区别吗?我会检查区域日期设置..
【解决方案2】:

还有什么变化吗,也许数据库也从 Linux 迁移到了 Windows?您所看到的可能只是数据库返回其日期值的方式。如果是这样,您应该在数据库配置中寻找解决方案,或者至少在数据库客户端库配置中寻找解决方案。

来自DBI documentation 的引用可能是相关的

日期和时间返回为 当前字符串中的 对应的默认格式 数据库引擎。时区效应是 依赖于数据库/驱动程序。

【讨论】:

  • 这是一个想法。以前的数据库是 SqlServer2000 现在是 SqlServer2008,虽然它没有解释我不认为的数字的四舍五入
  • 四舍五入是标准的 perl 行为,当字符串看起来像数字时,它会更改为数字(特别是当您要求使用 %f 进行浮点格式时,如示例中所示)。
  • @Bex 除非你正在和他们一起做数学,它确实如此。从数据库返回的数字在 Perl 5 中被视为字符串,直到您对其进行数学运算。
【解决方案3】:

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;

控制日期格式的最佳方法是使用日期模块之一或POSIXstrftime 函数。

#!/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";

【讨论】:

  • 那么有没有任何 perl 版本有这个全局格式化选项?因为看起来很奇怪,我不得不将它添加到脚本中;以前不存在..
  • 除非您在八十年代末或九十年代初使用 Perl,否则您一直在使用 Perl 5。我说 Perl 5 的原因是 Perl 6 现已推出(但仍处于试验阶段),我喜欢准确一点。
  • 哦..好的!这些脚本来自 1999/2000 年左右.. :)
  • 那么它们很可能是用 Perl 5 编写的,Perl 5 的第一个版本(非开发版本)于 1994 年发布。您可以在 perlhist 文档中找到更多历史。鉴于您正在处理非常旧的代码(它可能早于strict pragma 的常见用法),您最好阅读Perl Best Practices。许多当时做的事情现在被认为是危险的,并且已经发明了更好的方法。
  • @Chas 我一直在尝试手动格式化我的日期,因为我尝试更改我的电脑的位置和格式化选项,这没有任何区别。当使用上面的示例和我来自 teh DB 的日期时,我收到错误:Usage: POSIX::strftime(fmt, sec, min, hour, mday, mon, year,..... 我已经访问过这里:perldoc.perl.org/POSIX.html但我只是错过了一些东西.. 我的日期目前的格式是 2010-06-10 08:50:18.797 我需要把它弄到 2010 年 10 月 6 日上午 8:50 怎么办,你能帮忙吗?
猜你喜欢
  • 2010-11-20
  • 2021-09-24
  • 1970-01-01
  • 2019-07-17
  • 2022-06-22
  • 1970-01-01
  • 1970-01-01
  • 2020-11-26
  • 2012-06-13
相关资源
最近更新 更多