获取“挂钟”时间流逝的秒数
Getting number of seconds elapsed in `Wall Clock' time
我正在编写一个模块来计算给定日期的半小时交易时段。交易时段从半小时开始,从 1(从 00:00 开始)到 48(从 23:30 开始)连续编号。通常一天有48个交易时段,但在夏令时开始的那天有46个,在结束的那天有50个。
下面的代码适用于所有 'normal' 天,但无法在夏令时开始或结束的日子里给出正确的交易期数字,因为下面代码中的 datetime.replace()
使用相同的 [=12] =] 一天开始的时间偏移量。在夏令时改变的日子里,这个假设是不正确的。
datetime.replace() 是否可以将 00:00 的时间设置为 'wall clock' 时间,以便时差与将秒表设置为 00:00 然后计算它在所有天中正确匹配的半小时间隔数?我还没有找到自动执行此操作的方法。
一个例子:
新西兰的夏令时于 2015 年 4 月 5 日在 03:00 (2015-05-04 14:00Z
) 结束。因此 02:00-02:59(2015-05-04 14:00Z
- 2015-05-04 14:59Z
)在 'wall clock' 时间内重复。因此在新西兰,由于夏令时结束,2015 年 4 月 5 日凌晨 4 点用了 18000 秒。 2014 年 9 月 28 日,夏令时开始,用时 10800 秒。
@staticmethod
def half_hour_from_utc(time_utc = None):
# Get the time as NZ civil time.
time_nz = time_utc.astimezone(pytz.timezone('Pacific/Auckland'))
# Get the time tuple for the start of the day. This is done by keeping
# the date the same but setting the hours, minutes, seconds and
# microseconds to zero.
time_start_of_day = time_nz.replace(hour = 0, minute = 0, second = 0, microsecond = 0)
# Get total number of seconds. The half hour period is the number of
# 1800 second periods that have passed + 1
total_secs = int((time_nz - time_start_of_day).total_seconds())
half_hour = 1 + total_secs // 1800
print('%s %s %s %s\n' % (time_nz, time_start_of_day, total_secs, half_hour))
在处理挂钟算法时,您应该使用 normalize()
和 localize()
:
def half_hour_from_utc(time_utc = None):
tz = pytz.timezone('Pacific/Auckland')
time_nz = tz.normalize(time_utc)
time_start_of_day = tz.localize(datetime.datetime(time_nz.year, time_nz.month, time_nz.day))
total_secs = int((time_nz - time_start_of_day).total_seconds())
half_hour = 1 + total_secs // 1800
print('%s %s %s %s\n' % (time_nz, time_start_of_day, total_secs, half_hour))
normalize()
= 将带时区的日期时间转换为带另一个时区的日期时间。
localize()
= 将不带时区的日期时间转换为带时区的日期时间。
这些方法考虑了使用时区计算正确日期时间的必要逻辑。
问题是 .replace()
调用可能 return 非规范化 datetime
值,即 tzinfo
可能在午夜时出错。参见 How do I get the UTC time of “midnight” for a given timezone?
from datetime import datetime, time as datetime_time, timedelta
import pytz # $ pip install pytz
def half_hour_from_utc(time_utc, tz=pytz.timezone('Pacific/Auckland')):
time_nz = time_utc.astimezone(tz) # no need to call normalize() here
midnight = datetime.combine(time_nz, datetime_time(0, 0)) # naive
time_start_of_day = tz.localize(midnight, is_dst=None) # aware
return 1 + (time_nz - time_start_of_day) // timedelta(minutes=30) # Python 3
要在 Python 上模拟 1 + td // timedelta(minutes=30)
2:
td = time_nz - time_start_of_day
assert td.days == 0
return 1 + td.seconds // 1800
如果 DST 转换可能发生在给定时区的午夜,那么您可以在一天的开始使用最小值:
time_start_of_day = min(tz.localize(midnight, is_dst=False),
tz.localize(midnight, is_dst=True))
注意:即使在给定日期的给定时区不存在 00:00 时间,它也能正常工作:要找到差异,只有相应的 utc 时间很重要。
我正在编写一个模块来计算给定日期的半小时交易时段。交易时段从半小时开始,从 1(从 00:00 开始)到 48(从 23:30 开始)连续编号。通常一天有48个交易时段,但在夏令时开始的那天有46个,在结束的那天有50个。
下面的代码适用于所有 'normal' 天,但无法在夏令时开始或结束的日子里给出正确的交易期数字,因为下面代码中的 datetime.replace()
使用相同的 [=12] =] 一天开始的时间偏移量。在夏令时改变的日子里,这个假设是不正确的。
datetime.replace() 是否可以将 00:00 的时间设置为 'wall clock' 时间,以便时差与将秒表设置为 00:00 然后计算它在所有天中正确匹配的半小时间隔数?我还没有找到自动执行此操作的方法。
一个例子:
新西兰的夏令时于 2015 年 4 月 5 日在 03:00 (2015-05-04 14:00Z
) 结束。因此 02:00-02:59(2015-05-04 14:00Z
- 2015-05-04 14:59Z
)在 'wall clock' 时间内重复。因此在新西兰,由于夏令时结束,2015 年 4 月 5 日凌晨 4 点用了 18000 秒。 2014 年 9 月 28 日,夏令时开始,用时 10800 秒。
@staticmethod
def half_hour_from_utc(time_utc = None):
# Get the time as NZ civil time.
time_nz = time_utc.astimezone(pytz.timezone('Pacific/Auckland'))
# Get the time tuple for the start of the day. This is done by keeping
# the date the same but setting the hours, minutes, seconds and
# microseconds to zero.
time_start_of_day = time_nz.replace(hour = 0, minute = 0, second = 0, microsecond = 0)
# Get total number of seconds. The half hour period is the number of
# 1800 second periods that have passed + 1
total_secs = int((time_nz - time_start_of_day).total_seconds())
half_hour = 1 + total_secs // 1800
print('%s %s %s %s\n' % (time_nz, time_start_of_day, total_secs, half_hour))
在处理挂钟算法时,您应该使用 normalize()
和 localize()
:
def half_hour_from_utc(time_utc = None):
tz = pytz.timezone('Pacific/Auckland')
time_nz = tz.normalize(time_utc)
time_start_of_day = tz.localize(datetime.datetime(time_nz.year, time_nz.month, time_nz.day))
total_secs = int((time_nz - time_start_of_day).total_seconds())
half_hour = 1 + total_secs // 1800
print('%s %s %s %s\n' % (time_nz, time_start_of_day, total_secs, half_hour))
normalize()
= 将带时区的日期时间转换为带另一个时区的日期时间。localize()
= 将不带时区的日期时间转换为带时区的日期时间。
这些方法考虑了使用时区计算正确日期时间的必要逻辑。
问题是 .replace()
调用可能 return 非规范化 datetime
值,即 tzinfo
可能在午夜时出错。参见 How do I get the UTC time of “midnight” for a given timezone?
from datetime import datetime, time as datetime_time, timedelta
import pytz # $ pip install pytz
def half_hour_from_utc(time_utc, tz=pytz.timezone('Pacific/Auckland')):
time_nz = time_utc.astimezone(tz) # no need to call normalize() here
midnight = datetime.combine(time_nz, datetime_time(0, 0)) # naive
time_start_of_day = tz.localize(midnight, is_dst=None) # aware
return 1 + (time_nz - time_start_of_day) // timedelta(minutes=30) # Python 3
要在 Python 上模拟 1 + td // timedelta(minutes=30)
2:
td = time_nz - time_start_of_day
assert td.days == 0
return 1 + td.seconds // 1800
如果 DST 转换可能发生在给定时区的午夜,那么您可以在一天的开始使用最小值:
time_start_of_day = min(tz.localize(midnight, is_dst=False),
tz.localize(midnight, is_dst=True))
注意:即使在给定日期的给定时区不存在 00:00 时间,它也能正常工作:要找到差异,只有相应的 utc 时间很重要。