In Python, using this function (takes Eastern Standard Time (EST) with am/pm, should output it in 3 time formats. Central Time (CT), Mountain Time(MT), and Pacific Time(PT) all in the correct am/pm):
def time_in_24h(time,time_day): #time is eastern time
''' (number, str)--> number
This function converts a 12-hour time, represented by am/pm,to its equivalent 24-hour time.
Returns time in the 24-hour format.
'''
cCentral = 'Central Time(CT)' #-1 hour offset
mMountain = 'Mountain Time(MT)'#-2 hours offset
pPacific = 'Pacific Time(PT)'#-3 hours offset
eEst = 'EST is'
if time_day!='pm' and time_day!='am':
print('Input is not in the right format') #this is where input is not in the right format
return 0
else:
print(time, time_day, eEst, time-1, cCentral)
print(time, time_day, eEst, time-2, mMountain)
print(time, time_day, eEst, time-3, pPacific)
Using this command:
time_in_24h(7,'am')
I get this output:
7 am EST is 6 Central Time(CT)
7 am EST is 5 Mountain Time(MT)
7 am EST is 4 Pacific Time(PT)
I am trying to output the correct 3 times based on the input of EST,am/pm to Central Time (CT), Mountain Time(MT), and Pacific Time(PT) all in the correct am/pm. How can I get the correct am/pm outputted based on the offsets? For example, 2pm EST input, should output:
1 pm EST is 12 pm Central Time(CT)
1 pm EST is 11 am Mountain Time(MT)
1 pm EST is 10 am Pacific Time(PT)
As you see, pm/am change based on the offsets and it is not consistent. What would be the best way to handle this as it varies based on the time (am/pm)? Anything built in python already to handle this without an issue? Any solution to my dilemma? I gave it my all and really stuck on this one.
strptime() function to convert the string to a datetime object, and then using the string method strftime() to output the time in 24-hour format. The format code for 24-hour time is %H:%M whereas the format for 12-hour time is %I:%M with %p appended if the time contains AM/PM.
struct_time object, then use library function time. strftime() to format this struct_time into a string of your desired 12-hour format. %I is a directive that tells Python to give the hour in the 12-hour format. Additionally, you may include the %p directive which will display “AM” or “PM”.
Converting Between TimezonesUse the datetime. astimezone() method to convert the datetime from one timezone to another. This method uses an instance of the datetime object and returns a new datetime of a given timezone.
Method 1: Program to convert string to DateTime using datetime. strptime() function. strptime() is available in DateTime and time modules and is used for Date-Time Conversion.
For Central, just check if the Eastern time is 12 pm. If it is, then adjust to 11 am. Similarly, if eastern is midnight, then adjust to (11) pm. It'll take a bit of if
s, but you could do it.
The problem is, it's still wrong. Date-time math is hard, and you've forgotten about DST.
Typically, once a year, it's 1 AM in Eastern time (EST), but also 1 AM in Central time (CDT). (Likewise, it's also once 3 AM in Eastern, and 1 AM in Central.)
You can't, with the amount of inputs your function currently takes, account for this: you need to know the full date and time. Once you do, it's easiest to just convert that full Eastern (America/New_York) date and time to UTC, and then convert that to Central (America/Chicago), Mountain (America/Denver) and Pacific (America/Los_Angeles).
The America/… bits are the names for the timezones that the TZ database on most machines uses. America/New_York is the "Eastern" time: it specifies when DST is, when it isn't, and what the offset from UTC is. It even has historical data, as the dates when DST starts & end have changed. (And on a global scale, actually change quite often. Governments…)
First, let's get two helper functions going: to_24hour
, which converts a (hour, ampm)
to a 24-hour format, and to_12hour
, which goes the other way. These will make things easier to think about, as we can do the subtractions a lot more easily in 24-hour time.
def to_24hour(hour, ampm):
"""Convert a 12-hour time and "am" or "pm" to a 24-hour value."""
if ampm == 'am':
return 0 if hour == 12 else hour
else:
return 12 if hour == 12 else hour + 12
def to_12hour(hour):
"""Convert a 24-hour clock value to a 12-hour one."""
if hour == 0:
return (12, 'am')
elif hour < 12:
return (hour, 'am')
elif hour == 12:
return (12, 'pm')
else:
return (hour - 12, 'pm')
Once we have those, things get simpler:
def time_in_24h(time,time_day): #time is eastern time
''' (number, str)--> number
This function converts a 12-hour time, represented by am/pm,to its equivalent 24-hour time.
Returns time in the 24-hour format.
'''
cCentral = 'Central Time(CT)' #-1 hour offset
mMountain = 'Mountain Time(MT)'#-2 hours offset
pPacific = 'Pacific Time(PT)'#-3 hours offset
eEst = 'EST is'
if time_day!='pm' and time_day!='am':
print('Input is not in the right format') #this is where input is not in the right format
return 0
else:
est_24hour = to_24hour(time, time_day)
hour, ampm = to_12hour((est_24hour - 1 + 24) % 24)
print(time, time_day, eEst, hour, ampm, cCentral)
hour, ampm = to_12hour((est_24hour - 2 + 24) % 24)
print(time, time_day, eEst, hour, ampm, mMountain)
hour, ampm = to_12hour((est_24hour - 3 + 24) % 24)
print(time, time_day, eEst, hour, ampm, pPacific)
… with those adjustments:
>>> time_in_24h(1, 'pm')
1 pm EST is 12 pm Central Time(CT)
1 pm EST is 11 am Mountain Time(MT)
1 pm EST is 10 am Pacific Time(PT)
One last note. Your docstring reads:
(number, str)--> number
This function converts a 12-hour time, represented by am/pm,to its equivalent 24-hour time.
Returns time in the 24-hour format.
This, of course, is what to_24hour
does.
Python doesn't really help with timezones; Justin Barber, in a separate answer, suggests pytz
; it's a good choice.
If we have some date or time that we know to be in Eastern:
now = datetime.datetime(2014, 3, 14, 12, 34)
Grab the timezones:
et = pytz.timezone('America/New_York')
ct = pytz.timezone('America/Chicago')
mt = pytz.timezone('America/Denver')
pt = pytz.timezone('America/Los_Angeles')
We can convert to Central and the others with:
now_et = et.normalize(et.localize(now))
now_ct = ct.normalize(now_et.astimezone(ct))
now_mt = mt.normalize(now_et.astimezone(mt))
now_pt = pt.normalize(now_et.astimezone(pt))
(As a comment notes, pytz
oddly requires a call to normalize
when a change might cross a DST boundary, which is basically anything you do.)
Then:
print('{} Eastern in various other timezones:'.format(now_et.strftime('%I %p')))
print('Central : {}'.format(now_ct.strftime('%I %p')))
print('Mountain: {}'.format(now_mt.strftime('%I %p')))
print('Pacific : {}'.format(now_pt.strftime('%I %p')))
If you are talking about timezones then you must specify a date (year, month, day) in addition to the time.
To convert given hours
and am_or_pm
to a different timezone:
time_in_24h
shouldn't try to do too much. Let it do what its name implies, namely: convert input hours, am or pm to 24 hours format:
def time_in_24h(hours, am_or_pm):
"""Convert to 24 hours."""
if not (1 <= hours <= 12):
raise ValueError("hours must be in 01,..,12 range, got %r" % (hours,))
hours %= 12 # accept 12am as 00, and 12pm as 12
am_or_pm = am_or_pm.lower()
if am_or_pm == 'am':
pass
elif am_or_pm == 'pm':
hours += 12
else:
raise ValueError("am_or_pm must be 'am' or 'pm', got: %r" % (am_or_pm,))
return hours
You could also implement it using strptime()
:
from datetime import datetime
def time_in_24h(hours, am_or_pm):
return datetime.strptime("%02d%s" % (hours, am_or_pm), '%I%p').hour
Then you could define print_times()
function that prints times in the 3 different timezones:
from datetime import datetime, time
import pytz
def astimezone(aware_dt, dest_tz):
"""Convert the time to `dest_tz` timezone"""
return dest_tz.normalize(aware_dt.astimezone(dest_tz))
def print_times(hours, am_or_pm, date=None, is_dst=None):
source_tz = pytz.timezone('US/Eastern')
# 2. add date
if date is None: # if date is not specified; use today
date = datetime.now(source_tz).date()
naive_dt = datetime.combine(date, time(time_in_24h(hours, am_or_pm), 0, 0))
# 3. create timezone-aware datetime object in the source timezone
source_dt = source_tz.localize(naive_dt, is_dst=is_dst)
#NOTE: these timezone names are deprecated,
# use Continent/City format instead
fmt = '%I %p %Z'
for tzname in 'US/Central', 'US/Mountain', 'US/Pacific':
dest_dt = astimezone(source_dt, pytz.timezone(tzname))
print("{source_dt:{fmt}} is {dest_dt:{fmt}} ({tzname})".format(
**locals()))
It is important to specify the date correctly, otherwise you won't know the correct UTC offset. The code uses pytz
module to access timezone information. strftime()
format codes are used for printing.
Example:
>>> print_times(7, 'am')
07 AM EDT is 06 AM CDT (US/Central)
07 AM EDT is 05 AM MDT (US/Mountain)
07 AM EDT is 04 AM PDT (US/Pacific)
>>> print_times(1, 'pm')
01 PM EDT is 12 PM CDT (US/Central)
01 PM EDT is 11 AM MDT (US/Mountain)
01 PM EDT is 10 AM PDT (US/Pacific)
>>> print_times(9, 'pm')
09 PM EDT is 08 PM CDT (US/Central)
09 PM EDT is 07 PM MDT (US/Mountain)
09 PM EDT is 06 PM PDT (US/Pacific)
Special note:
datetime.now(source_tz)
allows to get the correct current time in the given timezone. datetime.now()
would be incorrect here if the local timezone is not source_tz
is_dst=None
means that tz.localize()
method raises an exception for ambiguous or non-existing local times. Otherwise it just defaults to is_dst=False
that might not be what you wanttz.normalize()
might be necessary if the conversion happens across DST boundaryIf you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With