Welcome to the Monastery PerlMonks

### Converting 24 hour time back into 12 hour

 on Nov 07, 2004 at 00:17 UTC Need Help??
Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

```      my (\$sec,\$min,\$hour,\$mday,\$mon,\$year,\$wday,\$yday,\$isdst) =
localtime(time);
makes the hour (right now in the Midwest) 18. How can I convert this back into real 12 hour time so it reads 6?

Replies are listed 'Best First'.
Re: Converting 24 hour time back into 12 hour
by atcroft (Abbot) on Nov 07, 2004 at 00:23 UTC

Try inserting this after that line: \$hour = (\$hour > 12 ? \$hour % 12 : \$hour);

Hope that helps.

(By the way, 24-hour time is just as valid as 12-hour time, and simpler, lacking the added complication of having to specify AM/PM. ;)

Re: Converting 24 hour time back into 12 hour
by Fletch (Chancellor) on Nov 07, 2004 at 02:19 UTC

See also perldoc POSIX and man 3 strftime, specifically the %I formatter.

Here is a working example of the strftime method mentioned
```use POSIX;
use POSIX qw(strftime);

my (\$sec, \$min, \$hour, \$mday, \$mon, \$year, \$wday, \$yday, \$isdst ) = lo
+caltime(time);
print print POSIX::strftime('%I:%M:%S %p - %a, %B %d, %Y',\$sec, \$min,
+\$hour, \$wday, \$mon, \$year, \$mday);

# 10:12:47 AM Mon, August 01, 2016

Thanks for this illustration. I have some small suggestions, however.

• There is no need to "use" a module multiple times within the same scope.
• When you have imported a symbol into the current namespace there is no need to use the package name to refer to it.
• There is no need to declare variables which are not used (\$wday, \$yday, \$isdst). If the others aren't used beyond the print statement, we don't need those either.
• print print is rather pointless since the first print just outputs the return value of the second.

Cleaning this up gives us:

```use POSIX 'strftime';

print strftime ('%I:%M:%S %p - %a, %B %d, %Y', localtime (time)) . "\n
+";

I prefer the brevity of this and think it aids clarity. However, here's the same but with 2 named variables just for completeness:

```use POSIX 'strftime';

my \$format = '%I:%M:%S %p - %a, %B %d, %Y' . "\n";
my @time   = localtime (time);
print strftime (\$format, @time);
Re: Converting 24 hour time back into 12 hour
by theorbtwo (Prior) on Nov 07, 2004 at 09:40 UTC

I looked through this thread, and was amazed that nobody implemented a correct, lossless implementation. Generally, when you write a 12-hour time, you should include "AM" or "PM", because otherwise you loose information. Thus, I'm adding my solution:

```sub to12h {
local \$_=shift;
return (12, "PM") if \$_==0;
return (\$_, "AM") if \$_<=12;
return (\$_-12, "PM")
}

for (0..23) {
print join " ", to12h(\$_), "\n";
}

Of course, if you /want/ to loose information, just use the first element of the return value.

Warning: Unless otherwise stated, code is untested. Do not use without understanding. Code is posted in the hopes it is useful, but without warranty. All copyrights are relinquished into the public domain unless otherwise stated. I am not an angel. I am capable of error, and err on a fairly regular basis. If I made a mistake, please let me know (such as by replying to this node).

hi,

slight correction:

```sub to12h {
local \$_=shift;

if ((\$_ < 0) || (\$_ > 23)) {
return ("\$_ is not a valid hour");
}

return (\$_, "AM") if \$_ < 12;
return (\$_, "PM") if \$_ == 12;
return (\$_ -12, "PM")
}

for (0..23) {
print join " ", to12h(\$_), "\n";
}

Jason L. Froebe

Team Sybase member

No one has seen what you have seen, and until that happens, we're all going to think that you're nuts. - Jack O'Neil, Stargate SG-1

Thanks.
one more correction - you have forgot to convert 24hr's 00 hours to 12AM
```sub to12h {
local \$_=shift;

if ((\$_ < 0) || (\$_ > 23)) {
return ("\$_ is not a valid hour");
}

return (12, "AM") if \$_ == 0;
return (\$_, "AM") if \$_ < 12;
return (\$_, "PM") if \$_ == 12;
return (\$_ -12, "PM");
}

for (0..23) {
print join " ", to12h(\$_), "\n";
}
Re: Converting 24 hour time back into 12 hour
by Arunbear (Prior) on Nov 07, 2004 at 00:31 UTC
```if(\$hour == 0)    { \$hour = 12 }
elsif(\$hour > 12) { \$hour -= 12 }
Or just on one line;
\$hour = (\$hour + 11) % 12 + 1;
Re: Converting 24 hour time back into 12 hour
by ercparker (Hermit) on Nov 07, 2004 at 07:56 UTC
You can also try this:
```\$hour -= 12 unless \$hour < 13;
Re: Converting 24 hour time back into 12 hour
by Kanji (Parson) on Nov 07, 2004 at 01:20 UTC
\$hour %= 12

--k.

To fix it for zero, at 0 and 12 hours:
```(\$hour %= 12) ||= 12;

The problem with your solution is that, now 12:00 (lunch time) becomes 0:00 ;-) If you read other answers carefully, you will fnd that they made effort to avoid this.

Re: Converting 24 hour time back into 12 hour
by TedPride (Priest) on Nov 08, 2004 at 05:24 UTC
```my (\$sec,\$min,\$hour,\$mday,\$mon,\$year,\$wday,\$yday,\$isdst) = localtime(t
+ime);
my \$shour = (\$hour > 11 ? \$hour - 12 : \$hour);
\$shour = 12 if ! \$shour; # if 0 should be 12
No point doing extra work computing AM/PM if you don't need them, and if you do, it's easy to determine AM/PM by comparing \$hour and \$shour. Or if all you want is the hour and you don't care about the rest at all:
```my \$hour = int (time / 3600) % 12;
\$hour = 12 if ! \$hour; # if 0 should be 12

Create A New User
Node Status?
node history
Node Type: perlquestion [id://405825]
Approved by atcroft
help
Chatterbox?
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others romping around the Monastery: (4)
As of 2018-05-21 22:58 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?
World peace can best be achieved by:

Results (163 votes). Check out past polls.

Notices?