我目前正在将Informix ESQL / C程序重写为Perl。我遇到的一个问题是尝试获取与Perl中rtoday()
完全相同的值。
"today
A pointer to an int4 value that receives the internal DATE.
Usage
The rtoday() function obtains the system date on the client computer, not
the server computer."
在命令行上执行echo $ DATE时,我得到:
username@myServer:/u/aDir/ $ echo $DATE
2457470 for March 23, 2016
但是当我从昨天在我的Unix机器上通过我的日志获得值时,我有:
42447 for March 22,2016
(日志来自我的ESQL程序)
问题是我需要使用rtoday()
值才能将该值导出到平面文件(以及其他数据),以便其他程序进行处理。
我只需要知道如何在Perl中或通过系统命令行获取此值,以便我可以使用它。
答案 0 :(得分:3)
手册页来自Informix ESQL / C.
您需要知道Informix中的日期是自第0天起的天数,即1899-12-31 - 所以第1天是1900-01-01。
#include <stdio.h>
#include "sqlhdr.h"
int main(void)
{
int4 date;
rtoday(&date);
printf("%ld\n", date);
return 0;
}
当我在2016-03-23运行此(Informix ESQL / C)程序时,我收到响应42451.当我测试SQL时:
$ sqlcmd -d stores "select date('2016-03-22') - date('1899-12-31')
> from informix.systables where tabid = 1"
输出为42450,这与ESQL / C程序一致(尽管sqlcmd
- IIUG中的那个,而不是Microsoft最近发明的同名 - 也是ESQL / C程序)。这与问题中显示的值不一致(2016-03-22为42447);我不知道为什么会出现差异。仅供记录,我在RHEL 5 Linux for x86_64上使用ESQL / C 3.70.FC4(和Informix 11.70.FC4) - 在Mac OS X 10.11.4上使用ESQL / C 4.10.FC5(和Informix 12.10.FC5) 。我不希望在任何其他平台上与ESQL / C 3.50(Informix 11.50)有任何区别。
1970-01-01的日期使用相同的方案的序号25568。因此,您可以使用以下内容将time
的值转换为正确的值:
$ perl -le 'print time, " ", int(time/(24*60*60))+25568'
1458764790 42451
$ perl -le 'sub informix_date_from_unix_time { return int($_[0]/86400) + 25568; }
> print time, " ", informix_date_from_unix_time(time)'
1458765443 42451
$
这是核心答案,在UTC时区准确无误;你需要仔细考虑日期边界和时区以及你想要的答案。
答案 1 :(得分:0)
您是否尝试使用system
作为命令调用echo $DATE
?
@args = ("command", "arg1", "arg2");
system(@args) == 0
or die "system @args failed: $?"
或者您可以使用%ENV
hash:
$ perl -e 'print $ENV{"DATE"}'
答案 2 :(得分:0)
从你所指的IBM网站上发布的代码(下面粘贴的)看来,rtoday()返回今天日期的内部表示,这种表示需要格式化具有rdatestr
功能。这可能意味着,这种表示完全取决于实现。
#include <stdio.h>
main()
{
mint errnum;
char today_date[20];
int4 i_date;
printf("RTODAY Sample ESQL Program running.\n\n");
/* Get todays date in the internal format */
rtoday(&i_date);
/* Convert date from internal format into a mm/dd/yyyy string */
if ((errnum = rdatestr(i_date, today_date)) == 0)
printf("\n\tTodays date is %s.\n", today_date);
else
printf("\n\tError %d in converting date to mm/dd/yyyy\n", errnum);
printf("\nRTODAY Sample Program over.\n\n");
}
答案 3 :(得分:0)
因此,经过一些工作和我正在寻找的价值的详细定义,我提出了这个:
#!/opt/standard_perl/perl5881/bin/perl
use Date::Calc qw(:all);
my $date = "03/19/2016";
print getSQLDate($date);
sub getSQLDate
{
my $value = shift;
my @date = split('/', $value);
my $alphaDay = 31;
my $alphaMonth = 12;
my $alphaYear = 1899;
my @alphaDate = ($alphaYear, $alphaMonth,$alphaDay);
my @currentDate = ($date[2], $date[0], $date[1]);
return Delta_Days(@alphaDate, @currentDate);
}
我的输出是:
42447
我根据我发现的关于我的SQL日期的定义做了这个:
Informix ESQL / C支持使用Informix ESQL / C的SQL DATE数据类型 主机变量的日期数据类型。日期数据类型存储内部DATE 值。它实现为4字节整数,其值为天数 自1899年12月31日以来。1899年12月31日之前的日期是负数, 而1899年12月31日之后的日期是正数。完整的 SQL DATE数据类型的说明,请参阅IBM®Informix®SQL指南: 参考