http://qs321.pair.com?node_id=275963
Category: Miscellaneous/Text processing
Author/Contact Info (c)2003 Mark Beihoffer, released under your choice of Artistic or GPL license.
Description: I've used this script under both Win32 and OpenBSD to generate a plain-text file that I use for keeping a little journal of my thoughts.

I wrote it a long time ago (it's written in baby Perl) but have been using it monthly to make my journals, which are then really easy to edit and archive. I like keeping them in plain text format because then the entries are easy to cut and paste into other applications (emails, HTML forms, word processors, etc) without having to start a gigantic program or be online, etc.

I also like it because it simply writes a date for each day of the current month, like "Monday, July 14, 2003", with a few line breaks thrown in. That way, I can write down what I worked on that day, keep little notes or code snippets, lyrics, and so forth, and easily go back and review my month. And cross-platform date handling is a little trickier than I had initially expected, so I learned some things writing it, too.

Anyway, I know it isn't fancy, but since I use it every month, I figure somebody else out there might.

#$/usr/bin/perl -w

use strict;
use warnings;


my ($date, $month, $year, $weekday) = (localtime)[3,4,5,6];


$month++;                        # Converts $month to human readable.

my $days = MonthDays($month, $year);            # Figures out how many
+ $days are in current month.

my $offset = ($date % 7);                # Returns the offset of weekd
+ays today is from the 1st, 0-6.
                            # i.e. 0 means that today's $weekday == th
+e 1st's $weekday.

my @months = qw(January February March April May June July August Sept
+ember October November December);

my $i = 1;                        # Set increment counter to 1.

$month--;                        # Converted $month back to machine-re
+adable.

$month = $months[$month];                # Converts $month number to m
+onth Name
$year = $year + 1900;                    # Converts $year to human rea
+dable 
    
$weekday = ($weekday - $offset);

my @weekdays = qw(Monday Tuesday Wednesday Thursday Friday Saturday Su
+nday);


######################################################################
+###########################
#                                                #
#        This section names the file - either journal.txt or journal_m
+onth_year.txt    #
#                                                #
#                                                #
######################################################################
+###########################

my $file = "journal.txt";

if (-e "journal.txt")  {            # Checks to see if journal.txt exi
+sts.

    $file = ("journal_" . $month . "_" . $year . ".txt");  # If so, gi
+ves it a dated name instead.

}

if (-e $file) {

    die "File $file already exists!\n";

        sleep(2);            # I sleep here so I can read the msg in W
+in32.

}

######################################################################
+###########################
#                                                #
#        OK, now're we're ready to get on with things. This part actua
+lly outputs    #
#        the file in a simple, nicely formatted monthly journal.      
+          #
#                                                #
######################################################################
+###########################



open (OUTPUT, "> $file") 
    or die "Could not open file for writing: $!\n";


while ($i <= $days) {

    print OUTPUT "$weekdays[$weekday], $month $i, $year\n\n\n";

$i++;

push(@weekdays, shift(@weekdays));

}

close (OUTPUT);

sub MonthDays {                # This subroutine determines the natura
+l weekday names.

    my @monthDays= qw( 31 28 31 30 31 30 31 31 30 31 30 31 );
    my $month = shift(@_);
    my $year= @_ ? shift(@_) : 1900+(localtime())[5];
    if(  $year <= 1752  ) {

        # Note:  Although September 1752 only had 19 days,
        # they were numbered 1,2,14..30!

        return 19   if  1752 == $year  &&  9 == $month;

        return 29   if  2 == $month  &&  0 == $year % 4;
    } else {
        return 29   if  2 == $month  and
          0 == $year%4  &&  0 == $year%100  ||  0 == $year%400;
    }
    return $monthDays[$month-1];
}
Replies are listed 'Best First'.
(jeffa) Re: Plaintext monthly journal generator
by jeffa (Bishop) on Jul 20, 2003 at 15:04 UTC
    Two words (three?): use Time::Piece!
    use strict; use warnings; use Time::Piece; my $t = localtime; my @d = $t->day_list; printf "%s, %s %d, %d\n\n\n", $d[($_ + 1) % 7], $t->fullmonth, $_, $t->year for 1..$t->month_last_day ;
    Whoopsie Daisy! This only works for this month and this year ... see the modulus up there? That was suppose to be ($_ - 1) % 7 and i accidentally added one instead. That, of course, doesn't work, but my blunder managed to give "correct looking" results. Here is a better version whose output is identical to yours (the days of the names are not abbreviated):
    use Time::Piece; my $t = localtime; my $last = $t->month_last_day; $t -= Time::Piece::ONE_DAY * ($t->mday - 1); for (1..$last) { printf "%s, %s %d, %d\n\n\n", $t->fullday, $t->fullmonth, $t->mday, $t->year ; $t += Time::Piece::ONE_DAY; }
    [This still] doesn't save to a file, but redirection works just as well, IMHO. Hope this helps. :)

    jeffa

    L-LL-L--L-LL-L--L-LL-L--
    -R--R-RR-R--R-RR-R--R-RR
    B--B--B--B--B--B--B--B--
    H---H---H---H---H---H---
    (the triplet paradiddle with high-hat)
    
Re: Plaintext monthly journal generator
by daeve (Deacon) on Jul 20, 2003 at 18:07 UTC
    There is a extra space in the line:
    if (-e " journal.txt") { # Checks to see if journal.txt ex +ists.
    between the " and journal.txt.

    Other than that it works fine.

    HTH
    Daeve

      I really like this script. Its cool to see Perl used for different things like this. I think I might extend it into a diet planner.
        Glad you like it, thanks! I know it's nothing fancy, but it's definitely saved me some time and made my planning and note-taking easier.

        Take a look at Jeffa's suggestion - Time::Piece looks like it eliminates a lot of my script's complexity, and it'd probably be easier to extend and maintain as well.