2014-01-12 38 views
0

我有Perl substr函数的问题。这是如此简单,但无论如何......不知道是什么问题。Perl substr错误

sub encode_date 
{ 
    $date = $_[0]; 
    $day = substr($date, 0, 2); 
    $month = substr($date, 2, 2); 
    $year = substr($date, 6, 4); 

    return "$year-$month-$day"; 
} 

Sub接受“DD.MM.YYYY”格式的字符串,必须将其转换为“YYYY-MM-DD”格式。

输入: 1993年9月9日
输出: 0-09-93-19 ???

有人可以解释什么是错的,请。

p.s .:我为解码日期编写了另一个子文件(从'yyyy-mm-dd'到'dd.mm.yyyy'),并且所有工作都正常。

sub decode_date 
{ 
    $date = $_[0]; 
    $year = substr $date, 0, 4; 
    $month = substr $date, 5, 2; 
    $day = substr $date, 8, 2; 
    return $day.".".$month.".".$year; 
} 

当然,我试图返回值的两个substr $date, 0, 2;substr($date, 0, 2);和不同的组合。

+1

我不能重现您所描述的输出;我得到了'1993-0.090'(当然这仍然是错误的,但至少有意义,因为你的子串偏移是错误的)。 – ruakh

+1

您的第一个示例不会生成您描述的输出。然而,第一个例子的sub不会遭遇错误:第二个'substr'表达式应该是'substr($ date,3,2)'。 – DavidO

+0

是的。 $日期被编码了2次。这是问题所在。 'encode_date(encode_date($ date));'这样的东西,但在不同的文件。 TY。 –

回答

3

月份从索引3开始,而不是2

sub encode_date 
{ 
    my ($date) = @_; 
    my $day = substr($date, 0, 2); 
    my $month = substr($date, 3, 2); 
    my $year = substr($date, 6, 4); 

    return "$year-$month-$day"; 
} 

也许更好的方式是分割字符串非数字(.),反向号码,并用破折号加入他们-

sub encode_date 
{ 
    my ($date) = @_; 

    return join "-", reverse split /\D/, $date; 
} 
+0

糟糕。你张贴了相同的。做得好。魔鬼在细节中。谢谢。 –

0

你的问题是,你的偏移量是错误的,因为他们不没有考虑到分隔符。 (例如,本月开始于偏移3,不2,因为它是两个字符的日期加上一段时间后。)

这么说,我觉得写这个功能最好的办法是:

sub encode_date($) { 
    if ($_[0] =~ /^(\d\d)\.(\d\d)\.(\d{4})$/) { 
     return "$3-$2-$1"; 
    } 
} 
0
sub encode_date 
{ 
    $date = $_[0]; 
    $day = substr($date, 0, 2); 
    $month = substr($date, 3, 2); 
    $year = substr($date, 6, 4); 

    return "$year-$month-$day"; 
} 

有2个问题。
我用encode_date(encode_date($date));(2次)
另一个是$month = substr($date, 2, 2);正确是$month = substr($date, 3, 2);

+0

添加一些参数验证是明智的,所以像在同一个变量上调用该函数两次会引发错误 – Davs