perl script to generate a list of Julian day/day of year dates, given start and end.

I discovered myself on a unix system with a 'date' utility that only accepts the -u and + parameters, a fairly basic perl install, and lots of archives that are listed by the "Julian day" (day of year) date.

I put together a perl script using the functions I had at my disposal. The script below makes some allowance for a few different formats, but not nearly as much as Date::Manip would have given me. Feedback appreciated.

#!/usr/bin/perl
 
use Time::Local;
use Getopt::Long;
use strict;
 
 
 
sub getJJJFromParameter
{
	my $dateString = shift; 
	our $mm;
	our $dd;
	our $yyyy;
 
	if($dateString =~ m/d{1,2}/d{1,2}/d{2,4}/) {
		($mm, $dd, $yyyy) = split(///, $dateString);
	} elsif ($dateString =~ m/d{2,4}-d{1,2}-d{1,2}/) {
		($yyyy, $mm, $dd) = split(/-/, $dateString);
	} elsif ($dateString =~ m/d{1,2}-d{1,2}-d{2,4}/) {
		($mm, $dd, $yyyy) = split(/-/, $dateString);
	}
	$yyyy %= 100;
	$yyyy += 100;
 
	my @dt = localtime(timelocal(0,0,0,$dd,$mm-1,$yyyy));
 
	return($dt[7]+1);
}
 
# main script
 
my $startDate='';
my $endDate='';
my $startJJJ = 0;
my $endJJJ = 0;
 
GetOptions('start=s' => $startDate, 'end=s' => $endDate);
 
if ($startDate == '') {
	exit;	
} else {
	$startJJJ = getJJJFromParameter($startDate); 
}
if ($endDate != '') {
	$endJJJ = getJJJFromParameter($endDate); 
} else {
	$endJJJ = $startJJJ;
}
 
my $jjj;
 
printf "%03d to %03dn", $startJJJ, $endJJJ;
 
for ($jjj=$startJJJ; $jjj <= $endJJJ; $jjj++) {
	printf("%03d ", $jjj);
}

Date formatting for Single Unix Specification(R) versions of "date"

The date command is wonderful for formatting dates, as such

date --date="2010-01-01" +%Y%j

But what happens when you're on a system whose date command only supports the -u [UTC] and + [for formatting] options?

Below is a quick hack in straight C that provides the ability to format a date that you provide. This is ideal if your unix install of perl is very basic or non-existent, but you still have access to the C compiler.

Compiling the target would go as follows:

gcc strptime.c -o strptime

Running the output would be as follows:

./strptime "2010-01-01" "%Y%j"

strptime.c source code--Please note: there is limited error checking for the wrong arguments, etc., and overlapping a built-in name such as strptime() isn't the best of practices...

#include <time.h>
#include <stdio.h>
 
int main(int argc, char *argv[]) {
    struct tm tm;
    time_t t;
    char string[255];
 
    if(strptime(argv[1], "%Y-%m-%d", &tm) == NULL) {
        if (strptime(argv[1], "%m/%d/%Y", &tm) == NULL ) {
            fprintf(stderr, "format errorn");
            return 1;
        }
    }
    strftime(string, sizeof(string) - 1, argv[2], &tm);
    printf("%s",string);
    return 0;
}