#!/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] ;
i've been trying to learn perl for a few days and i wrote that code to find the day from a given date. actually i converted this from a C code. But its not working true. The output is always Monday. Where am i making the mistake?
Don't do this yourself. Use a module. Time::Piece has been a standard part of the Perl distribution for almost ten years.
#!/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;
Some other tweaks I've made:
use strict
and use warnings
my
chomp()
to remove newlines from inputUpdate: I've now looked at your code in greater detail. There's only one error there.
Your logic looks like this:
if (we're in a leap year) {
Change the @months array to deal with leap years
Do the maths to calculate the day
}
When it should have looked like this:
if (we're in a leap year) {
Change the @months array to deal with leap years
}
Do the maths to calculate the day
So, unless your input year was a leap year, you were skipping all of the calculations. This meant that $s was never being given a value. Perl treats an undefined value as 0, therefore your final statement was always printing $week[0 + 1]
which is Monday.
If modules like Time::Piece weren't available, a Perl programmer would write your code like this:
#!/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];