在Python中,使用这个函数(接受东部标准时间(EST)和am/pm),应该以3种时间格式输出。中部时间(CT),山地时间(MT)和太平洋时间(PT)都在正确的上午/下午):
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)
使用命令:
time_in_24h(7,'am')
我得到这样的输出:
7 am EST is 6 Central Time(CT)
7 am EST is 5 Mountain Time(MT)
7 am EST is 4 Pacific Time(PT)
我正在尝试根据EST,am/pm到中央时间(CT),山地时间(MT)和太平洋时间(PT)的输入,在正确的am/pm中输出正确的3次。如何根据偏移量得到正确的am/pm输出?例如,EST下午2点输入,应该输出:
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)
如您所见,pm/am根据偏移量变化,它是不一致的。什么是最好的方法来处理这个,因为它是根据时间(上午/下午)而变化的?任何内置在python已经处理这个没有问题吗?有办法解决我的困境吗?
如果是中环,只需查看东部时间是否为中午12点。如果是,那就调整到上午11点。同样,如果东部时间是午夜,那么调整到晚上11点。这需要一些if
s,但你可以做到。
问题是它仍然是错误的。日期时间计算太难了,你忘了夏时制。
通常,每年一次,是东部时间(EST)的凌晨1点,但也是中部时间(CDT)的凌晨1点。(同样,东部也有一次是凌晨3点,中部是凌晨1点。)
你不能,用你的函数当前的输入量,考虑到这一点:你需要知道完整的日期和时间。一旦你这样做了,最简单的就是将完整的东部(美国/纽约)日期和时间转换为UTC,然后将其转换为中部(美国/芝加哥),山地(美国/丹佛)和太平洋(美国/洛杉矶)。
America/…位是大多数机器上的TZ数据库使用的时区名称。America/New_York是"东部"时间:它指定什么时候是夏令时,什么时候不是,以及与UTC的偏移量是多少。它甚至还有历史数据,比如夏令时开始的日期。结局都变了。(在全球范围内,实际上变化非常频繁。政府…)
保持不支持夏令时的版本:
首先,让我们运行两个辅助函数:to_24hour
,它将(hour, ampm)
转换为24小时格式,to_12hour
,它以相反的方式进行转换。这将使事情更容易思考,因为我们可以在24小时内更容易地做减法。
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')
一旦我们有了这些,事情就变得简单了:
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)
…与那些调整:
>>> 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)
最后一点。你的文档字符串是:
(number, str)-> number
这个函数将12小时的时间(以am/pm表示)转换为其等效的24小时时间。
以24小时格式返回时间。
这当然是to_24hour
所做的。
带时区识别
Python对时区并没有真正的帮助;Justin Barber在另一个答案中建议pytz
;这是个不错的选择。
如果我们知道某个日期或时间是东方的:
now = datetime.datetime(2014, 3, 14, 12, 34)
获取时区:
et = pytz.timezone('America/New_York')
ct = pytz.timezone('America/Chicago')
mt = pytz.timezone('America/Denver')
pt = pytz.timezone('America/Los_Angeles')
我们可以转换为中央和其他:
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))
(如注释所述,当更改可能跨越DST边界时,pytz
奇怪地要求调用normalize
,这基本上是您所做的任何事情。)
:
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')))
如果您正在讨论时区,那么除了时间之外,还必须指定日期(年,月,日)。
将给定的hours
和am_or_pm
转换为不同的时区:
- 转换为24小时 <
- 添加日期/gh>
- 在源时区创建具有时区意识的datetime对象
- 将其转换为给定的时区
time_in_24h
不应该尝试做太多。让它做它的名字所暗示的,即:转换输入小时,am或pm为24小时格式:
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
你也可以使用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
然后你可以定义print_times()
函数来打印3个不同时区的时间:
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()))
正确指定日期是很重要的,否则你将不知道正确的UTC偏移量。代码使用pytz
模块访问时区信息。strftime()
格式代码用于打印。
的例子:
>>> 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)
特别注意:
-
datetime.now(source_tz)
允许在给定的时区获得正确的当前时间。如果本地时区不是source_tz
,则 -
is_dst=None
表示tz.localize()
方法会在本地时间不明确或不存在时引发异常。否则它就默认为is_dst=False
这可能不是你想要的 -
tz.normalize()
可能是必要的,如果转换发生在DST边界
datetime.now()
在这里是不正确的您可以试试pytz
。您可以使用pip install pytz
安装它。在这里,您可以使用normalize
方法(基于文档)做类似的事情:
>>> from datetime import datetime
>>> from pytz import timezone
>>> import pytz
>>> central = timezone('US/Central')
>>> mountain = timezone('US/Mountain')
>>> mountain_date = mountain.localize(datetime.now()) # set time as right now mountain time
>>> fmt = '%Y-%m-%d %I:%M:%S %p'
>>> central_date = central.normalize(mountain_date.astimezone(central))
>>> print central_date.strftime(fmt), central, 'is', mountain_date.strftime(fmt), mountain
2014-03-15 07:29:17 PM US/Mountain is 2014-03-15 08:29:17 PM US/Central
那么你的函数可能最终看起来像这样:
>>> def time_in_24h(hour, am_pm):
"""hour is an integer that represents eastern time on the 12-hour clock, and am_pm
will take any string that begins with 'a' or 'p'"""
if not am_pm.lower().startswith(('a', 'p')): # return None if am_pm does not start with 'a' or 'p'
return
central = timezone('US/Central')
mountain = timezone('US/Mountain')
pacific = timezone('US/Pacific')
eastern = timezone('US/Eastern')
if hour == 12:
mod_hour = 0 if am_pm.lower().startswith('a') else 12
else:
mod_hour = hour + 12 if am_pm.lower().startswith('p') else hour # add 12 if am_pm starts with 'p', but keep original hour for display purposes
fmt = '%H:%M %p'
eastern_time = eastern.localize(datetime(1900, 1, 2, mod_hour))
for tz in (central, mountain, pacific):
d = tz.normalize(eastern_time.astimezone(tz))
print hour, am_pm, 'EST is', d.strftime(fmt), tz # tz displays as pytz timezone; can change
>>> time_in_24h(1, 'am')
1 am EST is 00:00 AM US/Central
1 am EST is 23:00 PM US/Mountain
1 am EST is 22:00 PM US/Pacific
>>> time_in_24h(9, 'pm')
9 pm EST is 20:00 PM US/Central
9 pm EST is 19:00 PM US/Mountain
9 pm EST is 18:00 PM US/Pacific