ctp has asked for the wisdom of the Perl Monks concerning the following question:

With the other homework queries I have recently posted I was at least able to write much of my own code, and then ask everyone for clues to bring me along, but the current problem has me completely flummoxed. Maybe I shouldn't work on this stuff at midnight...I have been pondering on this for a few days now though.

I will present the problem, but first I want to say that what I am looking for here is procedural/flowcharty kind of help...no code yet, as I need to start the dang thing on my own. Just some possible unflummoxment if you please.

I need to write a script which will convert dates. I can do that already...date format a in, date format b out. Where this assignment leaves me behind is in the fact that it needs to be able to read date formats as follows - Apr 8 1984, Apr 08 84, 4/8/84, 04/08/84, and 08 Apr 1984. The output then needs to be of one format.

It will read in the various format dates, but then it needs to be able to parse each piece of the different style dates and understand which piece is which in order to relate them to the output format.

One thought I had early on was to ask the user to select which format they are going to input, take their date, and then take care of it with one of a set of subroutines. Gets the job done, but kinda feels like a copout...of course trying to do it any other way may be well beyond my current Perl abilities.

Anyhow - I humbly seek some input, and suggestions...but no code (yet) please. Thanks!

Replies are listed 'Best First'.
Re: More date conversion happiness
by davido (Cardinal) on Jan 09, 2004 at 08:39 UTC
    Do you get extra credit for using CPAN? ;)

    Date::Manip is able to parse a wide variety of date formats automatically. There's half the assignment, already done.

    I can't remember if Date::Manip is a core module or not. If not, you can download it from CPAN, or if you're an ActiveState user, just pull it in with PPM.

    From the Date Manip POD:

    In the documentation below, US formats are used, but in most (if not all) cases, a non-English equivalent will work equally well.

    1. Parsing a date from any convenient format

    $date = ParseDate("today"); $date = ParseDate("1st thursday in June 1992"); $date = ParseDate("05/10/93"); $date = ParseDate("12:30 Dec 12th 1880"); $date = ParseDate("8:00pm december tenth"); if (! $date) { # Error in the date }

    Even if you're not allowed to use the Date::Manip module, at least look at its source code so you can see how it does all those neat tricks!


    Dave

      I wish I was allowed to use it...although the assignment doesn't explicitly say I can't...Hmmmmm.

      I surfed over there earlier today, and looked at the source. Sadly my brain still hurts from that - it was kinda like not closing my eyes while opening the ark, ya know? ;-)
Re: More date conversion happiness
by BigLug (Chaplain) on Jan 09, 2004 at 11:15 UTC

    I provide this because, quite simply, I'm sure you'd not be allowed to use it! However it's really the easiest solution to the problem:

    package DateTime::Format::Homework; use DateTime::Format::Builder ( parsers => { parse_datetime => [ {strptime => '%b %d %Y'}, # Apr 8 1984 {strptime => '%b %d %y'}, # Apr 08 84 {strptime => '%m/%d/%y'}, # 4/8/84 and 04/08/84 {strptime => '%d %b %Y'}, # 08 Apr 1984 ], } );

    And that's it, you have a parser that will handle all your teacher's dates without you needing to tell the script which kind of date you have. Of course, you can keep on adding strptime parsers until the cows come home and it will still work.*

    Now here's how to use it:

    use DateTime::Format::Homework; foreach ('Apr 8 1984', 'Apr 08 84', '4/8/84', '04/08/84', '08 Apr 1984 +') { print DateTime::Format::Homework->parse_datetime( $_ )->ymd . "\n" +; }
    Returns (tested):
    1984-04-08 1984-04-08 1984-04-08 1984-04-08 1984-04-08
    *Note that this isn't exactly true because both %m-%d-%y and %d-%m-%y would work for 03-03-84. The cows came home.
Re: More date conversion happiness
by Hofmator (Curate) on Jan 09, 2004 at 11:36 UTC
    to read date formats as follows - Apr 8 1984, Apr 08 84, 4/8/84, 04/08/84, and 08 Apr 1984
    • Take a close look at these date formats, what are the differences and what is similar? Each date format consists of three parts, separated either by space or by '/'. Take a look at split.
    • The year is always the last field, so that's easy. Just make sure that you add 1900 to it whenever it's necessary.
    • The month comes either as an abbreviation containing letters or as a number. Check which is true and act accordingly. For the mapping from 'Apr' to 4, a hash is ideal. For the output in a different format you probably need the reverse mapping.
    • Write one subroutine for reading in the date and return it in a standard format, e.g. three numbers for year (4 digit), month and day. Maybe add some date validation for extra credits :).
    • Then write conversions from this 'standard' format into all necessary output formats. See sprintf.
    • At last, when you are finished or get stuck, let us know what you have, I'm sure we can give a few more valulabe tips.

    -- Hofmator

      Many thanks to all. I'll start hacking on some code tonight and post it if I get stuck...or post it if I get it right on my own. (as if! :-)

      Again, thanks!
Re: More date conversion happiness
by Aragorn (Curate) on Jan 09, 2004 at 08:57 UTC
    You could use a list of regular expressions each of which match a possible input format, and use the results of that for outputting the desired format.

    As this is homework, I'm hesitant to provide (pseudo) code. ;-) There are a number of ways to go about this, like using a big if/elsif block to match the right format. Also, you probably need some sort of lookup table for the months.

    Arjen

Re: More date conversion happiness
by Hena (Friar) on Jan 09, 2004 at 08:59 UTC
    Well, couple of things to give some idea.
    1. Pattern matching.
    2. Sprintf.
    3. Hash.

    Code and how to use them, thats your job now :).
      LOL...all that, huh? (not to forget the shebang) You make it sound so easy! ;-) thanks :)
Re: More date conversion happiness
by Taulmarill (Deacon) on Jan 09, 2004 at 09:17 UTC
    hm, do you know regular expressions? if not, try to recognize the format.
    you could find out if the date has /īs or not and then split by "/" or " ". now it should be easy to recognize what type of data is in each field and do some stuff whith it.
Re: More date conversion happiness
by mkirank (Chaplain) on Jan 09, 2004 at 09:42 UTC
    pass the arguments to a function
    foodate(date,mon,year)
    then use regexp and other validations (dont forget leap year ;-) to validate date
    convert it to the format u require
    hope this helps ;-)