我試圖將中國月球系統轉換爲使用Perl的Gregorian,既有趣又有學習的目的。我認爲有一種簡單的數學算法來完成這項工作,但事實證明我錯了。無論如何,經過一段時間的搜索後,我發現一些SAS代碼可以完成這項工作。那麼,我就不難想出如何重寫Perl中的大部分代碼。但也有一些是這樣的:是否有一個Perl的等效的SAS'INTNX函數或JavaScript的Dateadd函數?
Convert2Gregorian = INTNX ('day', conDate, AddDay-1);
谷歌告訴我,INTNX是可以返回之後,在特定日期間隔已被添加日期的功能。但使用關鍵字「Perl INTNX」給了我沒有用處。後來我發現寫在Javascript腳本,一般的方法是對除了相同的JavaScript使用DATEADD函數,是這樣的:
Return DateAdd(DateInterval.Day, AddDay - 1, conDate)
我也嘗試使用PPM搜索,但未能找到我想要的模塊。有人能給我一些指點嗎?
感謝提前:)
更新
感謝@psilva和@hobbs :)
哈哈,我終於可以翻譯一個編程語言到另一種。這很有趣:) 只是爲了好玩,也許以後參考: 這是原始的SAS代碼和我翻譯的Perl代碼。糾正我,如果我錯了:)
注:數據不完整。
SAS代碼如下:
data DateNtoG (drop = Ngstrings conDate AddMonth AddDay Mrunyue I);
array NGlist{43} $18_TEMPORARY_(
"010110101010170130" /*(1968)*/
"010101101010000217" /*(1969)*/
"100101101101000206" /*(1970)*/
"010010101110150127" /*(1971)*/
);
input tYear tMonth tDay RunYue;
if (tyear >1967 and tyear<2011) then do;
NGstrings = NGlist(tYear - 1967);
conDate = MDY (substr (NGstrings,15,2),(NGstrings, 17,2), tYear);
AddMonth = tMonth;
select (substr(NGstrings, 14, 1));
when ("A") Mrunyue=10;
when ("B") Mrunyue=11;
when ("C") Mrunyue=12;
otherwise Mrunyue = substr (NGstrings, 14,1);
end;
if ((RunYue=1) and (tMonth=Mrunyue) ANDMrunyue>0)or ((tMonth Mrunyue) AND Mrunyue>0) then
do;
Addmonth = tMonth+1;
end;
AddDay = tDay;
do i = 1 To AddMonth-1;
AddDay = AddDay + 29 + substr(NGstrings,i,1);
end;
dNtoG = INTNX ('day', conDate, AddDay - 1);
put "Transfereddate:" dNtoGdate9.;
end;
TRANSLATED的Perl代碼如下: 沒處理不確定的情況下,暫時
(我改變了原來的SAS變量名)
#!perl
# A Chinese-Gregorian Calendar System Converter just for Testing
use Date::Calc qw(Add_Delta_Days);
use integer;
use strict;
use warnings;
$_ = shift @ARGV;
if (length == 8) {
$_.=0;
}
my ($Lunar_Year,$Lunar_Month,$Lunar_Day,$Leap_Month) = /(\d\d\d\d)(\d\d)(\d\d)(\d)/;
my %Lunar_Year_Patterns = qw/1968 010110101010170130 1969 010101101010000217 1970 100101101101000206 1971 010010101110150127/;
if (substr ($Lunar_Year_Patterns{$Lunar_Year},13,1) =~ /A/) {
$Leap_Month = 10;
} elsif (substr ($Lunar_Year_Patterns{$Lunar_Year},13,1)=~ /B/){
$Leap_Month = 11;
} elsif (substr ($Lunar_Year_Patterns{$Lunar_Year},13,1)=~ /C/){
$Leap_Month = 12;
} else {
$Leap_Month = substr($Lunar_Year_Patterns{$Lunar_Year},13,1);
}
my $First_Lunar_Day_In_Gregorian_Month = substr($Lunar_Year_Patterns{$Lunar_Year},14,2);
my $First_Lunar_Day_In_Gregorian_Day = substr($Lunar_Year_Patterns{$Lunar_Year},16,2);
my $AddMonth;
if ((($Leap_Month ==1) && ($Lunar_Month == $Leap_Month) && ($Leap_Month > 0)) || (($Lunar_Month > $Leap_Month) && ($Leap_Month>0))){
$AddMonth = $Lunar_Month +1;
} else {
$AddMonth = $Lunar_Month;
}
my $AddDay;
$AddDay = $Lunar_Day;
for(my $i = 1; $i <= $AddMonth - 1; $i++){
$AddDay = $AddDay +29 + substr($Lunar_Year_Patterns{$Lunar_Year},$i,1);
}
my @Gregorian = Add_Delta_Days($Lunar_Year,$First_Lunar_Day_In_Gregorian_Month,$First_Lunar_Day_In_Gregorian_Day,$AddDay -1);
print @Gregorian;
@hobbs,謝謝你的指針。我會嘗試DateTime。謝謝:) – Mike 2009-12-17 11:47:28
DateTime的+1。這是我在處理其他語言時最想念的Perl「特性」之一。 – 2009-12-17 12:46:21