如何获取“午夜”的 UTC 时间 对于给定的时区?
我现在能想到的最好的办法就是这个怪物:
>>> datetime.utcnow() \
... .replace(tzinfo=pytz.UTC) \
... .astimezone(pytz.timezone("Australia/Melbourne")) \
... .replace(hour=0,minute=0,second=0,microsecond=0) \
... .astimezone(pytz.UTC) \
... .replace(tzinfo=None)
datetime.datetime(2008, 12, 16, 13, 0)
即,用英语,获取当前时间(UTC),将其转换为其他时区,将时间设置为午夜,然后转换回 UTC。
我不只是使用 now() 或 localtime() ,因为这将使用服务器的时区,而不是用户的时区。
我不禁觉得自己错过了一些东西,有什么想法吗?
The best I can come up with for now is this monstrosity:
>>> datetime.utcnow() \
... .replace(tzinfo=pytz.UTC) \
... .astimezone(pytz.timezone("Australia/Melbourne")) \
... .replace(hour=0,minute=0,second=0,microsecond=0) \
... .astimezone(pytz.UTC) \
... .replace(tzinfo=None)
datetime.datetime(2008, 12, 16, 13, 0)
I.e., in English, get the current time (in UTC), convert it to some other timezone, set the time to midnight, then convert back to UTC.
I'm not just using now() or localtime() as that would use the server's timezone, not the user's timezone.
I can't help feeling I'm missing something, any ideas?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
使用 dateutil.tz 比 pytz 更简单:
tzinfo 文档 从 Python 3.6 开始推荐使用 dateutil.tz。 dateutil.tz 中的 tzinfo 对象没有像 DST 这样的异常问题,不需要 pytz 的本地化功能。 使用 user3850 的示例:
This is more straightforward with dateutil.tz than pytz:
The tzinfo documentation recommends dateutil.tz since Python 3.6. The tzinfo objects from dateutil.tz have no problems with anomalies like DST without requiring the localize functionality of pytz. Using the example from user3850:
设置 TZ 环境变量会修改 Python 的日期和时间函数使用的时区。
Setting the TZ environment variable modifies what timezone Python's date and time functions work with.
每个时区都有一个数字,例如美国/中部= -6。 这被定义为与 UTC 的小时偏移量。 由于 0000 是午夜,因此您可以简单地使用此偏移量来查找任何时区中午夜 UTC 的时间。 要访问它,我相信您可以使用
根据 Python 文档, time.timezone 实际上给出了这个数字的负值:
因此,如果该数字为正数,则只需使用该数字表示时间(以小时为单位)(即,如果芝加哥是午夜(时区值为 +6),则 6000 = UTC 时间上午 6 点)。
如果数字是负数,则从 24 中减去。例如,柏林会给出 -1,因此 24 - 1 => 2300 = 晚上 11 点。
Each time zone has a number, eg US/Central = -6. This is defined as the offset in hours from UTC. Since 0000 is midnight, you can simply use this offset to find the time in any time zone when it is midnight UTC. To access that, I believe you can use
According to The Python Docs, time.timezone actually gives the negative value of this number:
So you would simply use that number for the time in hours if it's positive (i.e., if it's midnight in Chicago (which has a +6 timezone value), then it's 6000 = 6am UTC).
If the number is negative, subtract from 24. For example, Berlin would give -1, so 24 - 1 => 2300 = 11pm.
值得一提的是,我们可以调整 @jfs 给出的答案来查找明天的午夜或昨天的午夜等。诀窍是向感知时区添加一定的天数。 这是有效的,因为虽然这通常会增加 24 小时,但有时可能会根据 DST 问题增加 23 或 25 小时。
It's worth remarking that we can adapt the answer given by @jfs to find tomorrow's midnight or yesterday's midnight, etc. The trick is to add a certain number of days to the aware timezone. This works because although this usually adds 24 hours, sometimes it might add 23 or 25 based on DST issues.
我认为如果你这样做的话,你可以减少一些方法调用:
但是......你的代码中有一个比美观更大的问题:它会在切换到夏令时或从夏令时切换到夏令时的那天给出错误的结果。
原因是日期时间构造函数和
replace()
都没有考虑 DST 更改。例如:
但是,
tz.localize()
的文档指出:因此,你的问题是这样解决的:
不过,不能保证 1582 年之前的日期。
I think you can shave off a few method calls if you do it like this:
BUT… there is a bigger problem than aesthetics in your code: it will give the wrong result on the day of the switch to or from Daylight Saving Time.
The reason for this is that neither the datetime constructors nor
replace()
take DST changes into account.For example:
However, the documentation for
tz.localize()
states:Thus, your problem is solved like so:
No guarantees for dates before 1582, though.
@hop 的答案在从夏令时 (DST) 过渡的那天是错误的,例如 2012 年 4 月 1 日。要修复它
tz.localize()
可以使用:与注释相同:
@hop's answer is wrong on the day of transition from Daylight Saving Time (DST) e.g., Apr 1, 2012. To fix it
tz.localize()
could be used:The same with comments: