in reply to Perl calendar

It is certainly possible. But the mandatory question is: why do it w/o using existing modules?

The only thing to remember is that february has 29 days if and only if

$year%4==0 && ($year%100!=0 || $year%400==0)

I've seen too many broken implementation of leap years...

Update: expression corrected (Thanks, Moritz)

Careful with that hash Eugene.

Replies are listed 'Best First'.
Re^2: Perl calendar
by moritz (Cardinal) on Jun 23, 2008 at 13:36 UTC
    I've seen too many broken implementation of leap years...
    Me too. Speaking of which, what should !$year%4 && ($year%100 || $year%400) do? if a number is divisible by 400, it is always also divisible by 100. (Update: not sure if that sentence makes sense. Other way round: if it's not divisible by 400 it's also not divisible by 100. Does that make more sense?)

    My suggestion is not to re-invent the wheel, and work around the "no external module" limitation. I quite like Date::Simple module which does about everything you want for date processing (if you don't need times), and is very intuitive.

    I'd construct a leap year condition like that, but I might be wrong - which is why I used a module:

    my $is_leep = ($year % 400 == 0) || (($year % 4 == 0) && $year % 100 ! += 0))

      Agree, "use a module" is the default. But to keep it simple why not: ($year/4)!~/\.|[27]5$|50$/? :)

      Careful with that hash Eugene.

Re^2: Perl calendar
by Delusional (Beadle) on Jun 23, 2008 at 13:43 UTC
    Thanks for the input. The reason for no modules is, no modules other then what is currently installed in the default installation can be used, nor can any modules be installed (firewall and admin restrictions).

    Its one of the more cumbersome tasks I'm working on, and I need to overcome the lack of modules here using what's available. timelocal appears to provide the easiest way of doing this, and is part of the standard installation.

    I will take the leap year into account. Thanks for pointing that out!

    Can I assume timelocal will handle the leap year correctly here?
    my $_next_month = timelocal(0, 0, 0, 1, $_month % 12, $_next_year); my $_last_day = (localtime($_next_month - 86400))[3];
      The reason for no modules is, no modules other then what is currently installed in the default installation can be used, nor can any modules be installed (firewall and admin restrictions).

      I can't even count how many times I've seen this. Heck, I've even seen it at $work. Hasn't stopped me from using CPAN modules where they make sense. I first had to convince my manager that this was a good idea. That wasn't hard. "Free code." As in, hours or days or even weeks of work, already done, likely reasonably well tested (look - unit tests!), that I don't have to repeat. That can propel me a bunch of the way through my current task. Note: I had this conversation independently from any conversation on how to get around the restrictions. Merely that the restrictions were impeding my ability to be as productive as possible.

      Then I found two ways around the restrictions. One was technical, one was social. The social one was more difficult, and likely will be for you, too. In this case, I befriended someone on the team that controlled the global installations of perl, and had him install XML::Twig on all platforms. What I actually did here was trade him work. He was tasked with something that my team was in a better position to do, which would look good on my yearly review to own (so I wanted it anyway), but was going to be a royal PITA for him. I suggested that I'd do it if he installed XML::Twig everywhere. He jumped at the trade. (He then got a bit frustrated in getting expat installed everywhere, but didn't complain much.)

      The technical solution works for most modules, but I didn't use it for XML::Twig because of expat. For these, where a simple untar && perl Makefile.PL && make && make install would work (or the equivalent using Build.PL), I just simply check the tarballs into our source code repository. During our build process, I install them *to* the source tree (not globally - don't have write access there) using a simple algorithm which even works on Windows.

      At this point, the modules I need are built into my tree, and I can use them.

      Once I put this infrastructure in, it has been really cheap to get lots of work done: just add new CPAN modules.

      Update: roboticus likened this to an XY Problem (see wikipedia or even google). I kinda think of this more of having an articial limitation (box) placed on your work, and needing to think outside of that limitation to actually solve it. In an XY Problem, it seems (to me) to be the consensus that the petitioner does a partial solve on X, and asks about the partial solution Y. In this case, the limitation is given to the petitioner who is then tasked to work within these boundaries. The XY problem is not the one posed to PM ("How do I do this without external modules?"), but the limitation itself ("No external modules" when the real problem is likely more along the lines of "we don't want to muck about with our standard perl installs as that's going to make upgrading or porting to new machines or even platforms such a royal pain that we won't be able to afford the work.") Understanding your IT department's real concerns can help you make great strides in getting your own work done as cheaply as possible. If you're into Agile or related methodologies, consider your IT department as a stakeholder. That may make things much more obvious.

      Unix time does not count leap seconds. This article shows the discontinuity that occurs when a leap second is encountered: (Wikipedia entry for Unix time).
      Can I assume timelocal will handle the leap year correctly here?

      Yes.

      localtime and timelocal do deal correctly with leap years, but I don't know how it handles leap seconds. They might be a problem because they could make you leak into a different day than you might expect. (Don't know if that's a real problem, but it's one of the many problems i can think of).