查找给定日期的一天

时间:2017-08-08 16:37:11

标签: perl

#!/usr/bin/perl

@month = (31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
@week = ("Sunday", "Monday","Tuesday", "Wednesday","Thursday", "Friday", 
    "Saturday");

print "date:\n";
$date=<STDIN>;
print "mon:\n";
$mon=<STDIN>;
print "year:\n";
$year=<STDIN>;

if ( ($year % 400 == 0) || ($year % 4 == 0) && ($year % 100 != 0) )
{
    $month[1] = 29 ;
    for($i = 0 ; $i < $mon - 1 ; $i++)
    {       
        $s = $s + $month[$i] ;
        $s = $s + ($date + $year + ($year / 4) - 2) ;
        $s = $s % 7 ;
    }
}
print $week[$s+1] ;

我一直在努力学习perl几天,然后我编写了代码来查找给定日期的日期。实际上我从C代码转换了这个。但它不成功。输出始终是星期一。我在哪里弄错了?

4 个答案:

答案 0 :(得分:5)

正如@Chris Turner指出的那样,你的代码中没有路径可以处理不是闰年的情况。要解决此问题并实现您的既定目标,只需对代码进行一处小改动。

 choices = sharedPreferences.getString(MainActivity.CHOICES, null);
应该重写

并重新缩进为

if( ($year % 400 == 0) || ($year % 4 == 0) && ($year % 100 != 0) ) {
   $month[1] = 29 ;
   for($i = 0 ; $i < $mon - 1 ; $i++) {
      ...
   }
}
print $week[$s+1] ;

这样if( ($year % 400 == 0) || ($year % 4 == 0) && ($year % 100 != 0) ) { $month[1] = 29 ; } for($i = 0 ; $i < $mon - 1 ; $i++) { ... } print $week[$s+1] ; 只会针对闰年进行更新,但$month[1]循环中的代码始终会运行。

经验丰富的Perl程序员也会建议您使用

启动每个脚本
for

因为这些pragma促进了良好的编程实践,并有助于在开发早期发现许多错误。他们不会帮助解决这个问题,但是如果你开始使用它们,他们会帮助解决下一个问题。

答案 1 :(得分:2)

为了介绍日期和时间最广泛使用的模块,这里有DateTime

use warnings;
use strict;
use feature qw(say);

use DateTime;

# ... acquire input ($year, $mon, $date)

my $dt = DateTime->new(year => $year, month => $mon, day => $date);

say $dt->day_name;

这是一个非常大且“重”的模块,具有很多功能。还有其他人。

虽然我支持手动将其作为学习的一部分,但在处理日期和时间之后,您将需要使用模块。

答案 2 :(得分:2)

不要自己这样做。使用模块。 Time::Piece已经成为Perl发行版的标准部分,差不多十年了。

#!/usr/bin/perl

use strict;
use warnings;
use feature 'say';

use Time::Piece;

print "date:\n";
chomp(my $date = <STDIN>);
print "mon:\n";
chomp(my $mon = <STDIN>);
print "year:\n";
chomp(my $year = <STDIN>);

my $tp = Time::Piece->strptime("$year-$mon-$date", '%Y-%m-%d');

say $tp->fullday;

我做过的其他一些调整:

  • 始终use strictuse warnings
  • 使用my
  • 声明变量
  • 使用chomp()删除输入中的换行符

更新:我现在更详细地查看了您的代码。那里只有一个错误。

你的逻辑是这样的:

if (we're in a leap year) {
    Change the @months array to deal with leap years
    Do the maths to calculate the day
}

什么时候看起来像这样:

if (we're in a leap year) {
    Change the @months array to deal with leap years
}
Do the maths to calculate the day

因此,除非您的输入年份是闰年,否则您正在跳过所有计算。这意味着$ s永远不会被赋予价值。 Perl将未定义的值视为0,因此您的最终语句始终打印$week[0 + 1],即星期一。

如果像Time :: Piece这样的模块不可用,那么Perl程序员就会编写这样的代码:

#!/usr/bin/perl

# Force us to declare variables.
use strict;
# Get Perl to tell us when we're doing something stupid
use warnings;
# Allow the use of say()
use feature 'say';

# Declare variables with my()
my @month = (31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
# qw(...) defines a list without all that tedious punctuation
my @week = qw(Sunday Monday Tuesday Wednesday Thursday Friday Saturday);

print "date:\n";
# Use chomp() to remove newlines from input
chomp(my $date = <STDIN>);
print "mon:\n";
chomp(my $mon = <STDIN>);
print "year:\n";
chomp(my $year = <STDIN>);

# This logic can be cleaned up a lot.
if ( ($year % 400 == 0) || ($year % 4 == 0) && ($year % 100 != 0) ) {
    $month[1] = 29 ;
}

# Initialise $s to avoid warnings later
my $s = 0;
# A foreach look is almost always cleaner than for (;;)
foreach my $i (0 .. $mon - 2) {
    # Haven't checked your calculations (but they seem to work
    # += is  useful shortcut
    $s += $month[$i];
    $s += ($date + $year + ($year / 4) - 2);
    $s %= 7;
}

# say() is like print() but with an extra newline
say $week[$s+1];

答案 3 :(得分:1)

HibernateSpec

更好的是,

use Time::Local qw( timegm );

my @dow_names = qw( Sunday Monday Tuesday Wednesday Thursday Friday Saturday );

my $Y = ...;
my $m = ...;
my $d = ...;

my $epoch = timegm(0, 0, 0, $d, $m-1, $Y-1900);
my $dow = ( gmtime($epoch) )[6];
my $dow_name = $dow_names[$dow];

你也可以使用DateTime;它使用起来比较简单,但它并不像上面使用的模块那么轻。