Complex record
s
111
6.3.1 Example
:
a differen
t
CD
file
Imagine, for example, if our 
CD
file was in a slightly different format, like this:
Name: Bragg, Billy
Title: Workers' Playtime
Label: Cooking Vinyl
Year: 1987
%%
Name: Bragg, Billy
Title: Mermaid Avenue
Label: EMI
Year: 1998
%%
Name: Black, Mary
Title: The Holy Ground
Label: Grapevine
Year: 1993
%%
Name: Black, Mary
Title: Circus
Label: Grapevine
Year: 1996
%%
Name: Bowie, David
Title: Hunky Dory
Label: RCA
Year: 1971
%%
Name: Bowie, David
Title: Earthling
Label: EMI
Year: 1997
In this case the data is exactly the same, but a record is now spread over a number of
lines. Notice that the records are separated by a line containing the character
sequence 
%%
.10 This will be our clue in working out the best way to read these
records. Earlier we briefly mentioned the variable 
$/
which defines the input record
separator. By setting this variable to an appropriate value we can get Perl to read the
file one whole record at a time. In this case the appropriate value is 
\n%%\n
. We can
now read in records like this:
local $/ = "\n%%\n";
while (<STDIN>) {
chomp;
print "Record $. is\n$_";
}
10
This is a surprisingly common record separator, due to its use as the record separator in the data files read
by the UNIX 
fortune
program.
Rotate single page in pdf reader - rotate PDF page permanently in C#.net, ASP.NET, MVC, Ajax, WinForms, WPF
Empower Users to Change the Rotation Angle of PDF File Page Using C#
rotate pdf page; rotate pdf pages in reader
Rotate single page in pdf reader - VB.NET PDF Page Rotate Library: rotate PDF page permanently in vb.net, ASP.NET, MVC, Ajax, WinForms, WPF
PDF Document Page Rotation in Visual Basic .NET Class Application
rotate all pages in pdf; rotate one page in pdf
112
CHAPTER 
Record-or
i
ented data
Remember that when Perl reads to the next occurrence of the input record separa-
tor, it includes the separator character sequence in the string that it returns. We
therefore use 
chomp
to remove that sequence from the string before processing it.
So now we have the record in a variable. How do we go about extracting the
individual fields from within the records? This is relatively easy as we can go back to
using 
split
to separate the fields. In this case the field separator is a newline char-
acter so that is what we need to split on.
local $/ = "\n%%\n";
while (<STDIN>) {
chomp;
print join('|', split(/\n/)), "\n";
}
This code will print each of the records on one line with the fields separated by a
pipe character. We are very close to having all of the fields in a form that we can use,
but there is one more step to take.
Making use of 
t
he ex
t
ra da
t
a
One difference between this format and the original (one record per line) format
for the CD file is that the individual fields are now labeled. We need to lose these
labels, but we can first make good use of them. Eventually we want each of our
records to end up in a hash. The values of the hash will be the values of the data
fields, but what are the keys? In previous versions of the 
CD
input routines we have
always hard-coded the names of the data fields, but here we have been given them.
Let’s use them to create the keys of our hash. This will hopefully become clearer
when you see this code:
1: $/ = "\n%%\n";
2:
3: my @CDs;
4:
5: while (<STDIN>) {
6:
chomp;
7:
my (%CD, $field);
8:
9:
my @fields = split(/\n/);
10:
foreach $field (@fields) {
11:
my ($key, $val) = split (/:\s*/, $field, 2);
12:
$CD{lc $key} = $val;
13:
}
14:
15:
push @CDs, \%CD;
16: }
VB.NET PDF Page Delete Library: remove PDF pages in vb.net, ASP.
Able to remove a single page from adobe PDF document in VB.NET. using RasterEdge. XDoc.PDF; How to VB.NET: Delete a Single PDF Page from PDF File.
pdf rotate single page; reverse page order pdf online
C# PDF Page Delete Library: remove PDF pages in C#.net, ASP.NET
application. Able to remove a single page from PDF document. Ability Demo Code: How to Delete a Single PDF Page from PDF File in C#.NET. How to
rotate pdf page permanently; pdf rotate page
Complex record
s
113
Let’s examine this code line by line.
Line 1 sets the input record separator to be 
%%\n
.
Line 3 defines an array variable that we will use to store the 
CD
s.
Line 5 starts the 
while
loop which reads each line from 
STDIN
in to 
$_
.
Line 6 calls 
chomp
to remove the 
%%\n
characters from the end of 
$_
.
Line 7 defines two temporary variables. 
%CD
will store the data for one 
CD
and
$field
will be used as temporary storage when processing the fields.
Line 9 creates an array 
@fields
which contains each of the fields in the record,
split on the newline character. Notice that 
split
throws away the separator charac-
ter so that the fields in the array do not have newline characters at the end of them.
Line 10 starts a 
foreach
loop which processes each field in the record in turn.
The field being processed is stored in 
$field
.
Line 11 splits the field into its key and its value, assigning the results to 
$key
and
$value
. Note that the regular expression that we split on is 
/:\s*/
. This matches a
colon followed by zero or more white space characters. In our sample data, the sep-
arator is always a colon followed by exactly one space, but we have made our script
a little more flexible. We also pass a limit to 
split
so that the list returned always
contains two or fewer elements.
Line 12 assigns the value to the key in the 
%CD
hash. Notice that we actually use
the lower-case version of 
$key
. Again this just allows us to cope with a few more
potential problems in the input data.
Line 13 completes the 
foreach
loop. At this point the 
%CD
hash should have
four records in it.
Line 15 pushes a reference to the 
%CD
onto the 
@CDs
array.
Line 16 completes the 
while
loop. At this point the 
@CDs
array will contain a
reference to one hash for each of the 
CD
s in the collection.
6.3.2 Special values for $
/
There are two other commonly used values for 
$/
undef
and the empty string.
Setting 
$/
to 
undef
puts Perl into “slurp mode.” In this mode there are no record
separators and the whole input file will be read in one go. Setting 
$/
to the empty
string puts Perl into “paragraph mode.” In this mode, records are separated by one
or more blank lines. Note that this is not the same as setting 
$/
to 
\n\n
. If a file has
two or more consecutive blank lines then setting 
$/
to 
\n\n
will give you extra
empty records, whereas setting it to the empty string will soak up any number of
blank lines between records. There are, of course, times when either of these behav-
iors is what is required.
You can also set 
$/
to a reference to a scalar (which should contain an integer).
In this case Perl will read that number of bytes from the input stream. For example:
VB.NET PDF- View PDF Online with VB.NET HTML5 PDF Viewer
PDF to images, C#.NET PDF file & pages edit, C#.NET PDF pages extract, copy, paste, C#.NET rotate PDF pages, C# Single page. View PDF in single page display mode
rotate pages in pdf and save; how to rotate pdf pages and save permanently
How to C#: Basic SDK Concept of XDoc.PDF for .NET
insert, delete, re-order, copy, paste, cut, rotate, and save or query data and save the PDF document. The PDFPage class presents a single page in a PDFDocument
pdf rotate single page and save; how to rotate one pdf page
114
CHAPTER 
Record-or
i
ented data
local $/ = \1024;
my $data = <DATA>;
will read in the next kilobyte from the file handle 
DATA
. This idiom is more useful
when reading binary files.
One thing that you would sometimes like to do with 
$/
is set it to a regular
expression so that you can read in records that are delimited by differing record
markers. Unfortunately, you must set 
$/
to be a fixed string, so you can’t do this.
The best way to get around this is to read the whole file into a scalar variable (by
setting 
$/
to 
undef
) and then use 
split
to break it up into an array of records.
The first parameter to 
split
is interpreted as a regular expression.
6.4
Special problems wi
t
h da
t
e fields
It is very common for data records to contain dates.11 Unfortunately, Perl’s date
handling seems to be one of the areas that confuses a large number of people, which
is a shame, because it is really very simple. Let’s start with an overview of how Perl
handles dates.
6.4.1 Buil
t
-
in Perl da
t
e func
t
ions
As far as Perl is concerned, all dates are measured as a number of seconds since the
epoch. That sounds more complex than it is. The epoch is just a date and time from
which all other dates are measured. This can vary from system to system, but on
many modern computer systems (including all 
UNIX
systems) the epoch is defined
as 00:00:00 
GMT
on Thursday, Jan. 1, 1970. The date as I’m writing this is
943011797, which means that almost a billion seconds have passed since the begin-
ning of 1970.
Ge
t
t
ing 
t
he curren
t
da
t
e and 
t
ime wi
t
t
ime func
t
ions
You can attain the current date and time in this format using the 
time
function. I
generated the number in the last paragraph by running this at my command line:
perl -e "print time";
This can be useful for calculating the time that a process has taken to run. You can
write something like this:
my $start = time;
# Do lots of clever stuff
11
When I mention dates in this section, I generally mean dates and times.
C# PDF Convert to Tiff SDK: Convert PDF to tiff images in C#.net
Both single page and multipage tiff image files can be created from PDF. Supports tiff compression selection. Supports for changing image size.
pdf rotate all pages; rotate all pages in pdf and save
VB.NET PDF: Basic SDK Concept of XDoc.PDF
insert, delete, re-order, copy, paste, cut, rotate, and save or query data and save the PDF document. The PDFPage class presents a single page in a PDFDocument
save pdf after rotating pages; how to rotate pdf pages and save
116
CHAPTER 
Record-or
i
ented data
The month and the day of the week are given as zero-based numbers. This is
because you are very likely to convert these into strings using an array of month or
day names.
The year is given as the number of years since 1900. This is well-documented
and has always been the case, but the fact that until recently this has been a two-
digit number has led many people to believe that it returns a two-digit year. This
has led to a number of broken scripts gaining a great deal of currency and it is com-
mon to see scripts that do something like this:
my $year = (localtime)[5];
$year = "19$year"; # THIS IS WRONG!
or (worse)
$year = ($year < 50) ? "20$year" : "19$year"; # THIS IS WRONG!
The correct way to produce a date using 
localtime
is to do something like this:
my @months = qw/January February March April May June July August
September October November December/;
my @days
= qw/Sunday Monday Tuesday Wednesday Thursday Friday Saturday/;
my @now = localtime;
$now[5] += 1900;
my $date = sprintf '%s %02d %s %4d, %02d:%02d:%02d',
$days[$now[6]], $now[3], $months[$now[4]], $now[5],
$now[2], $now[1], $now[0];
As hinted in the code above, if you don’t need all of the date information, it is sim-
ple enough to use an array slice to get only the parts of the array that you want.
These are all valid constructions:
my $year = (localtime)[5];
my ($d, $m, $y) = (localtime)[3 .. 5];
my ($year, $day_no) = (localtime)[5, 7];
Ge
t
t
ing 
t
he epoch seconds using 
t
imelocal
It is therefore easy enough to convert the return value from 
time
to a readable date
string. It would be reasonable to want to do the same in reverse. In Perl you can do
that by using the 
timelocal
function. This function is not a Perl built-in function,
but is included in the standard Perl library in the module 
Time::Local
.
To use 
timelocal
, you pass it a list of time values in the same format as they are
returned by 
localtime
. The arguments are seconds, minutes, hours, day of
month, month (January is 0 and December is 11), and year (in number of years
since 1900; e.g., 2000 would be passed in as 100). For example to find out how
many seconds will have passed at the start of the third millennium (i.e., Jan. 1,
2001) you can use code like this:
Spec
i
al problem
s
w
i
th date f
i
eld
s
117
use Time::Local;
my $secs = timelocal(0, 0, 0, 1, 0, 101);
Examples
:
da
t
e and 
t
ime manipula
t
ion using Perl buil
t
-
in func
t
ions
With 
localtime
and 
timelocal
it is possible to do just about any kind of data
manipulation that you want. Here are a few simple examples.
Finding the date in x day
s
time
This is, in principle, simple but there is one small complexity. The method that we
use is to find the current time (in seconds) using 
localtime
and add 86,400 (24 x
60 x 60) for each day that we want to add. The complication arises when you try to
calculate the date near the time when daylight saving time either starts or finishes. At
that time you could have days of either 23 or 25 hours and this can affect your calcu-
lation. To counter this we move the time to noon before carrying out the calculation.
use Time::Local;
my @now = localtime;
# Get the current date and time
my @then = (0, 0, 12, @now[3 .. 5]); # Normalize time to 12 noon
my $then = timelocal(@then);
# Convert to number of seconds
$then += $x * 86_400;
# Where $x is the number of days to add
@then = localtime($then);
# Convert back to array of values
@then[0 .. 2] = @now[0 .. 2];
# Replace 12 noon with real time
$then = timelocal(@then);
# Convert back to number of seconds
print scalar localtime $then;
# Print result
Finding the date of the previou
s
Saturday
Again, this is pretty simple, with just one slightly complex calculation, which is
explained in the comments. We work out the current day of the week and, therefore,
can work out the number of days that we need to go back to get to Saturday.
my @days = qw/Sunday Monday Tuesday Wednesday Thursday Friday
Saturday/;
my @months = qw/January February March April May June July August
September October November December/;
my $when = 6; # Saturday is day 6 in the week.
# You can change this line to get other days of the week.
my $now = time;
my @now = localtime($now);
# This is the tricky bit.
# $diff will be the number of days since last Saturday.
# $when is the day of the week that we want.
118
CHAPTER 
Record-or
i
ented data
# $now[6] is the current day of the week.
# We take the result modulus 7 to ensure that it stays in the
# range 0 - 6.
my $diff = ($now[6] - $when + 7) % 7;
my $then = $now - (24 * 60 * 60 * $diff);
my @then = localtime($then);
$then[5] += 1900;
print "$days[$then[6]] $then[3] $months[$then[4]] $then[5]";
Finding the date of the fir
s
t Monday in a given year
This is very similar in concept to the last example. We calculate the day of the week
that January 1 fell on in the given year, and from that we can calculate the number
of days that we have to move forward to get to the first Monday.
use Time::Local;
# Get the year to work on
my $year = shift || (localtime)[5] + 1900;
# Get epoch time of Jan 1st in that year
my $jan_1 = timelocal(0, 0, 0, 1, 0, $year - 1900);
# Get day of week for Jan 1
my $day = (localtime($jan_1))[6];
# Monday is day 1 (Sunday is day 0)
my $monday = 1;
# Calculate the number of days to the first Monday
my $diff = (7 - $day + $monday) % 7;
# Add the correct number of days to $jan_1
print scalar localtime($jan_1 + (86_400 * $diff));
Be
t
t
er da
t
e and 
t
ime forma
t
t
ing wi
t
h POSIX
:
:
s
t
rf
t
ime
There is one other important date function that comes with the Perl standard
library. This is the 
strftime
function that is part of the 
POSIX
module. 
POSIX
is an
attempt to standardize system calls across a number of computer vendors’ systems
(particularly among 
UNIX
vendors) and the Perl 
POSIX
module is an interface to
these standard functions. The 
strftime
function allows you to format dates and
times in a very controllable manner. The function takes as arguments a format
string and a list of date and time values in the same format as they are returned by
localtime
. The format string can contain any characters, but certain character
sequences will be replaced by various parts of the date and time. The actual set of
sequences supported will vary from system to system, but most systems should sup-
port the sequences shown in table 6.1.
Spec
i
al problem
s
w
i
th date f
i
eld
s
119
Here is a simple script which uses 
strftime
.
use POSIX qw(strftime);
foreach ('%c', '%A %d %B %Y', 'Day %j', '%I:%M:%S%p (%Z)') {
print strftime($_, localtime), "\n";
}
which gives the following output:
22/05/00 14:38:38
Monday 22 May 2000
Day 143
02:38:38PM (GMT Daylight Time)
Table 6.1 POSIX::strftime charac
t
er 
s
equence
s
%a 
s
hort day name (Sun to Sat)
%
A
long day name (Sunday to Saturday)
%b 
s
hort month name (Jan to Dec)
%B 
long month name (January to December)
%c 
full date and time in the 
s
ame format a
s
localtime return
s
in 
s
calar context
%d 
day of the month (01 to 31)
%H 
hour in 24
-
hour clock (00 to 23)
%
I
hour in 12
-
hour clock (01 to 12)
%
j
day of the year (001 to 366)
%m 
month of the year (01 to 12)
%M 
minute
s
after the hour (00 to 59)
%p 
A
M or PM
%S 
s
econd
s
after the minute (00 to 59)
%w 
day of the week (0 to 6)
%y 
year of the century (00 to 99)
%
Y
year (0000 to 9999)
%Z 
time zone 
s
tring (e.g., GMT)
%% 
a percent character
120
CHAPTER 
Record-or
i
ented data
In
t
erna
t
ional issues wi
t
h da
t
e forma
t
s
One of the most intractable problems with dates has nothing to do with computer
software, but with culture. If I tell you that I am writing this on 8
/
9
/
2000, with-
out knowing whether I am European or American you have no way of knowing if I
mean the 8th of September or the 9th of August. For that reason I’d recommend
that whenever possible you always use dates that are in the order year, month, and
day as that is far less likely to be misunderstood. There is an 
ISO
standard (number
8601) which recommends that dates and times are displayed in formats which can
be reproduced using the 
POSIX::strftime
templates 
%Y-%m-%dT%h:%M:%S
(for
date and time) or 
%Y-%m-%d
(for just the date).
All of the functions that we have just discussed come with every distribution of
Perl. You should therefore see that it is quite easy to carry out complex date manip-
ulation with vanilla Perl. As you might suspect, however, on the 
CPAN
there are a
number of modules that will make your coding life even easier. We will look in some
detail at two of them: 
Date::Calc
and 
Date::Manip
.
6.4.2 Da
t
e
:
:
Calc
Date::Calc
contains a number of functions for carrying out calculations using dates.
One important thing to know about 
Date::Calc
is that it represents dates dif-
ferently from Perl’s internal functions. In particular when dealing with months, the
numbers will be in the range 1 to 12 (instead of 0 to 11), and when dealing with
days of the week the numbers will be in the range 1 to 7 instead of 0 to 6.
Examples
:
da
t
e and 
t
ime manipula
t
ion wi
t
h Da
t
e
:
:
Calc
Let’s look at using 
Date::Calc
for solving the same three problems that we dis-
cussed in the section on built-in functions.
Finding the date in x day
s
time
With 
Date::Calc
, this becomes trivial as we simply call 
Today
to get the current
date and then call 
Add_Delta_Days
to get the result. Of course we can also call
Date_to_Text
to get a more user friendly output. The code would look like this:
print Date_to_Text(Add_Delta_Days(Today(), $x)); # Where $x is the
# number of days to add
Finding the date of the previou
s
Saturday
There are a number of different ways to solve this problem but here is a reasonably
simple one. We find the week number of the current week and then calculate the date
of Monday in this week. We then subtract two days to get to the previous Saturday.
my ($year, $month, $day) = Today;
my $week = Week_Number($year, $month, $day);
print Date_to_Text(Add_Delta_Days(Monday_of_Week($week, $year), -2));
Documents you may be interested
Documents you may be interested