将 UTC 日期时间字符串转换为本地日期时间

发布于 2024-10-13 18:20:09 字数 566 浏览 9 评论 0原文

我从来没有需要在 UTC 和 UTC 之间进行时间转换。最近有人请求让我的应用程序了解时区,但我一直在兜圈子。有关将本地时间转换为 UTC 的大量信息,我发现这些信息相当简单(也许我也做错了),但我找不到任何有关轻松将 UTC 时间转换为最终用户时区的信息。

简而言之,Android 应用程序向我(appengine 应用程序)发送数据,并且该数据中包含时间戳。为了将该时间戳存储为 utc 时间,我正在使用:

datetime.utcfromtimestamp(timestamp)

这似乎有效。当我的应用程序存储数据时,它被存储为提前 5 小时(我是 EST -5)

数据被存储在 appengine 的 BigTable 上,当检索时,它会以字符串形式出现,如下所示:

"2011-01-21 02:37:21"

如何将此字符串转换为用户正确时区的日期时间?

另外,用户时区信息的建议存储是什么? (你通常如何存储 tz 信息,即:“-5:00”或“EST”等?)我确信我的第一个问题的答案可能包含一个参数,第二个问题的答案。

I've never had to convert time to and from UTC. Recently had a request to have my app be timezone aware, and I've been running myself in circles. Lots of information on converting local time to UTC, which I found fairly elementary (maybe I'm doing that wrong as well), but I can not find any information on easily converting the UTC time to the end-users timezone.

In a nutshell, and android app sends me (appengine app) data and within that data is a timestamp. To store that timestamp to utc time I am using:

datetime.utcfromtimestamp(timestamp)

That seems to be working. When my app stores the data, it is being store as 5 hours ahead (I am EST -5)

The data is being stored on appengine's BigTable, and when retrieved it comes out as a string like so:

"2011-01-21 02:37:21"

How do I convert this string to a DateTime in the users correct time zone?

Also, what is the recommended storage for a users timezone information? (How do you typically store tz info ie: "-5:00" or "EST" etc etc ?) I'm sure the answer to my first question might contain a parameter the answers the second.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(16

南渊 2024-10-20 18:20:09

如果您不想提供自己的 tzinfo 对象,请查看 python-dateutil< /a> 库。它在 zoneinfo (Olson) 数据库 之上提供 tzinfo 实现,例如您可以通过有点规范的名称来引用时区规则。

from datetime import datetime
from dateutil import tz

# METHOD 1: Hardcode zones:
from_zone = tz.gettz('UTC')
to_zone = tz.gettz('America/New_York')

# METHOD 2: Auto-detect zones:
from_zone = tz.tzutc()
to_zone = tz.tzlocal()

# Since datetime.utcnow() is deprecated since version 3.12 use datetime.now()
# utc = datetime.now()  
utc = datetime.strptime('2011-01-21 02:37:21', '%Y-%m-%d %H:%M:%S')

# Tell the datetime object that it's in UTC time zone since 
# datetime objects are 'naive' by default
utc = utc.replace(tzinfo=from_zone)

# Convert time zone
central = utc.astimezone(to_zone)

编辑 扩展示例以显示 strptime 用法

编辑 2 修复 API 用法以显示更好的入口点方法

编辑 3 包含自动-时区检测方法(Yarin)

If you don't want to provide your own tzinfo objects, check out the python-dateutil library. It provides tzinfo implementations on top of a zoneinfo (Olson) database such that you can refer to time zone rules by a somewhat canonical name.

from datetime import datetime
from dateutil import tz

# METHOD 1: Hardcode zones:
from_zone = tz.gettz('UTC')
to_zone = tz.gettz('America/New_York')

# METHOD 2: Auto-detect zones:
from_zone = tz.tzutc()
to_zone = tz.tzlocal()

# Since datetime.utcnow() is deprecated since version 3.12 use datetime.now()
# utc = datetime.now()  
utc = datetime.strptime('2011-01-21 02:37:21', '%Y-%m-%d %H:%M:%S')

# Tell the datetime object that it's in UTC time zone since 
# datetime objects are 'naive' by default
utc = utc.replace(tzinfo=from_zone)

# Convert time zone
central = utc.astimezone(to_zone)

Edit Expanded example to show strptime usage

Edit 2 Fixed API usage to show better entry point method

Edit 3 Included auto-detect methods for timezones (Yarin)

面如桃花 2024-10-20 18:20:09

这是一种不依赖于任何外部库的弹性方法:

from datetime import datetime
import time

def datetime_from_utc_to_local(utc_datetime):
    now_timestamp = time.time()
    offset = datetime.fromtimestamp(now_timestamp) - datetime.utcfromtimestamp(now_timestamp)
    return utc_datetime + offset

这避免了 DelboyJay 示例中的计时问题。以及埃里克·范·奥斯滕修正案中较小的时机问题。

作为一个有趣的脚注,上面计算的时区偏移量可能与以下看似等效的表达式不同,这可能是由于夏令时规则的更改:

offset = datetime.fromtimestamp(0) - datetime.utcfromtimestamp(0) # NO!

更新: 此代码段的缺点是使用当前时间的 UTC 偏移量,这可能与输入日期时间的 UTC 偏移量不同。请参阅对此答案的评论以获取其他解决方案。

为了绕过不同的时间,请从传入的时间中获取纪元时间。这就是我所做的:

def utc2local(utc):
    epoch = time.mktime(utc.timetuple())
    offset = datetime.fromtimestamp(epoch) - datetime.utcfromtimestamp(epoch)
    return utc + offset

Here's a resilient method that doesn't depend on any external libraries:

from datetime import datetime
import time

def datetime_from_utc_to_local(utc_datetime):
    now_timestamp = time.time()
    offset = datetime.fromtimestamp(now_timestamp) - datetime.utcfromtimestamp(now_timestamp)
    return utc_datetime + offset

This avoids the timing issues in DelboyJay's example. And the lesser timing issues in Erik van Oosten's amendment.

As an interesting footnote, the timezone offset computed above can differ from the following seemingly equivalent expression, probably due to daylight savings rule changes:

offset = datetime.fromtimestamp(0) - datetime.utcfromtimestamp(0) # NO!

Update: This snippet has the weakness of using the UTC offset of the present time, which may differ from the UTC offset of the input datetime. See comments on this answer for another solution.

To get around the different times, grab the epoch time from the time passed in. Here's what I do:

def utc2local(utc):
    epoch = time.mktime(utc.timetuple())
    offset = datetime.fromtimestamp(epoch) - datetime.utcfromtimestamp(epoch)
    return utc + offset
仅此而已 2024-10-20 18:20:09

更新了最新的 Python 3 支持(请参阅旧答案的编辑历史记录):

从 Python 3.9 开始,内置的 zoneinfo 库:

zoneinfo 模块提供了具体的时区实现,以支持 PEP 615 中最初指定的 IANA 时区数据库。默认情况下, zoneinfo 使用系统的时区数据(如果有);如果没有可用的系统时区数据,库将回退到使用第一方 tzdata< /code>PyPI 上提供的软件包。


请参阅 zoneinfo.available_timezones() 获取时区名称列表。

这是一个简单的例子:

# "pip install -U tzdata" for latest zone support required on some OSes
import datetime as dt
import zoneinfo as zi

GMT = zi.ZoneInfo('GMT')
ExT = zi.ZoneInfo('US/Eastern')

print(dt.datetime.now(tz=GMT).strftime('%m/%d/%Y %H:%M:%S %Z'))
print(dt.datetime.now(tz=ExT).strftime('%m/%d/%Y %H:%M:%S %Z'))

t = dt.datetime.strptime('2011-01-21 02:37:21','%Y-%m-%d %H:%M:%S')
t = t.replace(tzinfo=GMT)
print(t)
print(t.astimezone(ExT))

# Preferred way now instead of utcfromtimestamp().
# See https://docs.python.org/3/library/datetime.html#datetime.datetime.utcfromtimestamp.
d = dt.datetime.fromtimestamp(1714365725, tz=dt.UTC)  # time zone-aware

# Formatting in different zones
print(d.strftime('%Y-%m-%d %I:%M:%S %p %Z'))
print(d.astimezone(ExT).strftime('%Y-%m-%d %I:%M:%S %p %Z'))
print(d.astimezone(zi.ZoneInfo('US/Pacific')).strftime('%Y-%m-%d %I:%M:%S %p %Z'))

输出:

04/29/2024 04:46:19 GMT
04/29/2024 00:46:19 EDT
2011-01-21 02:37:21+00:00
2011-01-20 21:37:21-05:00
2024-04-29 04:42:05 AM UTC
2024-04-29 12:42:05 AM EDT
2024-04-28 09:42:05 PM PDT

Updated for latest Python 3 support (see edit history for old answer):

As of Python 3.9 time zone information is provided in the built-in zoneinfo library:

The zoneinfo module provides a concrete time zone implementation to support the IANA time zone database as originally specified in PEP 615. By default, zoneinfo uses the system’s time zone data if available; if no system time zone data is available, the library will fall back to using the first-party tzdata package available on PyPI.

See zoneinfo.available_timezones() for a list of time zone names.

Here's a simple example:

# "pip install -U tzdata" for latest zone support required on some OSes
import datetime as dt
import zoneinfo as zi

GMT = zi.ZoneInfo('GMT')
ExT = zi.ZoneInfo('US/Eastern')

print(dt.datetime.now(tz=GMT).strftime('%m/%d/%Y %H:%M:%S %Z'))
print(dt.datetime.now(tz=ExT).strftime('%m/%d/%Y %H:%M:%S %Z'))

t = dt.datetime.strptime('2011-01-21 02:37:21','%Y-%m-%d %H:%M:%S')
t = t.replace(tzinfo=GMT)
print(t)
print(t.astimezone(ExT))

# Preferred way now instead of utcfromtimestamp().
# See https://docs.python.org/3/library/datetime.html#datetime.datetime.utcfromtimestamp.
d = dt.datetime.fromtimestamp(1714365725, tz=dt.UTC)  # time zone-aware

# Formatting in different zones
print(d.strftime('%Y-%m-%d %I:%M:%S %p %Z'))
print(d.astimezone(ExT).strftime('%Y-%m-%d %I:%M:%S %p %Z'))
print(d.astimezone(zi.ZoneInfo('US/Pacific')).strftime('%Y-%m-%d %I:%M:%S %p %Z'))

Output:

04/29/2024 04:46:19 GMT
04/29/2024 00:46:19 EDT
2011-01-21 02:37:21+00:00
2011-01-20 21:37:21-05:00
2024-04-29 04:42:05 AM UTC
2024-04-29 12:42:05 AM EDT
2024-04-28 09:42:05 PM PDT
ぇ气 2024-10-20 18:20:09

如果您想获得正确的结果,即使是与不明确的本地时间相对应的时间(例如,在 DST 转换期间)和/或本地 utc 偏移量在本地时区的不同时间不同,请使用 pytz时区:

#!/usr/bin/env python
from datetime import datetime
import pytz    # $ pip install pytz
import tzlocal # $ pip install tzlocal

local_timezone = tzlocal.get_localzone() # get pytz tzinfo
utc_time = datetime.strptime("2011-01-21 02:37:21", "%Y-%m-%d %H:%M:%S")
local_time = utc_time.replace(tzinfo=pytz.utc).astimezone(local_timezone)

If you want to get the correct result even for the time that corresponds to an ambiguous local time (e.g., during a DST transition) and/or the local utc offset is different at different times in your local time zone then use pytz timezones:

#!/usr/bin/env python
from datetime import datetime
import pytz    # $ pip install pytz
import tzlocal # $ pip install tzlocal

local_timezone = tzlocal.get_localzone() # get pytz tzinfo
utc_time = datetime.strptime("2011-01-21 02:37:21", "%Y-%m-%d %H:%M:%S")
local_time = utc_time.replace(tzinfo=pytz.utc).astimezone(local_timezone)
匿名的好友 2024-10-20 18:20:09

如果您不想使用除 datetime 之外的任何其他模块,这个答案应该会有所帮助。

datetime.utcfromtimestamp(timestamp) 返回一个简单的 datetime 对象(不是一个有意识的对象)。有意识的人会意识到时区,而天真的人则不会。如果您想在时区之间进行转换(例如在 UTC 和本地时间之间),您需要一个有意识的转换。

如果您不是实例化日期的人,但您仍然可以以 UTC 时间创建一个简单的 datetime 对象,您可能需要尝试使用以下 Python 3.x 代码来转换它

import datetime

d=datetime.datetime.strptime("2011-01-21 02:37:21", "%Y-%m-%d %H:%M:%S") #Get your naive datetime object
d=d.replace(tzinfo=datetime.timezone.utc) #Convert it to an aware datetime object in UTC time.
d=d.astimezone() #Convert it to your local timezone (still aware)
print(d.strftime("%d %b %Y (%I:%M:%S:%f %p) %Z")) #Print it with a directive of choice

:小心不要错误地认为,如果您的时区当前是 MDT,则夏令时不适用于上述代码,因为它会打印 MST。您会注意到,如果将月份更改为八月,它将打印 MDT。

获取可感知的 datetime 对象(也在 Python 3.x 中)的另一种简单方法是使用指定的时区来创建它。下面是一个使用 UTC 的示例:

import datetime, sys

aware_utc_dt_obj=datetime.datetime.now(datetime.timezone.utc) #create an aware datetime object
dt_obj_local=aware_utc_dt_obj.astimezone() #convert it to local time

#The following section is just code for a directive I made that I liked.
if sys.platform=="win32":
    directive="%#d %b %Y (%#I:%M:%S:%f %p) %Z"
else:
    directive="%-d %b %Y (%-I:%M:%S:%f %p) %Z"

print(dt_obj_local.strftime(directive))

如果您使用 Python 2.x,您可能需要子类化 datetime.tzinfo 并使用它来帮助您创建一个感知的 datetime 对象,因为 Python 2.x 中不存在 datetime.timezone

This answer should be helpful if you don't want to use any other modules besides datetime.

datetime.utcfromtimestamp(timestamp) returns a naive datetime object (not an aware one). Aware ones are timezone aware, and naive are not. You want an aware one if you want to convert between timezones (e.g. between UTC and local time).

If you aren't the one instantiating the date to start with, but you can still create a naive datetime object in UTC time, you might want to try this Python 3.x code to convert it:

import datetime

d=datetime.datetime.strptime("2011-01-21 02:37:21", "%Y-%m-%d %H:%M:%S") #Get your naive datetime object
d=d.replace(tzinfo=datetime.timezone.utc) #Convert it to an aware datetime object in UTC time.
d=d.astimezone() #Convert it to your local timezone (still aware)
print(d.strftime("%d %b %Y (%I:%M:%S:%f %p) %Z")) #Print it with a directive of choice

Be careful not to mistakenly assume that if your timezone is currently MDT that daylight savings doesn't work with the above code since it prints MST. You'll note that if you change the month to August, it'll print MDT.

Another easy way to get an aware datetime object (also in Python 3.x) is to create it with a timezone specified to start with. Here's an example, using UTC:

import datetime, sys

aware_utc_dt_obj=datetime.datetime.now(datetime.timezone.utc) #create an aware datetime object
dt_obj_local=aware_utc_dt_obj.astimezone() #convert it to local time

#The following section is just code for a directive I made that I liked.
if sys.platform=="win32":
    directive="%#d %b %Y (%#I:%M:%S:%f %p) %Z"
else:
    directive="%-d %b %Y (%-I:%M:%S:%f %p) %Z"

print(dt_obj_local.strftime(directive))

If you use Python 2.x, you'll probably have to subclass datetime.tzinfo and use that to help you create an aware datetime object, since datetime.timezone doesn't exist in Python 2.x.

柏拉图鍀咏恒 2024-10-20 18:20:09

如果使用 Django,您可以使用 timezone.localtime方法:

from django.utils import timezone
date 
# datetime.datetime(2014, 8, 1, 20, 15, 0, 513000, tzinfo=<UTC>)

timezone.localtime(date)
# datetime.datetime(2014, 8, 1, 16, 15, 0, 513000, tzinfo=<DstTzInfo 'America/New_York' EDT-1 day, 20:00:00 DST>)

If using Django, you can use the timezone.localtime method:

from django.utils import timezone
date 
# datetime.datetime(2014, 8, 1, 20, 15, 0, 513000, tzinfo=<UTC>)

timezone.localtime(date)
# datetime.datetime(2014, 8, 1, 16, 15, 0, 513000, tzinfo=<DstTzInfo 'America/New_York' EDT-1 day, 20:00:00 DST>)
南街九尾狐 2024-10-20 18:20:09

以下内容在美国西部的云环境中对我有用:

import datetime
import pytz

#set the timezone
tzInfo = pytz.timezone('America/Los_Angeles')
dt = datetime.datetime.now(tz=tzInfo)
print(dt)

The following worked for me in a Cloud environment for US west:

import datetime
import pytz

#set the timezone
tzInfo = pytz.timezone('America/Los_Angeles')
dt = datetime.datetime.now(tz=tzInfo)
print(dt)
琉璃梦幻 2024-10-20 18:20:09

franksands 的答案合并为一种方便的方法。

import calendar
import datetime

def to_local_datetime(utc_dt):
    """
    convert from utc datetime to a locally aware datetime according to the host timezone

    :param utc_dt: utc datetime
    :return: local timezone datetime
    """
    return datetime.datetime.fromtimestamp(calendar.timegm(utc_dt.timetuple()))

Consolidating the answer from franksands into a convenient method.

import calendar
import datetime

def to_local_datetime(utc_dt):
    """
    convert from utc datetime to a locally aware datetime according to the host timezone

    :param utc_dt: utc datetime
    :return: local timezone datetime
    """
    return datetime.datetime.fromtimestamp(calendar.timegm(utc_dt.timetuple()))
短叹 2024-10-20 18:20:09

您可以使用 arrow

from datetime import datetime
import arrow

now = datetime.utcnow()

print(arrow.get(now).to('local').format())
# '2018-04-04 15:59:24+02:00'

您可以使用 arrow.get() 提供任何事物。时间戳、iso 字符串等

You can use arrow

from datetime import datetime
import arrow

now = datetime.utcnow()

print(arrow.get(now).to('local').format())
# '2018-04-04 15:59:24+02:00'

you can feed arrow.get() with anything. timestamp, iso string etc

笑,眼淚并存 2024-10-20 18:20:09

此处的答案中,您可以使用时间模块将 utc 转换为计算机中设置的本地时间:

utc_time = time.strptime("2018-12-13T10:32:00.000", "%Y-%m-%dT%H:%M:%S.%f")
utc_seconds = calendar.timegm(utc_time)
local_time = time.localtime(utc_seconds)

From the answer here, you can use the time module to convert from utc to the local time set in your computer:

utc_time = time.strptime("2018-12-13T10:32:00.000", "%Y-%m-%dT%H:%M:%S.%f")
utc_seconds = calendar.timegm(utc_time)
local_time = time.localtime(utc_seconds)
月寒剑心 2024-10-20 18:20:09

这对我有用:

from django.utils import timezone
from datetime import timedelta,datetime

ist_time = timezone.now() + timedelta(hours=5,minutes=30)

#second method

ist_time = datetime.now() + timedelta(hours=5,minutes=30)

This worked for me:

from django.utils import timezone
from datetime import timedelta,datetime

ist_time = timezone.now() + timedelta(hours=5,minutes=30)

#second method

ist_time = datetime.now() + timedelta(hours=5,minutes=30)
脱离于你 2024-10-20 18:20:09

您可以使用calendar.timegm将时间转换为自Unix纪元以来的秒数,并使用time.localtime转换回来:

import calendar
import time

time_tuple = time.strptime("2011-01-21 02:37:21", "%Y-%m-%d %H:%M:%S")
t = calendar.timegm(time_tuple)

print time.ctime(t)

给出Fri Jan 21 05:37:21 2011 (因为我位于 UTC+03:00 时区)。

You can use calendar.timegm to convert your time to seconds since Unix epoch and time.localtime to convert back:

import calendar
import time

time_tuple = time.strptime("2011-01-21 02:37:21", "%Y-%m-%d %H:%M:%S")
t = calendar.timegm(time_tuple)

print time.ctime(t)

Gives Fri Jan 21 05:37:21 2011 (because I'm in UTC+03:00 timezone).

孤城病女 2024-10-20 18:20:09
import datetime

def utc_str_to_local_str(utc_str: str, utc_format: str, local_format: str):
    """
    :param utc_str: UTC time string
    :param utc_format: format of UTC time string
    :param local_format: format of local time string
    :return: local time string
    """
    temp1 = datetime.datetime.strptime(utc_str, utc_format)
    temp2 = temp1.replace(tzinfo=datetime.timezone.utc)
    local_time = temp2.astimezone()
    return local_time.strftime(local_format)

utc_tz_example_str = '2018-10-17T00:00:00.111Z'
utc_fmt = '%Y-%m-%dT%H:%M:%S.%fZ'
local_fmt = '%Y-%m-%dT%H:%M:%S+08:00'

# call my function here
local_tz_str = utc_str_to_local_str(utc_tz_example_str, utc_fmt, local_fmt)
print(local_tz_str)   # 2018-10-17T08:00:00+08:00

当我输入 utc_tz_example_str = 2018-10-17T00:00:00.111Z,(UTC +00:00)
然后我会得到 local_tz_str = 2018-10-17T08:00:00+08:00 (我的目标时区 +08:00)

参数 utc_format 是由您的特定 utc_tz_example_str 确定的格式。
参数local_fmt是最终所需的格式。

就我而言,我所需的格式是 %Y-%m-%dT%H:%M:%S+08:00 (+08:00 时区)。您应该构建您想要的格式。

import datetime

def utc_str_to_local_str(utc_str: str, utc_format: str, local_format: str):
    """
    :param utc_str: UTC time string
    :param utc_format: format of UTC time string
    :param local_format: format of local time string
    :return: local time string
    """
    temp1 = datetime.datetime.strptime(utc_str, utc_format)
    temp2 = temp1.replace(tzinfo=datetime.timezone.utc)
    local_time = temp2.astimezone()
    return local_time.strftime(local_format)

utc_tz_example_str = '2018-10-17T00:00:00.111Z'
utc_fmt = '%Y-%m-%dT%H:%M:%S.%fZ'
local_fmt = '%Y-%m-%dT%H:%M:%S+08:00'

# call my function here
local_tz_str = utc_str_to_local_str(utc_tz_example_str, utc_fmt, local_fmt)
print(local_tz_str)   # 2018-10-17T08:00:00+08:00

When I input utc_tz_example_str = 2018-10-17T00:00:00.111Z, (UTC +00:00)
then I will get local_tz_str = 2018-10-17T08:00:00+08:00 (My target timezone +08:00)

parameter utc_format is a format determined by your specific utc_tz_example_str.
parameter local_fmt is the final desired format.

In my case, my desired format is %Y-%m-%dT%H:%M:%S+08:00 ( +08:00 timezone). You should construct the format you want.

罪#恶を代价 2024-10-20 18:20:09

我传统上将其推迟到前端——从后端将时间作为时间戳或 UTC 中的其他日期时间格式发送,然后让客户端计算出时区偏移并在正确的时区中呈现此数据。

对于网络应用程序来说,这在 javascript 中很容易做到——您可以使用内置方法轻松计算出浏览器的时区偏移量,然后正确地从后端渲染数据。

I traditionally defer this to the frontend -- send times from the backend as timestamps or some other datetime format in UTC, then let the client figure out the timezone offset and render this data in the proper timezone.

For a webapp, this is pretty easy to do in javascript -- you can figure out the browser's timezone offset pretty easily using builtin methods and then render the data from the backend properly.

你又不是我 2024-10-20 18:20:09
  1. 首先确保您的计算机/服务器中有正确的时区,有时您可能会看到正确的时间,但使用错误的时区,因为系统会根据互联网调整时间。

这是我的工作代码,允许时区自动检测并支持 DST 时区:

from datetime import datetime, timedelta

def datetime_from_utc_to_local(utc_string ):  #"2023-09-30T17:49:06.000Z"
    # Extract the offset from the input string, assuming it's always in the format "-HHMM"
    local_offset_str = datetime.now().astimezone().isoformat(timespec="seconds")[-6:]

    # Convert the offset string to an integer representing hours an minutes
    offset_hours = int(local_offset_str[:3])
    offset_minutes = int(local_offset_str[4:])

    # Create a datetime object from the input string, excluding the "Z" character
    utc_datetime = datetime.fromisoformat(utc_string[:-1]) 

    # Apply the offset to convert the GMT datetime to the local time
    local_datetime = utc_datetime + timedelta(hours=offset_hours, minutes=offset_minutes)
    
    return local_datetime
  1. First make sure to have the right Timezone in your computer/server sometime you may see the right time but using a wrong timezone because the system adjust the time from internet.

This is my working code allowing timezone auto-detect and support DST timezone:

from datetime import datetime, timedelta

def datetime_from_utc_to_local(utc_string ):  #"2023-09-30T17:49:06.000Z"
    # Extract the offset from the input string, assuming it's always in the format "-HHMM"
    local_offset_str = datetime.now().astimezone().isoformat(timespec="seconds")[-6:]

    # Convert the offset string to an integer representing hours an minutes
    offset_hours = int(local_offset_str[:3])
    offset_minutes = int(local_offset_str[4:])

    # Create a datetime object from the input string, excluding the "Z" character
    utc_datetime = datetime.fromisoformat(utc_string[:-1]) 

    # Apply the offset to convert the GMT datetime to the local time
    local_datetime = utc_datetime + timedelta(hours=offset_hours, minutes=offset_minutes)
    
    return local_datetime
蝶…霜飞 2024-10-20 18:20:09

这是一个快速但肮脏的版本,它使用本地系统设置来计算时差。注意:如果您需要转换到当前系统未运行的时区,这将不起作用。我已经在 BST 时区下使用英国设置对此进行了测试

from datetime import datetime
def ConvertP4DateTimeToLocal(timestampValue):
   assert isinstance(timestampValue, int)

   # get the UTC time from the timestamp integer value.
   d = datetime.utcfromtimestamp( timestampValue )

   # calculate time difference from utcnow and the local system time reported by OS
   offset = datetime.now() - datetime.utcnow()

   # Add offset to UTC time and return it
   return d + offset

Here is a quick and dirty version that uses the local systems settings to work out the time difference. NOTE: This will not work if you need to convert to a timezone that your current system is not running in. I have tested this with UK settings under BST timezone

from datetime import datetime
def ConvertP4DateTimeToLocal(timestampValue):
   assert isinstance(timestampValue, int)

   # get the UTC time from the timestamp integer value.
   d = datetime.utcfromtimestamp( timestampValue )

   # calculate time difference from utcnow and the local system time reported by OS
   offset = datetime.now() - datetime.utcnow()

   # Add offset to UTC time and return it
   return d + offset
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文