Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations John Tel on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Check date string for day of week

Status
Not open for further replies.

ssmith001

Programmer
Oct 6, 2005
40
US
I'm sure this is easy, but I've looked everywhere and cannot find a way to do this. I have a flat file that I read, line by line. I need to look at a date that is on each of these lines, and is in the YYYYMMDD format, and see if this date falls on a Monday. If it does, I need to move the file to a different directory.

I have been able to open the file, and read each line. I cannot however figure out how to check each date. The date begins in column 64 and goes for 8 characters.
 
You can extract substrings with the substr function:
Code:
# start at position 63 (starts at 0) and go for 8 characters
$date = substr( $longer_string, 63, 8 );
 
Here's what I have so far. I can pull off the order type and the date, but how do I then take this date and find out the corresponding day of the week?


open (FILEH,"c:\\data\\ord.20060221230011") or die "Could not open order file";

while ($line = <FILEH>){
$ordertype = substr($line, 0, 2);
if ($ordertype eq "HM")
{
$orderdate = substr($line, 64, 8);
print "$ordertype $orderdate\n";
}

}
close FILEH;
 
There are modules you can download that will do this for you, but just using core modules and functions you can get away with doing something like this:
Code:
use Time::Local;

my $date_str='20060811';

my ($year, $month, $day) = $date_str =~ m/(\d{4})(\d{2})(\d{2})/;
my $time = timelocal("", "", "", $day, $month, $year);

if ((localtime($time))[6] == 1) {
    print "$date_str is a Monday!\n";
} else {
    print "$date_str is NOT a Monday\n";
}
If you have questions, take a look at perldoc Time::Local and perldoc -f localtime.
 
Here is one way.

Code:
use Date::Manip;
my $date = '20060811';
my $day_of_week = UnixDate($date,"%A");
print $day_of_week;
 
Hah! Ignore my code, it's not working correctly.
 
Never mind, I'm being an idiot today. Month 8 is September... now that wasn't a very good date to use as an example! But, it is a monday, so everything is ok. %-)
 
I've tweaked it a bit, but I don't think it's working. It says that 20060303 is a Monday, but it's not.

use Time::Local;

open (FILEH,"c:\\data\\ord.20060221230011") or die "Could not open order file";

while ($line = <FILEH>)
{
$ordertype = substr($line, 0, 2);

if ($ordertype eq "HM")
{
my $date_str = substr($line, 64, 8);

my ($year, $month, $day) = $date_str =~ m/(\d{4})(\d{2})(\d{2})/;
my $time = timelocal("", "", "", $day, $month, $year);

if ((localtime($time))[6] == 1) {
print "$date_str is a Monday!\n";
} else {
print "$date_str\n";
}
}
}
close FILEH;
 
You should probably take a look at the localtime function - April 3, 2006 is a Monday. I think you made the same mistake I did.

The months are:
0 - Jan
1 - Feb
2 - Mar
3 - Apr
... and so on.

So, try something like:
Code:
my $time = timelocal("", "", "", $day, $month-1, $year);
 
20060303 is indeed a Monday, when the months start at zero ;-) It's in the docs: here.
 
Thanks a ton guys! Adding the $month-1 fixed the problem. I just have one more question for you experts. I want to bail out of the loop as soon as I encounter a non-Monday date. Would I use "until" instead of the "while"?
 
last is your friend.
Code:
if ((localtime($time))[6] == 1) {
    print "$date_str is a Monday!\n";
} else {
    last;
}
 
What I am trying to do is this. Look in a certain directory for all files beginning with "ord.", spin through each of these files, looking at a particular date string. If all these date strings are Mondays, the file is bad, and I want to move it to the \badorders directory. As soon as I encounter a non-Monday date, I want to exit the loop because the file is OK, and I want to move it to the \goodorders directory.

Currently this code almost works, but I get a Permission Denied error when the move the attempted.

#!/usr/bin/perl
use File::Copy;
use Time::Local;

$filename = "c:\\data\\ord.20060221230011";
$goodpath = "c:\\data\\goodorders";
$badpath = "c:\\data\\badorders";

open (FILEH, $filename) or die "Could not open order file: $filename";

while ($line = <FILEH>)
{
$ordertype = substr($line, 0, 2);

if ($ordertype eq "HM")
{
my $date_str = substr($line, 64, 8);

my ($year, $month, $day) = $date_str =~ m/(\d{4})(\d{2})(\d{2})/;

my $time = timelocal("", "", "", $day, $month-1, $year); # For $month: Jan = 0, Feb = 1, etc.

if ((localtime($time))[6] == 1 ) {
# We have found a date that is a Monday. We need to keep looking at the
# rest of the dates to see if the rest of the dates are Mondays
print "All dates in the file $filename are Mondays. Now moving it to the $badpath directory\n";
move("$filename", "$badpath") or die "Could not move the file $filename. Move failed: $!";
} else {
# We have found a date that is not a Monday. This file is OK. We need to move it to be processed
print "Not all dates in the file $filename are Mondays. Now moving it to the $goodpath directory\n";
move("$filename", "$goodpath") or die "Could not move the file $filename. Move failed: $!";
last;
}
}
}
close FILEH;
 
Got to put a filename on the end of your path.

move("$filename", "$badpath\\file.ord"); # or whatever you are going to call it.

Raklet
 
Thanks for the reply. I think I got past that issue. I have two test files. One with all Monday dates, and one with other dates. I am expecting these files to be moved to the corresponding directories. The files are being moved as expected, for some reason I am getting another error: "Could not move the file /opt/manu/manu71/transport/natt1/order_temp/ord.20060221230012. Move failed: A file or directory in the path name does not exist. at test.pl line 109, <FILEH> line 4"

The other issue is that the code is supposed to print every order number and order date, and the order day (Mon..Fri). On the second test file, that has only Monday dates, only the first two lines are printed, when I am expecting 4. Any clues?

use strict;
use File::Copy;
use Time::Local;
use lib "/opt/perl/lib/site_perl/5.6.1/Mail";
use Mail::Sender;
my $instance = "natt1";
my $instance_root = "/opt/manu/manu71/transport/$instance";
my $goodordpath = "$instance_root/order_good";
my $badordpath = "$instance_root/order_bad";

my $allmonday = 0;

my $starttime = localtime;
print "\n\n*** Starttime = $starttime ***\n\n";

if (-d "$instance_root/order_temp") {
my $where = "$instance_root/order_temp";
print "Directory $where exists. Directory check was successful.\n\n";

# find the number of files we are to process
my @count = (<$instance_root/order_temp/ord.*>);
my $plural = (scalar(@count = (<$instance_root/order_temp/ord.*>)) == 1) ? "" : "s";
print "Processing ", scalar @count, " order file$plural.\n";

foreach my $orderfile (<$instance_root/order_temp/ord.*> ) {

print "\nProcessing Order File: $orderfile\n";

open (FILEH, $orderfile) or die "Could not open order file: $orderfile : $!\n";

while (my $line = <FILEH>) # loop as long as there are records in the file
{
my $ordertype = substr($line, 0, 2); # used to find the order header

if ($ordertype eq "HM") # only look at the dates on the header records
{
my $ordernum = substr($line, 3, 7);
my $date_str = substr($line, 64, 8);

my ($year, $month, $day) = $date_str =~ m/(\d{4})(\d{2})(\d{2})/;

my $time = timelocal("", "", "", $day, $month-1, $year); # For $month: Jan = 0, Feb = 1, etc.

if ((localtime($time))[6] == 1 ) # Monday
{
print " Order Number = $ordernum Order Date = $date_str is a Monday\n";
# We have found a date that is a Monday. We need to keep looking at the
# rest of the dates to see if the rest of the dates are Mondays
$allmonday = 1;
next; # move onto the next record and look at it
}
else
{
$allmonday = 0;
print " Order Number = $ordernum Order Date = $date_str is not a Monday. This file is OK to move and process.\n";
# We have found a date that is not a Monday. This file is OK. We need to move it to be processed
close FILEH;
move("$orderfile", $goodordpath) or die "Could not move the file $orderfile. Move failed: $!";
last; # bail out of the loop if date is not Monday
}
}

if (scalar $allmonday) {
move("$orderfile", $badordpath) or die "\nCould not move the file $orderfile. Move failed: $!";
$allmonday = 0;
}
}
close FILEH;
}
} else {
my $where = "$instance_root/order_temp";
print "Directory $where does not exist...now exiting\n\n";
}

my $endtime = localtime;
print "\n*** Endtime = $endtime ***\n\n";
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top