0

我正在寻找一种将 YYDDD 格式的日期转换为 YY/MM/DD 的方法。

即 12212 变为 12/07/30。

php 示例可在http://www.longpelaexpertise.com.au/toolsJulian.php找到,您可以在http://landweb.nascom.nasa.gov/browse/calendar.html找到 DDD 日历

无论有无 perl 模块,我都将不胜感激。

谢谢!

编辑:我不是在寻找一种方法来转换 php2perl 或类似的东西。我只是在寻找一种使用 perl 将 YYDDD 转换为 YY/MM/DD 的方法。我更喜欢一种不使用任何额外 perl 模块的方法,但是如果这是唯一的方法,那么我将欢迎使用 perl 模块的示例。

4

3 回答 3

4

最好的方法是用来Time::Piece解析日期并重新格式化它,像这样

Time::Piece->strptime('12212', '%y%j')->strftime('%y/%m/%d')

然而不幸的是,该模块不接受%jstrptime格式的(一年中的一天)(尽管它在 中很好strftime)。

第二个最佳选项strftime来自POSIX模块。该字符串必须首先拆分为年和日,并且年中的日是从零开始的,因此必须减去一个,但是转换很简单。它可能最好打包成一个子程序,像这样

use strict;
use warnings;

use POSIX 'strftime';

sub yj2ymd {
  my ($year, $yday) = $_[0] =~ /(\d\d)(\d\d\d)/;
  strftime('%y/%m/%d', 0, 0, 0, 0, 0, 2000+$year, 0, $yday-1);
}

print yj2ymd('12212');

输出

12/07/30

如果您期望上个世纪的任何日期,您将不得不对这一年做一些更有趣的事情。

于 2013-08-28T14:13:18.610 回答
3

我喜欢Time::Piece仅仅是因为它带有 Perl,因为我相信 5.10 版。你会发现几十个日期/时间模块,每个人都有自己的最爱,但随着Time::Piece成为官方发行版的一部分,是时候切换到它了。

要使用 Time::Piece,您需要了解strptime ( STR ing P ass TIME ) 和strftime ( STR ing F格式TIME ) 两者都使用%x字母格式来表示时间字符串的某些方面。原因是Time::Piece使用相同的%x格式字符将您的时间字符串转换为时间对象,有时将该时间对象格式化为您的字符串。

strftime的手册页:

%j

以十进制数表示的一年中的日期(范围 001 到 366)。

和:

%y

年份为十进制数,不带世纪(范围 00 到 99)。

现在转换您的日期:

use Time::Piece;

my $old_time = "12212";   #YYddd
my $time = Time::Piece->strptime( $old_time, "%y%j" );
my $new_time = $time->ymd("/"); Now in YY/MM/DD format

哎呀

等一下——strptime 不能理解 %j。这将给出错误的答案。

我没有对此进行测试,因为我经常使用 Time::Piece,以至于我可以在睡梦中做到这一点。我以前从未%jTime::Piece. perldoc 没有提到任何关于%j不工作的内容,而且我没有收到任何错误。这不好。

新战略。YYddd我可以将字符串解析为年和日。然后,我可以将年初作为01/01/$year. 在那之后,我可以把天数加到年里。但是,要正确执行此操作,我需要来自Time::Seconds的常量:

use strict;
use warnings;
use feature qw(say);
use Time::Piece;
use Time::Seconds;

my $old_date = "12212";
$old_date =~ /(..)(.*)/;
my $year = $1;
my $days = $2;

my $time = Time::Piece->strptime("01/01/$year", "%m/%d/%y");
$time += ( ( $days - 1 ) * ONE_DAY);  #01/01/$year is day 1 and not 0

say  $time->strftime("%y/%m/%d");

这给出12/07/30了答案。


公告

模块的所有者Time::Piece修复了模块中的错误。1.23 版现在可以使用:

use warnings;
use strict;
use autodie;
use feature qw(say);
use Data::Dumper;

use Time::Piece;

my $old_time = "12212";   #YYddd
my $time = Time::Piece->strptime( $old_time, "%y%j" );
my $new_time = $time->ymd("/"); #Now in YY/MM/DD format
say "Version: $Time::Piece::VERSION";
say $new_time;

这打印出来:

Version: 1.23
2012/07/30
于 2013-08-28T14:07:53.173 回答
1

这是一个简短而甜蜜的方法来做你想做的事:

#!/usr/bin/perl

use strict;
use Date::Calc qw(Add_Delta_Days);

my $dt = '12212';

my $startYr = 2000 + substr($dt, 0, 2);
my $daysToAdd = substr($dt, 2) - 1;
my ($newYr, $newMo, $newDay) = Add_Delta_Days($startYr, 1, 1, $daysToAdd);

printf("%02d/%02d/%02d\n", $newYr % 100, $newMo, $newDay);
于 2013-08-28T14:41:25.800 回答