首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python -将时间转换为不同的时区,保持am/pm。

Python -将时间转换为不同的时区,保持am/pm。
EN

Stack Overflow用户
提问于 2014-03-16 01:48:54
回答 3查看 4.9K关注 0票数 5

在Python中,使用这个函数(带am/pm的东部标准时间(EST) )应该以3种时间格式输出它。中央时间(CT)、山区时间(MT)和太平洋时间(PT)均在正确的上午/下午):

代码语言:javascript
复制
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)

使用此命令:

代码语言:javascript
复制
time_in_24h(7,'am')

我得到了这个输出:

代码语言:javascript
复制
7 am EST is 6 Central Time(CT)
7 am EST is 5 Mountain Time(MT)
7 am EST is 4 Pacific Time(PT)

我试图输出正确的3次基于输入的EST,上午/下午到中央时间(CT),山时间(MT)和太平洋时间(PT)都在正确的上午/下午。如何根据偏移量得到正确的am/pm输出?例如,下午2点EST的输入,应该输出:

代码语言:javascript
复制
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中构建的东西都可以在没有问题的情况下解决这个问题吗?有办法解决我的困境吗?我付出了我的全部,在这件事上真的坚持了下来。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-03-16 02:01:26

到中环,看看东部时间是下午12点就可以了。如果是,那就调整到上午11点。同样,如果东部时间是午夜,那么调整到晚上11点。这需要一点if,但您可以这样做。

问题是,,它还是错的,。约会时间的数学很难,你已经忘记了DST。

通常,每年一次是东部时间(EST)的凌晨1次,也是中央时间(CDT)的1次。(同样,它也是东部的凌晨3点和中环的1点。)

考虑到您的函数当前的输入量,您不能考虑这一点:您需要知道完整的日期和时间。一旦你这样做了,最简单的办法就是把整个东部(美国/纽约)的日期和时间转换为世界协调时,然后转换成中美洲(美国/芝加哥)、山(美国/丹佛)和太平洋(美国/洛杉矶)。

美国/…位是大多数机器上TZ数据库使用的时区的名称。美国/纽约是“东方”时间:它指定DST是什么时候,什么时候不是,以及与UTC的偏移量是什么。它甚至有历史数据,因为DST开始和结束的日期已经改变了。(在全球范围内,实际变化相当频繁。)政府(…)

保持非DST版本:

首先,让我们使用两个帮助函数:to_24hour (将(hour, ampm)转换为24小时格式)和to_12hour (另一种方式)。这将使事情更容易思考,因为我们可以更容易地在24小时内完成减法。

代码语言:javascript
复制
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')

一旦我们有了这些,事情就变得简单了:

代码语言:javascript
复制
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)

…在作出这些调整后:

代码语言:javascript
复制
>>> 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)

最后一个音符。您的docstring如下:

(编号,str)-->数字 此函数将以上午/下午为代表的12小时时间转换为其等效的24小时时间。 以24小时格式返回时间。

当然,这就是to_24hour所做的。

时区意识

Python在时区方面并没有真正的帮助;Justin在另一个答案中建议pytz;这是一个很好的选择。

如果我们有一些我们知道在东部的日期或时间:

代码语言:javascript
复制
now = datetime.datetime(2014, 3, 14, 12, 34)

抓取时区:

代码语言:javascript
复制
et = pytz.timezone('America/New_York')
ct = pytz.timezone('America/Chicago')
mt = pytz.timezone('America/Denver')
pt = pytz.timezone('America/Los_Angeles')

我们可以转换为中环和其他有:

代码语言:javascript
复制
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,这基本上就是您所做的任何事情。)

然后:

代码语言:javascript
复制
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')))
票数 4
EN

Stack Overflow用户

发布于 2014-03-16 12:47:38

如果您说的是时区,那么除了时间之外,还必须指定日期(年、月、日)。

要将给定的hoursam_or_pm转换为不同的时区,请执行以下操作:

  1. 转换为24小时
  2. 添加日期
  3. 在源时区中创建时区感知的datetime对象。
  4. 将其转换为给定的时区。

time_in_24h不应该做太多的事情。让它做它的名字所暗示的,即:将输入小时、上午或下午转换为24小时格式:

代码语言:javascript
复制
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()实现它。

代码语言:javascript
复制
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()函数,该函数在三个不同的时区中打印时间:

代码语言:javascript
复制
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模块访问时区信息。格式码用于打印。

示例:

代码语言:javascript
复制
>>> 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)允许在给定时区中获得正确的当前时间。如果本地时区不是datetime.now(),则此处的source_tz将是不正确的。
  • is_dst=None意味着tz.localize()方法会为不明确或不存在的本地时间引发异常。否则,它只是默认为is_dst=False,这可能不是您想要的
  • 如果转换发生在DST边界上,则可能需要tz.normalize()
票数 2
EN

Stack Overflow用户

发布于 2014-03-16 02:12:02

你可以试试pytz。您可以用pip install pytz安装它。在这里,您可以使用normalize方法(基于医生们)执行类似的操作:

代码语言:javascript
复制
>>> 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

因此,您的函数最终可能看起来如下所示:

代码语言:javascript
复制
>>> 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
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22432030

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档