Very Simple Conversion of Gregorian to Julian Calendar

by Aim9b (Monk)
 on Aug 22, 2007 at 11:52 UTC Need Help??
Aim9b has asked for the wisdom of the Perl Monks concerning the following question:

I need to convert the mm/dd ranges such as 0112 - 0402 into the filenames testnnn.txt where nnn = 012 for jan 12th, thru 092 for April 2nd, etc. Year is irrelevant, & leap year can be hard coded in the shortterm, since this will not be used past 2020. I've digressed to the following code, & it appears to work...
```sub conv2jul {
my \$moda=shift;
my @Days = (0,31,28,31,30,31,30,31,31,30,31,30,31);
if (\$leapyear) { \$Days [2] = 29; }
my \$jul = 0;  my \$i = 0;
my \$mo = substr(\$moda,0,2);
my \$da = substr(\$moda,2,2);
if ((\$mo <= 0) || (\$mo > 12)) { return "000"; }
if ((\$da <= 0) || (\$da > 31)) { return "000"; }
for (\$i = 0;\$i < \$mo;\$i++) { \$jul += \$Days[\$i]; }
\$jul += \$da;
return \$jul;
}
But I started with this & I'm curious as to why it doesn't work...
```sub conv2jul {
my \$moda=shift;
my @Days = (0,31,28,31,30,31,30,31,31,30,31,30,31);
if (\$leapyear) { \$Days [2] = 29; }
my \$jul = 0;  my \$i = 0;
my \$mo = substr(\$moda,0,2);
my \$da = substr(\$moda,2,2);
if ((\$mo <= 0) || (\$mo > 12)) { return "000"; }
if ((\$da <= 0) || (\$da > 31)) { return "000"; }
\$jul += (\$Days[\$mo..\$mo-1]) + \$da;     # his is the only diff
return \$jul;
}
I've tried several variation of this syntax, & I always get 0 returned in \$jul. Is the range op just not usable in this scenario? More likely I've just hosed it beyond belief ;-) If you can see what I'm trying to accomplish & can offer any enlightenment I'd be very thankful.

Replies are listed 'Best First'.
Re: Very Simple Conversion of Gregorian to Julian Calendar
by almut (Canon) on Aug 22, 2007 at 13:01 UTC

There are also a couple of modules out there on CPAN for this, for example Time::JulianDay. You could use it like this (which should also handle leap years correctly):

```use Time::JulianDay;

sub conv2jul {
my (\$moda, \$year) = @_;
my (\$mon, \$day) = unpack "A2A2", \$moda;
return julian_day(\$year, \$mon, \$day) - julian_day(\$year, 1, 0);
}

for my \$year qw(2000 2007) {
print "\$year:\n";
for my \$moda qw(0112 0402 1231) {
my \$jd = conv2jul(\$moda, \$year);
printf "  %s --> %03s\n", \$moda, \$jd;
}
}

would print:

```2000:          (leap year)
0112 --> 012
0402 --> 093
1231 --> 366
2007:
0112 --> 012
0402 --> 092
1231 --> 365
Re: Very Simple Conversion of Gregorian to Julian Calendar
by moritz (Cardinal) on Aug 22, 2007 at 12:15 UTC
What do you want to do here?

The idea is to add the number of days per month to \$jul - but what you are trying is neither a loop nor a sum, but some kind of array slice (that would be written as @Days[0 .. \$mo]).

Maybe you meant something like this:

```use List::Util qw(sum);
...
\$jul = sum(@Days[0..\$mo]) + \$da;

By the way please try to write in proper english words, we all try (and we're not all native speakers)

Re: Very Simple Conversion of Gregorian to Julian Calendar
by FunkyMonk (Canon) on Aug 22, 2007 at 12:47 UTC
You just can't do it - it doesn't make sense in Perl. The nearest thing to do what you intend (without using any modules) needs a loop:

```   my \$jul = \$da;
\$jul += \$_ for @Days[0..\$mo-1];

@ARRAY[LIST] is known as an array slice. It returns a list of elements of @ARRAY. You can also slice a hash. See Slices for the details.

Re: Very Simple Conversion of Gregorian to Julian Calendar
by Fletch (Chancellor) on Aug 22, 2007 at 12:59 UTC

The Julian day or Julian day number (JDN) is the integer number of days that have elapsed since the initial epoch defined as noon Universal Time (UT) Monday, January 1, 4713 BC in the proleptic Julian calendar.

(...)

The use of Julian date to refer to the day-of-year (ordinal date) is usually considered to be incorrect, however it is widely used that way in the earth sciences and computer programming.

Create A New User
Node Status?
node history
Node Type: perlquestion [id://634312]
Approved by Corion
Front-paged by Corion
help
Chatterbox?
 [Corion]: GrandFather: All's well that ends well? ;) [GrandFather]: I'm fighting with a third party device our software is to support. The documentation for the device's SDK is quite a lot less than average and most of today was spent ... [GrandFather]: discovering that one of the sensors for the device lies about the gain range it is using! [GrandFather]: However, by the end of the day I had discovered its deceptions and now have it working correctly, so yes, all's well that ends well. :-D [Corion]: GrandFather: Ah, (hardware) APIs - I have a similar situation with Chrome and its API... It is fairly underdocumented and I guess I have to hunt... [Corion]: ... down supposedly working code to find out what I'm supposed to do [GrandFather]: I haven't any "working code" to inspect! I have to find ways to generate reference signals then check the numbers I get at the far end match. [GrandFather]: That's ok when the signal is a voltage, but there are three axis accelerometers, gyroscopes and magnetometers in these things! A little invention is needed at times! [Corion]: GrandFather: Yeah, in that aspect, hardware is far more a black box than software

How do I use this? | Other CB clients
Other Users?
Others pondering the Monastery: (5)
As of 2017-08-24 07:08 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?
Who is your favorite scientist and why?

Results (365 votes). Check out past polls.

Notices?