12 hour clock and offset problem

Discussion in 'Perl Misc' started by Kenetic, Jun 16, 2007.

  1. Kenetic

    Kenetic Guest

    I'm trying to convert an input time to the offset time in a 12 hour
    clock system. It's giving me a headache. The am and pm must be the
    right ones when the offset is added to the input time ($temptime). I
    understand it's better to use a 24 hour clock, but unfortunately I
    can't in this situation. Everything needs to be done in 12-hour
    format.

    In short, 10:00 am with an offset of -3 should result in 1:00 pm;
    10:00 pm with an offset of -3 should result in 1:00 am.
    I've been at this for awhile, sadly, and cannot wrap my head around
    it. Any help to point me in the right direction would be fantastic.

    This is my latest version, which works to a certain extent--the
    difficulty is the AM/PM to switch.

    my $offset = -3;
    my $tempTime = "10:00 pm";
    sub myMod {
    my ( $a, $b ) = @_;
    my $div = $a / $b;
    return $a - int( $div ) * $b;
    }
    sub getutc {
    my $time = shift;
    my $GMTOffset = shift;
    $time =~ /(\d{1,2}):(\d\d)\s(.+)*/;
    # Is UTC a .5 remainder? if so, chop it off--we use
    # it later regardless
    my $hours = $1;
    if (myMod($hours,int($hours)) == -0.5) {
    $hours - 0.5;
    }
    my $minutes = $2;
    my $ampm = $3;
    #Take hours and subtract whole number in Offset Time
    $hours = $hours - int($GMTOffset);
    if ($hours >= 12) {
    $ampm = "pm";
    $hours = $hours - 12
    }
    # If 0.5 on the Offset, then add 30 minutes and wrap
    if (myMod($GMTOffset, int($GMTOffset)) == -0.5) {
    $minutes = $minutes + 30;
    if ($minutes >= 60) {
    $minutes = $minutes % 60;
    $hours = $hours + 1;
    }
    }
    $minutes = sprintf("%02d", $minutes);
    $hours = sprintf("%2d", $hours);
    if ($hours == 0) { $hours = "12";}
    return $hours.":".$minutes." ".$ampm;
    }

    my $theTime = getutc($tempTime, $offset);
    print "\nCurrent time: $tempTime\n";
    print "Adjust ".$offset." hours\n";
    print "Adjusted to: $theTime\n";
     
    Kenetic, Jun 16, 2007
    #1
    1. Advertising

  2. On Jun 16, 4:40 pm, Kenetic <> wrote:
    > I'm trying to convert an input time to the offset time in a 12 hour
    > clock system. It's giving me a headache. The am and pm must be the
    > right ones when the offset is added to the input time ($temptime). I
    > understand it's better to use a 24 hour clock, but unfortunately I
    > can't in this situation. Everything needs to be done in 12-hour
    > format.


    What makes you think that _everything_ needs to be done in 12-hour
    format?

    Maybe input and output needs to be in 12-hour format but I can see no
    reason why intermediate values should not be in, say, seconds or
    minutes since midnight.

    > In short, 10:00 am with an offset of -3 should result in 1:00 pm;
    > 10:00 pm with an offset of -3 should result in 1:00 am.
    > I've been at this for awhile, sadly, and cannot wrap my head around
    > it. Any help to point me in the right direction would be fantastic.
    >
    > This is my latest version, which works to a certain extent--the
    > difficulty is the AM/PM to switch.
    >
    > my $offset = -3;
    > my $tempTime = "10:00 pm";
    > sub myMod {
    > my ( $a, $b ) = @_;
    > my $div = $a / $b;
    > return $a - int( $div ) * $b;
    > }


    Perl has a mod operator.

    > sub getutc {
    > my $time = shift;
    > my $GMTOffset = shift;
    > $time =~ /(\d{1,2}):(\d\d)\s(.+)*/;


    You should always check the match succeeds before you use the result.
    At least say "or die".
    > # Is UTC a .5 remainder? if so, chop it off--we use
    > # it later regardless


    I don't get all that, I'll ignore it.

    > my $hours = $1;


    It's usually preferable you use the return value of the m// operator
    rather than $1 etc.

    > if (myMod($hours,int($hours)) == -0.5) {
    > $hours - 0.5;
    > }
    > my $minutes = $2;
    > my $ampm = $3;
    > #Take hours and subtract whole number in Offset Time
    > $hours = $hours - int($GMTOffset);
    > if ($hours >= 12) {
    > $ampm = "pm";
    > $hours = $hours - 12
    > }
    > # If 0.5 on the Offset, then add 30 minutes and wrap
    > if (myMod($GMTOffset, int($GMTOffset)) == -0.5) {
    > $minutes = $minutes + 30;
    > if ($minutes >= 60) {
    > $minutes = $minutes % 60;
    > $hours = $hours + 1;
    > }
    > }
    > $minutes = sprintf("%02d", $minutes);
    > $hours = sprintf("%2d", $hours);


    sprintf can format several arguments at once.

    > if ($hours == 0) { $hours = "12";}
    > return $hours.":".$minutes." ".$ampm;
    >
    > }
    >
    > my $theTime = getutc($tempTime, $offset);
    > print "\nCurrent time: $tempTime\n";
    > print "Adjust ".$offset." hours\n";
    > print "Adjusted to: $theTime\n";



    #!perl
    use strict;
    use warnings;

    my $offset = -3;
    my $tempTime = "10:00 pm";

    sub getutc {
    my $time = shift;
    my $GMTOffset = shift;
    my ($hours,$minutes,$ampm) =
    $time =~ /(\d{1,2}):(\d\d)\s*([ap]m)/ or die;
    $hours += 12 if $ampm eq 'pm';
    my $m = (($hours - $GMTOffset) * 60 + $minutes ) % ( 24 * 60 );
    return sprintf("%2d:%02d %s",
    int($m / 60 + 11 ) % 12 + 1,
    $m % 60,
    $m < 12 * 60 ? 'am' : 'pm');
    }

    my $theTime = getutc($tempTime, $offset);
    print "\nCurrent time: $tempTime\n";
    print "Adjust $offset hours\n";
    print "Adjusted to: $theTime\n";
    __END__
     
    Brian McCauley, Jun 16, 2007
    #2
    1. Advertising

  3. >>>>> "K" == Kenetic <> writes:

    K> I've been at this for awhile, sadly, and cannot wrap my head
    K> around it. Any help to point me in the right direction would be
    K> fantastic.

    You will drive yourself crazy trying to write your own date and time
    handling code, and even if you think you've gotten it right, there's a
    near certainty you'll find out after the fact you forgot about
    something. You're far better off using something like DateTime.pm.

    Charlton

    --
    Charlton Wilbur
     
    Charlton Wilbur, Jun 16, 2007
    #3
  4. Kenetic

    Paul Lalli Guest

    On Jun 16, 11:40 am, Kenetic <> wrote:
    > I'm trying to convert an input time to the offset time in a 12 hour
    > clock system. It's giving me a headache. The am and pm must be the
    > right ones when the offset is added to the input time ($temptime). I
    > understand it's better to use a 24 hour clock, but unfortunately I
    > can't in this situation. Everything needs to be done in 12-hour
    > format.
    >
    > In short, 10:00 am with an offset of -3 should result in 1:00 pm;
    > 10:00 pm with an offset of -3 should result in 1:00 am.
    > I've been at this for awhile, sadly, and cannot wrap my head around
    > it. Any help to point me in the right direction would be fantastic.


    Maybe I'm missing something about your requirements. If so, please
    correct me. But I'm not seeing why this is as complicated as you've
    made it. It's a fairly simple task for strftime:

    $ perl -MPOSIX=strftime -le'
    sub getutc {
    my ($time, $offset) = @_;
    my ($h, $m, $ap) = ($time =~ /^(\d+)\:(\d+)\s*([ap])m/i);
    $h += 12 if lc $ap eq "p";
    strftime("%I:%M %p", 0, $m, $h + $offset, 1, 0, 107);
    }

    print getutc("10:00 am", -3);
    print getutc("10:00 pm", -3);
    print getutc("12:00 pm", -3);
    print getutc("12:00 am", -3);
    print getutc("4:00am", -3);
    print getutc("4:00pm", -3);
    '
    07:00 AM
    07:00 PM
    09:00 PM
    09:00 AM
    01:00 AM
    01:00 PM

    Am I not understanding something?

    Paul Lalli
     
    Paul Lalli, Jun 16, 2007
    #4
  5. Kenetic wrote:
    > I'm trying to convert an input time to the offset time in a 12 hour
    > clock system. It's giving me a headache. The am and pm must be the
    > right ones when the offset is added to the input time ($temptime). I
    > understand it's better to use a 24 hour clock, but unfortunately I
    > can't in this situation. Everything needs to be done in 12-hour
    > format.
    >
    > In short, 10:00 am with an offset of -3 should result in 1:00 pm;
    > 10:00 pm with an offset of -3 should result in 1:00 am.
    > I've been at this for awhile, sadly, and cannot wrap my head around
    > it. Any help to point me in the right direction would be fantastic.


    $ perl -le'
    use POSIX q/strftime/;
    use Time::Local;

    my $offset = -3;
    my $tempTime = "10:00 pm";

    sub getutc {
    my ( $time, $GMTOffset ) = @_;
    my ( $hours, $minutes, $ampm ) = $time =~ /(\d\d?):(\d\d?)\s+([ap]m)*/i;
    $hours = "am" eq lc $ampm ? $hours : $hours == 12 ? 0 : $hours + 12;
    return strftime "%I:%M %P", gmtime timegm( 0, $minutes, $hours, 1, 1, 1 )
    + -$GMTOffset * 3600;
    }

    my $theTime = getutc( $tempTime, $offset );

    print "\nCurrent time: $tempTime\n",
    "Adjust $offset hours\n",
    "Adjusted to: $theTime\n";
    '

    Current time: 10:00 pm
    Adjust -3 hours
    Adjusted to: 01:00 am




    John
    --
    Perl isn't a toolbox, but a small machine shop where you
    can special-order certain sorts of tools at low cost and
    in short order. -- Larry Wall
     
    John W. Krahn, Jun 17, 2007
    #5
  6. Kenetic

    Paul Lalli Guest

    On Jun 16, 10:40 pm, Purl Gurl <> wrote:
    > Paul Lalli wrote:
    > > Kenetic wrote:

    >
    > (snipped a lot)
    >


    > >> In short, 10:00 am with an offset of -3 should result in 1:00 pm;



    > > Am I not understanding something?

    >
    > Input Time: 10:00 am
    >
    > Expected Results: 1:00 pm
    >
    > Printed Results: 07:00 AM


    Hrm. Right you are. I misread the OP's requirements. My mistake.
    Corrected subroutine:

    sub getutc {
    my ($time, $offset) = @_;
    my ($h, $m, $ap) = ($time =~ /^(\d+)\:(\d+)\s*([ap])m/i);
    $h += 12 if lc $ap eq "p";
    strftime("%I:%M %p", 0, $m, $h - $offset, 1, 0, 107);
    }

    Thanks for the correction,
    Paul Lalli
     
    Paul Lalli, Jun 17, 2007
    #6
  7. Kenetic

    Kenetic Guest

    On Jun 16, 9:40 pm, Purl Gurl <> wrote:

    >
    > Let me know if you find any glitches.
    >
    > --
    > Purl Gurl
    > --


    It looks like it works particularly with 12 am and 12 pm, and since
    you have a handle on the script (there are some things in here I
    haven't used extensively--just a novice at perl), I wonder if you can
    modify it to include, .5 of an hour. The offset can be -3 or -3.5 for
    3 hours and 30 minutes. Also to be considered is how :30 past the hour
    would then wrap around to the next hour, which is easy enough
    (although when wrapping past 12 am or pm might pose a challenge)

    Thanks for all the help so far, it's been overwhelming.

    Cheers,
     
    Kenetic, Jun 17, 2007
    #7
  8. Kenetic

    Mumia W. Guest

    On 06/17/2007 02:48 AM, Kenetic wrote:
    >
    > It looks like it works particularly with 12 am and 12 pm, and since
    > you have a handle on the script (there are some things in here I
    > haven't used extensively--just a novice at perl), I wonder if you can
    > modify it to include, .5 of an hour. [...]


    As the others have said, use already-made modules for this sort of
    thing. The module writers have already worked out most of the complexities.

    Is something like this what you're trying to do?

    require Date::parse;
    require POSIX;
    Date::parse->import(qw/str2time/);
    POSIX->import(qw/strftime mktime/);

    local $\ = "\n";
    my $offset = -3;
    my $data = 'June 10, 2007 10:00am';
    my $timeval = str2time($data)-($offset*3600);
    print strftime('%F %r',localtime $timeval);

    On my system (Perl 5.8.4, Linux), this prints "2007-06-10 01:00:00 PM"

    Date::parse is a very useful CPAN module, and POSIX is part of Perl.
     
    Mumia W., Jun 17, 2007
    #8
  9. Kenetic

    Kenetic Guest

    On Jun 16, 9:19 am, Brian McCauley <> wrote:
    > On Jun 16, 4:40 pm, Kenetic <> wrote:
    >
    > > I'm trying to convert an input time to the offset time in a 12 hour
    > > clock system. It's giving me a headache. The am and pm must be the
    > > right ones when the offset is added to the input time ($temptime). I
    > > understand it's better to use a 24 hour clock, but unfortunately I
    > > can't in this situation. Everything needs to be done in 12-hour
    > > format.

    >
    > What makes you think that _everything_ needs to be done in 12-hour
    > format?
    >
    > Maybe input and output needs to be in 12-hour format but I can see no
    > reason why intermediate values should not be in, say, seconds or
    > minutes since midnight.
    >
    > > In short, 10:00 am with an offset of -3 should result in 1:00 pm;
    > > 10:00 pm with an offset of -3 should result in 1:00 am.
    > > I've been at this for awhile, sadly, and cannot wrap my head around
    > > it. Any help to point me in the right direction would be fantastic.

    >
    > > This is my latest version, which works to a certain extent--the
    > > difficulty is the AM/PM to switch.

    >
    > > my $offset = -3;
    > > my $tempTime = "10:00 pm";
    > > sub myMod {
    > > my ( $a, $b ) = @_;
    > > my $div = $a / $b;
    > > return $a - int( $div ) * $b;
    > > }

    >
    > Perl has a mod operator.
    >
    > > sub getutc {
    > > my $time = shift;
    > > my $GMTOffset = shift;
    > > $time =~ /(\d{1,2}):(\d\d)\s(.+)*/;

    >
    > You should always check the match succeeds before you use the result.
    > At least say "or die".
    >
    > > # Is UTC a .5 remainder? if so, chop it off--we use
    > > # it later regardless

    >
    > I don't get all that, I'll ignore it.
    >
    > > my $hours = $1;

    >
    > It's usually preferable you use the return value of the m// operator
    > rather than $1 etc.
    >
    >
    >
    > > if (myMod($hours,int($hours)) == -0.5) {
    > > $hours - 0.5;
    > > }
    > > my $minutes = $2;
    > > my $ampm = $3;
    > > #Take hours and subtract whole number in Offset Time
    > > $hours = $hours - int($GMTOffset);
    > > if ($hours >= 12) {
    > > $ampm = "pm";
    > > $hours = $hours - 12
    > > }
    > > # If 0.5 on the Offset, then add 30 minutes and wrap
    > > if (myMod($GMTOffset, int($GMTOffset)) == -0.5) {
    > > $minutes = $minutes + 30;
    > > if ($minutes >= 60) {
    > > $minutes = $minutes % 60;
    > > $hours = $hours + 1;
    > > }
    > > }
    > > $minutes = sprintf("%02d", $minutes);
    > > $hours = sprintf("%2d", $hours);

    >
    > sprintf can format several arguments at once.
    >
    > > if ($hours == 0) { $hours = "12";}
    > > return $hours.":".$minutes." ".$ampm;

    >
    > > }

    >
    > > my $theTime = getutc($tempTime, $offset);
    > > print "\nCurrent time: $tempTime\n";
    > > print "Adjust ".$offset." hours\n";
    > > print "Adjusted to: $theTime\n";

    >
    > #!perl
    > use strict;
    > use warnings;
    >
    > my $offset = -3;
    > my $tempTime = "10:00 pm";
    >
    > sub getutc {
    > my $time = shift;
    > my $GMTOffset = shift;
    > my ($hours,$minutes,$ampm) =
    > $time =~ /(\d{1,2}):(\d\d)\s*([ap]m)/ or die;
    > $hours += 12 if $ampm eq 'pm';
    > my $m = (($hours - $GMTOffset) * 60 + $minutes ) % ( 24 * 60 );
    > return sprintf("%2d:%02d %s",
    > int($m / 60 + 11 ) % 12 + 1,
    > $m % 60,
    > $m < 12 * 60 ? 'am' : 'pm');
    >
    > }
    >
    > my $theTime = getutc($tempTime, $offset);
    > print "\nCurrent time: $tempTime\n";
    > print "Adjust $offset hours\n";
    > print "Adjusted to: $theTime\n";
    > __END__


    Brian, the reason why I need to use a sub for mod is that perl's mod
    doesn't work very well with fractions. I picked this snippet up from
    perlmonks, if you compare '3.5 % 3' and myMod(3.5, 3), the former will
    result in 0, the latter is 0.5. Thank you for your tips about the
    matching and strftime, those are quite valuable during this journey
    through perl. It's also true that the format can take on whatever form
    in the intermediary, however raw input and eventual output are in 12-
    hour format. I've built a similar time conversion in excel using
    minutes so I understand what your saying.

    Other then that, I think your scripts works to the extent that 12 pm
    and 12 am don't work properly.

    Cheers,
     
    Kenetic, Jun 17, 2007
    #9
  10. Kenetic

    Kenetic Guest

    On Jun 17, 1:47 am, "Mumia W." <paduille.4061.mumia.w
    > wrote:

    >
    > As the others have said, use already-made modules for this sort of
    > thing. The module writers have already worked out most of the complexities.
    >


    I'll most likely be unable to use any external modules. One of the
    constraints I have unfortunately.

    I've almost got the minutes to work, but I'm missing am or pm, so I
    can't test it that well. Just getting the hang of substr and index, I
    suppose. Looks promising though.

    Cheers,
     
    Kenetic, Jun 17, 2007
    #10
  11. Kenetic

    Kenetic Guest

    Sounds good. I am definitely learning more then I bargained for as I
    didn't expect such a in-depth response. Of course, time is a rather
    complex thing. I'm certainly interested in learning this rather then
    just copy and paste and have it work--my first perl script was a lot
    of fun to put together and it didn't dawn on me to seek out a group
    like this one. In fact, I enjoy doing the research and teaching
    myself. The reason I was wondering if you could handle minutes was
    under the assumption others knew it was part of the original problem.
    I didn't make that clear enough in my comments.

    Anyway, I think I should have more then enough information, as you
    mentioned, to complete this even if it takes a little while longer.
    Would love to have the satisfaction of finally seeing the results I
    want.

    Thanks again,
     
    Kenetic, Jun 17, 2007
    #11
  12. >>>>> "Purl" == Purl Gurl <> writes:

    Purl> You are, again, running into convention problems. Convention is to
    Purl> adjust time by hours, only, to determine a local time.

    Almost correct. There are, in fact, timezones that vary by non-whole hours,
    and places that use mean solar time instead.

    Take a glance at <http://en.wikipedia.org/wiki/Time_zone>, noting the time
    zones for such places as India, Burma, and the center of Australia.

    --
    Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
    <> <URL:http://www.stonehenge.com/merlyn/>
    Perl/Unix/security consulting, Technical writing, Comedy, etc. etc.
    See PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!

    --
    Posted via a free Usenet account from http://www.teranews.com
     
    Randal L. Schwartz, Jun 17, 2007
    #12
  13. >>>>> "Purl" == Purl Gurl <> writes:

    Purl> Larry Wall, Randal Schwartz, Joseph Hall, Brigitte Jellinek and others
    Purl> like them, did not become masters of Perl through using modules.

    That statement is incorrect. Please don't speak for me like that.

    A large part of being a master is knowing the tool thoroughly. For Perl, part
    of the "tool" is in fact the CPAN. Knowing what modules exist, and how to use
    them, is part of the proper mastery of Perl.

    --
    Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
    <> <URL:http://www.stonehenge.com/merlyn/>
    Perl/Unix/security consulting, Technical writing, Comedy, etc. etc.
    See PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!

    --
    Posted via a free Usenet account from http://www.teranews.com
     
    Randal L. Schwartz, Jun 17, 2007
    #13
  14. Kenetic wrote:
    > On Jun 17, 1:47 am, "Mumia W." <paduille.4061.mumia.w
    >> As the others have said, use already-made modules for this sort of
    >> thing. The module writers have already worked out most of the
    >> complexities.

    >
    > I'll most likely be unable to use any external modules. One of the
    > constraints I have unfortunately.


    Then good luck in dealing with the added/missing hour during the switch
    to/from daylight saving time, of course adjusted to the proper locale.

    jue
     
    Jürgen Exner, Jun 17, 2007
    #14
  15. Kenetic

    Dr.Ruud Guest

    Kenetic schreef:

    > perl's mod doesn't work very well with fractions


    <quote src="perlop">
    Binary "%" computes the modulus of two numbers. Given
    integer operands $a and $b: If $b is positive, then "$a %
    $b" is $a minus the largest multiple of $b that is not
    greater than $a. If $b is negative, then "$a % $b" is $a
    minus the smallest multiple of $b that is not less than $a
    (i.e. the result will be less than or equal to zero).
    Note that when "use integer" is in scope, "%" gives you
    direct access to the modulus operator as implemented by
    your C compiler. This operator is not as well defined for
    negative operands, but it will execute faster.
    </quote>

    Nothing is mentioned there about fractional behaviour. But I was never
    surprised because *in my world*, "modulus" operates on integers. So
    AFAIK, Perl's mod works perfectly with fractions.

    --
    Affijn, Ruud

    "Gewoon is een tijger."
     
    Dr.Ruud, Jun 17, 2007
    #15
  16. Le Sun, 17 Jun 2007 07:52:20 -0700, Purl Gurl a écrit :

    >
    > Do you want to be known as a Perl Programmer or a Copy And Paste Baby?


    This is preposterous. Just like saying "if you want to be a real C
    programmer, don't use any existing library, not even libc".

    To deserve the title of "programmer", you have to get the job
    done, writing software that actually works. reinventing the wheel isn't
    the right way to get things done...

    --
    A thing of beauty is a joy forever.
    J. Keats.

    Ah! Singe débotté, hisse un jouet fort et vert!
    Marcel Bénabou.
     
    Emmanuel Florac, Jun 17, 2007
    #16
  17. >>>>> "Purl" == Purl Gurl <> writes:

    Purl> I know about a cello. I am a professional cellist. I can make my cello
    Purl> weep, scream, cry, laugh and sing in voice which will bring you tears
    Purl> to your eyes.

    Purl> I sure as heck do not know how to build a cello.

    Purl> Should I snap my chubby fingers and magically make all Perl modules
    Purl> and all knowledge of Perl modules vanish, almost all Perl "programmers"
    Purl> would no longer be able to program in Perl.

    Your analogy is flawed, and in fact demonstrates precisely the opposite of
    what you intended.

    Since you don't know how to build a cello, if somone were to provide you with
    blocks of wood, some metal, and even plans for building a cello, you would
    not, in any reasonable amount of time, be playing cello music.

    Perl modules would be akin to having one box with the cello, another box with
    the strings, and a third box with the bow, and all you have to do is snap them
    together, and there's your music.

    So, without modules would be like having raw wood. *With* modules, you're
    making music.

    --
    Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
    <> <URL:http://www.stonehenge.com/merlyn/>
    Perl/Unix/security consulting, Technical writing, Comedy, etc. etc.
    See PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!

    --
    Posted via a free Usenet account from http://www.teranews.com
     
    Randal L. Schwartz, Jun 17, 2007
    #17
  18. Le Sun, 17 Jun 2007 10:45:17 -0700, Purl Gurl a écrit :

    >
    > Ha! Ha! Your lame claim about reinventing the wheel is a flat tire.


    Purl Gurl, you're wonderful, but nonetheless wrong about CPAN and
    modules :)

    --
    Le commissaire : Comment vous appelez-vous?
    Garance : Moi je ne m'appelle jamais, je suis toujours là. J'ai pas
    besoin de m'appeler. Mais les autres m'appellent Garance, si ça peut
    vous intéresser.
    Prévert,"les enfants du Paradis".
     
    Emmanuel Florac, Jun 17, 2007
    #18
  19. On Jun 17, 12:05 pm, Kenetic <> wrote:
    > On Jun 16, 9:19 am, Brian McCauley <> wrote:
    >
    > > Perl has a mod operator.


    > Brian, the reason why I need to use a sub for mod is that perl's mod
    > doesn't work very well with fractions. I picked this snippet up from
    > perlmonks, if you compare '3.5 % 3' and myMod(3.5, 3), the former will
    > result in 0, the latter is 0.5.


    When dealing with time, currency, or anything like that never work
    with fractions if you can avoid it. Always convert to a unit that will
    keep all your numbers integer (cents, seconds, whatever).

    > > sub getutc {
    > > my $time = shift;
    > > my $GMTOffset = shift;
    > > my ($hours,$minutes,$ampm) =
    > > $time =~ /(\d{1,2}):(\d\d)\s*([ap]m)/ or die;
    > > $hours += 12 if $ampm eq 'pm';
    > > my $m = (($hours - $GMTOffset) * 60 + $minutes ) % ( 24 * 60 );
    > > return sprintf("%2d:%02d %s",
    > > int($m / 60 + 11 ) % 12 + 1,
    > > $m % 60,
    > > $m < 12 * 60 ? 'am' : 'pm');


    > Other then that, I think your scripts works to the extent that 12 pm
    > and 12 am don't work properly.


    Sorry, yes.

    $hours += 12 if $ampm eq 'pm';

    Should, of course, read:

    $hours += 12 if $ampm eq 'pm' xor $hours eq '12';
     
    Brian McCauley, Jun 18, 2007
    #19
  20. Kenetic

    -berlin.de Guest

    Dr.Ruud <> wrote in comp.lang.perl.misc:
    > Kenetic schreef:
    >
    > > perl's mod doesn't work very well with fractions


    [...]

    > Nothing is mentioned there about fractional behaviour. But I was never
    > surprised because *in my world*, "modulus" operates on integers. ...


    That's customary, but it's an unnecessary restriction. The "x mod y"
    operation can be consistently defined for all real x and y through

    x mod y = x - y*floor(x/y) (y != 0)
    y mod 0 = x

    (Yes, a zero "denominator" is admissible.) Cf. Knuth, _TAOCP_, 1.2.4
    (Vol 1).

    Anno
     
    -berlin.de, Jun 18, 2007
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Lance Riedel

    Translated Offset to Source Offset

    Lance Riedel, Oct 14, 2003, in forum: XML
    Replies:
    2
    Views:
    502
    Patrick TJ McPhee
    Oct 15, 2003
  2. Replies:
    2
    Views:
    882
    Hal Rosser
    Jun 1, 2007
  3. ssylee
    Replies:
    4
    Views:
    518
    Thad Smith
    Jan 1, 2008
  4. Chris Gunnels
    Replies:
    4
    Views:
    162
    Robert Klemme
    Sep 16, 2010
  5. Roy Smith
    Replies:
    4
    Views:
    276
    Roy Smith
    Jan 27, 2013
Loading...

Share This Page