标签归档:datetime

从号码中获取月份名称

问题:从号码中获取月份名称

如何从月份编号中获得月份名称?

例如,如果我有3,我想返回march

date.tm_month()

如何获得字符串march

How can I get the month name from the month number?

For instance, if I have 3, I want to return march

date.tm_month()

How to get the string march?


回答 0

日历API

从中可以看到calendar.month_name[3]它将返回March,并且的数组索引0为空字符串,因此也无需担心零索引。

Calendar API

From that you can see that calendar.month_name[3] would return March, and the array index of 0 is the empty string, so there’s no need to worry about zero-indexing either.


回答 1

import datetime
mydate = datetime.datetime.now()
mydate.strftime("%B")

返回:12月

有关Python文档网站的更多信息


[编辑:来自@GiriB的出色评论]您还可以使用%b它返回月份名称的缩写。

mydate.strftime("%b")

对于上面的示例,它将返回Dec

import datetime
mydate = datetime.datetime.now()
mydate.strftime("%B")

Returns: December

Some more info on the Python doc website


[EDIT : great comment from @GiriB] You can also use %b which returns the short notation for month name.

mydate.strftime("%b")

For the example above, it would return Dec.


回答 2

import datetime

monthinteger = 4

month = datetime.date(1900, monthinteger, 1).strftime('%B')

print month

四月

import datetime

monthinteger = 4

month = datetime.date(1900, monthinteger, 1).strftime('%B')

print month

April


回答 3

如果您只需要知道给定数字(1-12)的月份名称,这就没有太大帮助,因为当前日期无关紧要。

calendar.month_name[i]

要么

calendar.month_abbr[i]

在这里更有用。

这是一个例子:

import calendar

for month_idx in range(1, 13):
    print (calendar.month_name[month_idx])
    print (calendar.month_abbr[month_idx])
    print ("")

样本输出:

January
Jan

February
Feb

March
Mar

...

This is not so helpful if you need to just know the month name for a given number (1 – 12), as the current day doesn’t matter.

calendar.month_name[i]

or

calendar.month_abbr[i]

are more useful here.

Here is an example:

import calendar

for month_idx in range(1, 13):
    print (calendar.month_name[month_idx])
    print (calendar.month_abbr[month_idx])
    print ("")

Sample output:

January
Jan

February
Feb

March
Mar

...

回答 4

import datetime
mydate = datetime.datetime.now()
mydate.strftime("%B") # 'December'
mydate.strftime("%b") # 'dec'
import datetime
mydate = datetime.datetime.now()
mydate.strftime("%B") # 'December'
mydate.strftime("%b") # 'dec'

回答 5

如果您(像我一样)在数据框中有一列月份数字,我将提供此信息:

df['monthName'] = df['monthNumer'].apply(lambda x: calendar.month_name[x])

I’ll offer this in case (like me) you have a column of month numbers in a dataframe:

df['monthName'] = df['monthNumer'].apply(lambda x: calendar.month_name[x])

回答 6

这就是我要做的:

from datetime import *

months = ["Unknown",
          "January",
          "Febuary",
          "March",
          "April",
          "May",
          "June",
          "July",
          "August",
          "September",
          "October",
          "November",
          "December"]

now = (datetime.now())
year = (now.year)
month = (months[now.month])
print(month)

输出:

>>> September

(这是我写这篇文章的真实日期)

This Is What I Would Do:

from datetime import *

months = ["Unknown",
          "January",
          "Febuary",
          "March",
          "April",
          "May",
          "June",
          "July",
          "August",
          "September",
          "October",
          "November",
          "December"]

now = (datetime.now())
year = (now.year)
month = (months[now.month])
print(month)

It Outputs:

>>> September

(This Was The Real Date When I Wrote This)


回答 7

一些好的 答案已经利用日历了,但是尚未提到设置语言环境的效果。

例如,法语:

import locale
import calendar

locale.setlocale(locale.LC_ALL, 'fr_FR')

assert calendar.month_name[1] == 'janvier'
assert calendar.month_abbr[1] == 'jan'

如果计划在setlocale代码中使用,请确保阅读文档中的提示和注意事项以及扩展编写器部分。此处显示的示例并不代表应如何使用它。特别是从这两部分中:

在某些库例程中调用setlocale()通常是一个坏主意,因为它的副作用是会影响整个程序[…]

扩展模块永远不要调用setlocale()[…]

Some good answers already make use of calendar but the effect of setting the locale hasn’t been mentioned yet.

Calendar set month names according to the current locale, for exemple in French:

import locale
import calendar

locale.setlocale(locale.LC_ALL, 'fr_FR')

assert calendar.month_name[1] == 'janvier'
assert calendar.month_abbr[1] == 'jan'

If you plan on using setlocale in your code, make sure to read the tips and caveats and extension writer sections from the documentation. The example shown here is not representative of how it should be used. In particular, from these two sections:

It is generally a bad idea to call setlocale() in some library routine, since as a side effect it affects the entire program […]

Extension modules should never call setlocale() […]


回答 8

对于arbitaray月度范围

month_integer=range(0,100)
map(lambda x: calendar.month_name[x%12+start],month_integer)

将产生正确的列表。start从一月在月份整数列表中开始的位置调整-parameter。

For arbitaray range of month numbers

month_integer=range(0,100)
map(lambda x: calendar.month_name[x%12+start],month_integer)

will yield correct list. Adjust start-parameter from where January begins in the month-integer list.


回答 9

8.1。datetime-基本日期和时间类型-Python 2.7.17文档 https://docs.python.org/2/library/datetime.html#strftime-strptime-behavior

所有strftime参数的列表。月份的名称以及诸如格式化之类的好东西,将零填满。阅读整页,了解诸如“天真的”参数规则之类的内容。这是简短的列表:%a周日,周一,…,星期六

%A周日,周一,…,周六

%w工作日为数字,其中0是星期日

%d每月的第一天02,…,31

%b 1月,2月,…,12月

%B一月,二月,…,十二月

%m月号,以零填充的01、02,…,12

%y 2位数字年份零填充00、01,…,99

%Y 4位数字1970、1988、2001、2013年

%H小时(24小时制),零填充00,01,…,23

%I小时(12小时制)零填充01,02,…,12

%p AM或PM。

%M分钟零填充00、01,…,59

%S第二个零填充00、01,…,59

%f微秒零填充000000,000001,…,999999

%z UTC偏移量,格式为+ HHMM或-HHMM + 0000,-0400,+ 1030

%Z时区名称UTC,EST,CST

%j一年中的当日零填充001、002,…,366

%U年份的周号零填充,第一个星期日之前的天是第0周

%W一年中的第几周(星期一作为第一天)

%c语言环境的日期和时间表示。1988年8月16日星期二21:30:00

%x语言环境的日期表示形式。1988年8月16日(zh_CN)

%X语言环境的时间表示形式。21:30:00

%%文字’%’字符。

8.1. datetime — Basic date and time types — Python 2.7.17 documentation https://docs.python.org/2/library/datetime.html#strftime-strptime-behavior

A list of all the strftime arguments. Names of months and nice stuff like formatting left zero fill. Read the full page for stuff like rules for “naive” arguments. Here is the list in brief: %a Sun, Mon, …, Sat

%A Sunday, Monday, …, Saturday

%w Weekday as number, where 0 is Sunday

%d Day of the month 01, 02, …, 31

%b Jan, Feb, …, Dec

%B January, February, …, December

%m Month number as a zero-padded 01, 02, …, 12

%y 2 digit year zero-padded 00, 01, …, 99

%Y 4 digit Year 1970, 1988, 2001, 2013

%H Hour (24-hour clock) zero-padded 00, 01, …, 23

%I Hour (12-hour clock) zero-padded 01, 02, …, 12

%p AM or PM.

%M Minute zero-padded 00, 01, …, 59

%S Second zero-padded 00, 01, …, 59

%f Microsecond zero-padded 000000, 000001, …, 999999

%z UTC offset in the form +HHMM or -HHMM +0000, -0400, +1030

%Z Time zone name UTC, EST, CST

%j Day of the year zero-padded 001, 002, …, 366

%U Week number of the year zero padded, Days before the first Sunday are week 0

%W Week number of the year (Monday as first day)

%c Locale’s date and time representation. Tue Aug 16 21:30:00 1988

%x Locale’s date representation. 08/16/1988 (en_US)

%X Locale’s time representation. 21:30:00

%% literal ‘%’ character.


回答 10

我创建了自己的函数,将数字转换为相应的月份。

def month_name (number):
    if number == 1:
        return "January"
    elif number == 2:
        return "February"
    elif number == 3:
        return "March"
    elif number == 4:
        return "April"
    elif number == 5:
        return "May"
    elif number == 6:
        return "June"
    elif number == 7:
        return "July"
    elif number == 8:
        return "August"
    elif number == 9:
        return "September"
    elif number == 10:
        return "October"
    elif number == 11:
        return "November"
    elif number == 12:
        return "December"

然后,我可以调用该函数。例如:

print (month_name (12))

输出:

>>> December

I created my own function converting numbers to their corresponding month.

def month_name (number):
    if number == 1:
        return "January"
    elif number == 2:
        return "February"
    elif number == 3:
        return "March"
    elif number == 4:
        return "April"
    elif number == 5:
        return "May"
    elif number == 6:
        return "June"
    elif number == 7:
        return "July"
    elif number == 8:
        return "August"
    elif number == 9:
        return "September"
    elif number == 10:
        return "October"
    elif number == 11:
        return "November"
    elif number == 12:
        return "December"

Then I can call the function. For example:

print (month_name (12))

Outputs:

>>> December

为什么datetime.datetime.utcnow()不包含时区信息?

问题:为什么datetime.datetime.utcnow()不包含时区信息?

datetime.datetime.utcnow()

datetime鉴于它明确是UTC,为什么没有任何时区信息datetime

我希望这将包含tzinfo

datetime.datetime.utcnow()

Why does this datetime not have any timezone info given that it is explicitly a UTC datetime?

I would expect that this would contain tzinfo.


回答 0

这意味着它是时区幼稚的,所以您不能将其与 datetime.astimezone

你可以给它一个时区

import pytz  # 3rd party: $ pip install pytz

u = datetime.utcnow()
u = u.replace(tzinfo=pytz.utc) #NOTE: it works only with a fixed utc offset

现在您可以更改时区

print(u.astimezone(pytz.timezone("America/New_York")))

要获取给定时区的当前时间,可以将tzinfo datetime.now()直接传递给:

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

print(datetime.now(pytz.timezone("America/New_York")))

它适用于任何时区,包括那些遵守夏令时(DST)的时区,即,它适用于在不同时间具有不同utc偏移量(非固定utc偏移量)的时区。请勿使用tz.localize(datetime.now())-如果当地时间不明确,则在DST结束过渡期间可能会失败。

That means it is timezone naive, so you can’t use it with datetime.astimezone

you can give it a timezone like this

import pytz  # 3rd party: $ pip install pytz

u = datetime.utcnow()
u = u.replace(tzinfo=pytz.utc) #NOTE: it works only with a fixed utc offset

now you can change timezones

print(u.astimezone(pytz.timezone("America/New_York")))

To get the current time in a given timezone, you could pass tzinfo to datetime.now() directly:

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

print(datetime.now(pytz.timezone("America/New_York")))

It works for any timezone including those that observe daylight saving time (DST) i.e., it works for timezones that may have different utc offsets at different times (non-fixed utc offset). Don’t use tz.localize(datetime.now()) — it may fail during end-of-DST transition when the local time is ambiguous.


回答 1

请注意,对于Python 3.2及更高版本,该datetime模块包含datetime.timezone。文档datetime.utcnow()说明:

可以通过调用获取当前的UTC日期时间。datetime.now(timezone.utc)

因此,您可以执行以下操作:

>>> import datetime
>>> datetime.datetime.now(datetime.timezone.utc)
datetime.datetime(2014, 7, 10, 2, 43, 55, 230107, tzinfo=datetime.timezone.utc)

Note that for Python 3.2 onwards, the datetime module contains datetime.timezone. The documentation for datetime.utcnow() says:

An aware current UTC datetime can be obtained by calling datetime.now(timezone.utc).

So, datetime.utcnow() doesn’t set tzinfo to indicate that it is UTC, but datetime.now(datetime.timezone.utc) does return UTC time with tzinfo set.

So you can do:

>>> import datetime
>>> datetime.datetime.now(datetime.timezone.utc)
datetime.datetime(2014, 7, 10, 2, 43, 55, 230107, tzinfo=datetime.timezone.utc)

回答 2

标准的Python库不包含任何tzinfo类(但请参见pep 431)。我只能猜测原因。我个人认为不为UTC包含tzinfo类是错误的,因为该类没有争议,可以进行标准实现。

编辑:尽管库中没有实现,但是在tzinfo文档中给出了一个示例。

from datetime import timedelta, tzinfo

ZERO = timedelta(0)

# A UTC class.

class UTC(tzinfo):
    """UTC"""

    def utcoffset(self, dt):
        return ZERO

    def tzname(self, dt):
        return "UTC"

    def dst(self, dt):
        return ZERO

utc = UTC()

要使用它,以将当前时间作为已知的datetime对象获取:

from datetime import datetime 

now = datetime.now(utc)

datetime.timezone.utc在Python 3.2+:

from datetime import datetime, timezone 

now = datetime.now(timezone.utc)

The standard Python libraries don’t include any tzinfo classes (but see pep 431). I can only guess at the reasons. Personally I think it was a mistake not to include a tzinfo class for UTC, because that one is uncontroversial enough to have a standard implementation.

Edit: Although there’s no implementation in the library, there is one given as an example in the tzinfo documentation.

from datetime import timedelta, tzinfo

ZERO = timedelta(0)

# A UTC class.

class UTC(tzinfo):
    """UTC"""

    def utcoffset(self, dt):
        return ZERO

    def tzname(self, dt):
        return "UTC"

    def dst(self, dt):
        return ZERO

utc = UTC()

To use it, to get the current time as an aware datetime object:

from datetime import datetime 

now = datetime.now(utc)

There is datetime.timezone.utc in Python 3.2+:

from datetime import datetime, timezone 

now = datetime.now(timezone.utc)

回答 3

pytz模块是一个选项,还有另一个选项,python-dateutil尽管它也是第三方软件包,但根据您的其他依赖项和操作系统,它可能已经可用。

我只是想将这种方法包括在内以供参考-如果您已经安装python-dateutil了其他方法,则可以使用它tzinfo而不是使用pytz

import datetime
import dateutil.tz

# Get the UTC time with datetime.now:
utcdt = datetime.datetime.now(dateutil.tz.tzutc())

# Get the UTC time with datetime.utcnow:
utcdt = datetime.datetime.utcnow()
utcdt = utcdt.replace(tzinfo=dateutil.tz.tzutc())

# For fun- get the local time
localdt = datetime.datetime.now(dateutil.tz.tzlocal())

我倾向于同意,调用utcnow应包含UTC时区信息。我怀疑这不包括在内,因为本机日期时间库默认为天真日期时间以实现交叉兼容性。

The pytz module is one option, and there is another python-dateutil, which although is also third party package, may already be available depending on your other dependencies and operating system.

I just wanted to include this methodology for reference- if you’ve already installed python-dateutil for other purposes, you can use its tzinfo instead of duplicating with pytz

import datetime
import dateutil.tz

# Get the UTC time with datetime.now:
utcdt = datetime.datetime.now(dateutil.tz.tzutc())

# Get the UTC time with datetime.utcnow:
utcdt = datetime.datetime.utcnow()
utcdt = utcdt.replace(tzinfo=dateutil.tz.tzutc())

# For fun- get the local time
localdt = datetime.datetime.now(dateutil.tz.tzlocal())

I tend to agree that calls to utcnow should include the UTC timezone information. I suspect that this is not included because the native datetime library defaults to naive datetimes for cross compatibility.


回答 4

朱利安•丹乔(Julien Danjou)写了一篇很好的文章,解释了为什么永远不要处理时区。摘录:

确实,Python datetime API总是返回不知道的datetime对象,这是非常不幸的。确实,一旦您获得此对象之一,就无法知道时区是什么,因此,这些对象本身就非常“无用”。

las,即使您可以使用utcnow(),也仍然看不到时区信息,就像您发现的那样。

建议:

  • 始终使用感知datetime对象,即带有时区信息。这样可以确保您可以直接比较它们(感知datetime 对象和未感知对象是不可比较的),并将它们正确返回给用户。利用pytz具有时区对象。

  • 使用ISO 8601作为输入和输出字符串格式。用于datetime.datetime.isoformat()将时间戳返回为使用该格式格式化的字符串,其中包括时区信息。

  • 如果您需要解析包含ISO 8601格式的时间戳记的字符串,则可以依靠iso8601,它返回带有正确时区信息的时间戳记。这使得时间戳直接可比。

Julien Danjou wrote a good article explaining why you should never deal with timezones. An excerpt:

Indeed, Python datetime API always returns unaware datetime objects, which is very unfortunate. Indeed, as soon as you get one of this object, there is no way to know what the timezone is, therefore these objects are pretty “useless” on their own.

Alas, even though you may use utcnow(), you still won’t see the timezone info, as you discovered.

Recommendations:

  • Always use aware datetime objects, i.e. with timezone information. That makes sure you can compare them directly (aware and unaware datetime objects are not comparable) and will return them correctly to users. Leverage pytz to have timezone objects.

  • Use ISO 8601 as the input and output string format. Use datetime.datetime.isoformat() to return timestamps as string formatted using that format, which includes the timezone information.

  • If you need to parse strings containing ISO 8601 formatted timestamps, you can rely on iso8601, which returns timestamps with correct timezone information. This makes timestamps directly comparable.


回答 5

timezone在Python 3.2+中添加信息

import datetime

>>> d = datetime.datetime.now(tz=datetime.timezone.utc)
>>> print(d.tzinfo)
'UTC+00:00'

To add timezone information in Python 3.2+

import datetime

>>> d = datetime.datetime.now(tz=datetime.timezone.utc)
>>> print(d.tzinfo)
'UTC+00:00'

回答 6

from datetime import datetime 
from dateutil.relativedelta import relativedelta
d = datetime.now()
date = datetime.isoformat(d).split('.')[0]
d_month = datetime.today() + relativedelta(months=1)
next_month = datetime.isoformat(d_month).split('.')[0]
from datetime import datetime 
from dateutil.relativedelta import relativedelta
d = datetime.now()
date = datetime.isoformat(d).split('.')[0]
d_month = datetime.today() + relativedelta(months=1)
next_month = datetime.isoformat(d_month).split('.')[0]

回答 7

由于UTC日期是UTC,因此不需要任何时区信息,根据定义,这意味着它们没有偏移量。

UTC dates don’t need any timezone info since they’re UTC, which by definition means that they have no offset.


仅在Python中将datetime对象转换为日期字符串

问题:仅在Python中将datetime对象转换为日期字符串

datetime在Python 中将日期字符串转换为对象时,我看到了很多东西,但是我想采用另一种方法。
我有

datetime.datetime(2012, 2, 23, 0, 0)

我想将其转换为类似的字符串'2/23/2012'

I see a lot on converting a date string to an datetime object in Python, but I want to go the other way.
I’ve got

datetime.datetime(2012, 2, 23, 0, 0)

and I would like to convert it to string like '2/23/2012'.


回答 0

您可以使用strftime来帮助您设置日期格式。

例如,

import datetime
t = datetime.datetime(2012, 2, 23, 0, 0)
t.strftime('%m/%d/%Y')

将生成:

'02/23/2012'

有关格式化的更多信息,请参见此处

You can use strftime to help you format your date.

E.g.,

import datetime
t = datetime.datetime(2012, 2, 23, 0, 0)
t.strftime('%m/%d/%Y')

will yield:

'02/23/2012'

More information about formatting see here


回答 1

datedatetime对象(以及对象time)都支持一种迷你语言来指定output,并且有两种访问它的方法:

  • 直接的方法调用:dt.strftime('format here'); 和
  • 新格式方法: '{:format here}'.format(dt)

因此,您的示例可能如下所示:

dt.strftime('%m/%d/%Y')

要么

'{:%m/%d/%Y}'.format(dt)

为了完整起见:您还可以直接访问对象的属性,但随后只能获取数字:

'%s/%s/%s' % (dt.month, dt.day, dt.year)

学习迷你语言所花的时间是值得的。


作为参考,以下是迷你语言中使用的代码:

  • %a 工作日为语言环境的缩写名称。
  • %A 工作日为语言环境的全名。
  • %w 以十进制数表示的工作日,其中0是星期日,6是星期六。
  • %d 以零填充的十进制数字表示月份中的一天。
  • %b 月作为语言环境的缩写名称。
  • %B 月作为语言环境的全名。
  • %m 以零填充的十进制数字表示的月份。01,…,12
  • %y 无世纪的年份,为零填充的十进制数字。00,…,99
  • %Y 以世纪作为十进制数字的年份。1970、1988、2001、2013
  • %H 小时(24小时制),为补零的十进制数字。00,…,23
  • %I 小时(12小时制),为零填充的十进制数字。01,…,12
  • %p 相当于AM或PM的语言环境。
  • %M 分钟,为零填充的十进制数字。00,…,59
  • %S 第二个为零填充的十进制数。00,…,59
  • %f 微秒,十进制数字,在左侧补零。000000,…,999999
  • %z UTC偏移量,格式为+ HHMM或-HHMM(如果为天真则为空),+ 0000,-0400,+ 1030
  • %Z 时区名称(如果是天真则为空),UTC,EST,CST
  • %j 一年中的一天,为零填充的十进制数字。001,…,366
  • %U 一年中的星期号(星期日是第一个),以零填充的十进制数表示。
  • %W 一年中的星期数(星期一为第一位),以十进制数表示。
  • %c 语言环境的适当日期和时间表示。
  • %x 语言环境的适当日期表示形式。
  • %X 语言环境的适当时间表示形式。
  • %% 文字“%”字符。

date and datetime objects (and time as well) support a mini-language to specify output, and there are two ways to access it:

  • direct method call: dt.strftime('format here'); and
  • new format method: '{:format here}'.format(dt)

So your example could look like:

dt.strftime('%m/%d/%Y')

or

'{:%m/%d/%Y}'.format(dt)

For completeness’ sake: you can also directly access the attributes of the object, but then you only get the numbers:

'%s/%s/%s' % (dt.month, dt.day, dt.year)

The time taken to learn the mini-language is worth it.


For reference, here are the codes used in the mini-language:

  • %a Weekday as locale’s abbreviated name.
  • %A Weekday as locale’s full name.
  • %w Weekday as a decimal number, where 0 is Sunday and 6 is Saturday.
  • %d Day of the month as a zero-padded decimal number.
  • %b Month as locale’s abbreviated name.
  • %B Month as locale’s full name.
  • %m Month as a zero-padded decimal number. 01, …, 12
  • %y Year without century as a zero-padded decimal number. 00, …, 99
  • %Y Year with century as a decimal number. 1970, 1988, 2001, 2013
  • %H Hour (24-hour clock) as a zero-padded decimal number. 00, …, 23
  • %I Hour (12-hour clock) as a zero-padded decimal number. 01, …, 12
  • %p Locale’s equivalent of either AM or PM.
  • %M Minute as a zero-padded decimal number. 00, …, 59
  • %S Second as a zero-padded decimal number. 00, …, 59
  • %f Microsecond as a decimal number, zero-padded on the left. 000000, …, 999999
  • %z UTC offset in the form +HHMM or -HHMM (empty if naive), +0000, -0400, +1030
  • %Z Time zone name (empty if naive), UTC, EST, CST
  • %j Day of the year as a zero-padded decimal number. 001, …, 366
  • %U Week number of the year (Sunday is the first) as a zero padded decimal number.
  • %W Week number of the year (Monday is first) as a decimal number.
  • %c Locale’s appropriate date and time representation.
  • %x Locale’s appropriate date representation.
  • %X Locale’s appropriate time representation.
  • %% A literal ‘%’ character.

回答 2

另外一个选项:

import datetime
now=datetime.datetime.now()
now.isoformat()
# ouptut --> '2016-03-09T08:18:20.860968'

Another option:

import datetime
now=datetime.datetime.now()
now.isoformat()
# ouptut --> '2016-03-09T08:18:20.860968'

回答 3

您可以使用简单的字符串格式化方法:

>>> dt = datetime.datetime(2012, 2, 23, 0, 0)
>>> '{0.month}/{0.day}/{0.year}'.format(dt)
'2/23/2012'
>>> '%s/%s/%s' % (dt.month, dt.day, dt.year)
'2/23/2012'

You could use simple string formatting methods:

>>> dt = datetime.datetime(2012, 2, 23, 0, 0)
>>> '{0.month}/{0.day}/{0.year}'.format(dt)
'2/23/2012'
>>> '%s/%s/%s' % (dt.month, dt.day, dt.year)
'2/23/2012'

回答 4

type-specific formatting 也可以使用:

t = datetime.datetime(2012, 2, 23, 0, 0)
"{:%m/%d/%Y}".format(t)

输出:

'02/23/2012'

type-specific formatting can be used as well:

t = datetime.datetime(2012, 2, 23, 0, 0)
"{:%m/%d/%Y}".format(t)

Output:

'02/23/2012'

回答 5

如果您正在寻找一种简单的方式来datetime进行字符串转换并可以省略格式。您可以将datetime对象转换为str,然后使用数组切片。

In [1]: from datetime import datetime

In [2]: now = datetime.now()

In [3]: str(now)
Out[3]: '2019-04-26 18:03:50.941332'

In [5]: str(now)[:10]
Out[5]: '2019-04-26'

In [6]: str(now)[:19]
Out[6]: '2019-04-26 18:03:50'

但是请注意以下几点。如果在这种情况下,AttributeError当其他解决方案上升时,None您将收到一个'None'字符串。

In [9]: str(None)[:19]
Out[9]: 'None'

If you looking for a simple way of datetime to string conversion and can omit the format. You can convert datetime object to str and then use array slicing.

In [1]: from datetime import datetime

In [2]: now = datetime.now()

In [3]: str(now)
Out[3]: '2019-04-26 18:03:50.941332'

In [5]: str(now)[:10]
Out[5]: '2019-04-26'

In [6]: str(now)[:19]
Out[6]: '2019-04-26 18:03:50'

But note the following thing. If other solutions will rise an AttributeError when the variable is None in this case you will receive a 'None' string.

In [9]: str(None)[:19]
Out[9]: 'None'

回答 6

通过直接使用日期时间对象的组件,可以将日期时间对象转换为字符串。

from datetime import date  

myDate = date.today()    
#print(myDate) would output 2017-05-23 because that is today
#reassign the myDate variable to myDate = myDate.month 
#then you could print(myDate.month) and you would get 5 as an integer
dateStr = str(myDate.month)+ "/" + str(myDate.day) + "/" + str(myDate.year)    
# myDate.month is equal to 5 as an integer, i use str() to change it to a 
# string I add(+)the "/" so now I have "5/" then myDate.day is 23 as
# an integer i change it to a string with str() and it is added to the "5/"   
# to get "5/23" and then I add another "/" now we have "5/23/" next is the 
# year which is 2017 as an integer, I use the function str() to change it to 
# a string and add it to the rest of the string.  Now we have "5/23/2017" as 
# a string. The final line prints the string.

print(dateStr)  

输出-> 5/23/2017

It is possible to convert a datetime object into a string by working directly with the components of the datetime object.

from datetime import date  

myDate = date.today()    
#print(myDate) would output 2017-05-23 because that is today
#reassign the myDate variable to myDate = myDate.month 
#then you could print(myDate.month) and you would get 5 as an integer
dateStr = str(myDate.month)+ "/" + str(myDate.day) + "/" + str(myDate.year)    
# myDate.month is equal to 5 as an integer, i use str() to change it to a 
# string I add(+)the "/" so now I have "5/" then myDate.day is 23 as
# an integer i change it to a string with str() and it is added to the "5/"   
# to get "5/23" and then I add another "/" now we have "5/23/" next is the 
# year which is 2017 as an integer, I use the function str() to change it to 
# a string and add it to the rest of the string.  Now we have "5/23/2017" as 
# a string. The final line prints the string.

print(dateStr)  

Output –> 5/23/2017


回答 7

您可以将日期时间转换为字符串。

published_at = "{}".format(self.published_at)

You can convert datetime to string.

published_at = "{}".format(self.published_at)

回答 8

字符串连接str.join可以用来构建字符串。

d = datetime.now()
'/'.join(str(x) for x in (d.month, d.day, d.year))
'3/7/2016'

String concatenation, str.join, can be used to build the string.

d = datetime.now()
'/'.join(str(x) for x in (d.month, d.day, d.year))
'3/7/2016'

回答 9

如果您还需要时间,请选择

datetime.datetime.now().__str__()

2019-07-11 19:36:31.118766在控制台中为我打印

If you want the time as well, just go with

datetime.datetime.now().__str__()

Prints 2019-07-11 19:36:31.118766 in console for me


将timedelta格式化为字符串

问题:将timedelta格式化为字符串

我在格式化datetime.timedelta对象时遇到问题。

这是我要执行的操作:我有一个对象列表,并且该对象类的成员之一是timedelta对象,该对象显示事件的持续时间。我想以小时:分钟的格式显示该持续时间。

我尝试了多种方法来执行此操作,但遇到了困难。我当前的方法是为返回小时和分钟的对象添加方法。我可以将timedelta.seconds除以3600并四舍五入来获得小时数。我在获取剩余秒数并将其转换为分钟时遇到麻烦。

顺便说一句,我将Google AppEngine与Django模板结合使用进行演示。

I’m having trouble formatting a datetime.timedelta object.

Here’s what I’m trying to do: I have a list of objects and one of the members of the class of the object is a timedelta object that shows the duration of an event. I would like to display that duration in the format of hours:minutes.

I have tried a variety of methods for doing this and I’m having difficulty. My current approach is to add methods to the class for my objects that return hours and minutes. I can get the hours by dividing the timedelta.seconds by 3600 and rounding it. I’m having trouble with getting the remainder seconds and converting that to minutes.

By the way, I’m using Google AppEngine with Django Templates for presentation.


回答 0

您可以使用str()将timedelta转换为字符串。这是一个例子:

import datetime
start = datetime.datetime(2009,2,10,14,00)
end   = datetime.datetime(2009,2,10,16,00)
delta = end-start
print(str(delta))
# prints 2:00:00

You can just convert the timedelta to a string with str(). Here’s an example:

import datetime
start = datetime.datetime(2009,2,10,14,00)
end   = datetime.datetime(2009,2,10,16,00)
delta = end-start
print(str(delta))
# prints 2:00:00

回答 1

如您所知,您可以通过访问.seconds属性从timedelta对象获取total_seconds 。

Python提供了内置函数divmod(),该函数允许:

s = 13420
hours, remainder = divmod(s, 3600)
minutes, seconds = divmod(remainder, 60)
print '{:02}:{:02}:{:02}'.format(int(hours), int(minutes), int(seconds))
# result: 03:43:40

或者您可以将模和减相结合,转换为小时和余数:

# arbitrary number of seconds
s = 13420
# hours
hours = s // 3600 
# remaining seconds
s = s - (hours * 3600)
# minutes
minutes = s // 60
# remaining seconds
seconds = s - (minutes * 60)
# total time
print '{:02}:{:02}:{:02}'.format(int(hours), int(minutes), int(seconds))
# result: 03:43:40

As you know, you can get the total_seconds from a timedelta object by accessing the .seconds attribute.

Python provides the builtin function divmod() which allows for:

s = 13420
hours, remainder = divmod(s, 3600)
minutes, seconds = divmod(remainder, 60)
print '{:02}:{:02}:{:02}'.format(int(hours), int(minutes), int(seconds))
# result: 03:43:40

or you can convert to hours and remainder by using a combination of modulo and subtraction:

# arbitrary number of seconds
s = 13420
# hours
hours = s // 3600 
# remaining seconds
s = s - (hours * 3600)
# minutes
minutes = s // 60
# remaining seconds
seconds = s - (minutes * 60)
# total time
print '{:02}:{:02}:{:02}'.format(int(hours), int(minutes), int(seconds))
# result: 03:43:40

回答 2

>>> str(datetime.timedelta(hours=10.56))
10:33:36

>>> td = datetime.timedelta(hours=10.505) # any timedelta object
>>> ':'.join(str(td).split(':')[:2])
10:30

如果我们简单地输入,将timedelta对象传递给str()函数将调用相同的格式代码print td。由于您不需要秒数,因此我们可以用冒号(3个部分)分割字符串,然后仅将前2个部分放回去。

>>> str(datetime.timedelta(hours=10.56))
10:33:36

>>> td = datetime.timedelta(hours=10.505) # any timedelta object
>>> ':'.join(str(td).split(':')[:2])
10:30

Passing the timedelta object to the str() function calls the same formatting code used if we simply type print td. Since you don’t want the seconds, we can split the string by colons (3 parts) and put it back together with only the first 2 parts.


回答 3

def td_format(td_object):
    seconds = int(td_object.total_seconds())
    periods = [
        ('year',        60*60*24*365),
        ('month',       60*60*24*30),
        ('day',         60*60*24),
        ('hour',        60*60),
        ('minute',      60),
        ('second',      1)
    ]

    strings=[]
    for period_name, period_seconds in periods:
        if seconds > period_seconds:
            period_value , seconds = divmod(seconds, period_seconds)
            has_s = 's' if period_value > 1 else ''
            strings.append("%s %s%s" % (period_value, period_name, has_s))

    return ", ".join(strings)
def td_format(td_object):
    seconds = int(td_object.total_seconds())
    periods = [
        ('year',        60*60*24*365),
        ('month',       60*60*24*30),
        ('day',         60*60*24),
        ('hour',        60*60),
        ('minute',      60),
        ('second',      1)
    ]

    strings=[]
    for period_name, period_seconds in periods:
        if seconds > period_seconds:
            period_value , seconds = divmod(seconds, period_seconds)
            has_s = 's' if period_value > 1 else ''
            strings.append("%s %s%s" % (period_value, period_name, has_s))

    return ", ".join(strings)

回答 4

我个人使用该humanize库:

>>> import datetime
>>> humanize.naturalday(datetime.datetime.now())
'today'
>>> humanize.naturalday(datetime.datetime.now() - datetime.timedelta(days=1))
'yesterday'
>>> humanize.naturalday(datetime.date(2007, 6, 5))
'Jun 05'
>>> humanize.naturaldate(datetime.date(2007, 6, 5))
'Jun 05 2007'
>>> humanize.naturaltime(datetime.datetime.now() - datetime.timedelta(seconds=1))
'a second ago'
>>> humanize.naturaltime(datetime.datetime.now() - datetime.timedelta(seconds=3600))
'an hour ago'

当然,它并不能完全给您为您的答案(的确是,str(timeA - timeB)但是我发现,一旦您超过几个小时,显示就会迅速变得不可读。humanize它支持更大的值易于阅读,并且位置很好。

contrib.humanize显然,它是受Django 模块启发的,因此,由于您使用的是Django,您应该使用它。

I personally use the humanize library for this:

>>> import datetime
>>> humanize.naturalday(datetime.datetime.now())
'today'
>>> humanize.naturalday(datetime.datetime.now() - datetime.timedelta(days=1))
'yesterday'
>>> humanize.naturalday(datetime.date(2007, 6, 5))
'Jun 05'
>>> humanize.naturaldate(datetime.date(2007, 6, 5))
'Jun 05 2007'
>>> humanize.naturaltime(datetime.datetime.now() - datetime.timedelta(seconds=1))
'a second ago'
>>> humanize.naturaltime(datetime.datetime.now() - datetime.timedelta(seconds=3600))
'an hour ago'

Of course, it doesn’t give you exactly the answer you were looking for (which is, indeed, str(timeA - timeB), but I have found that once you go beyond a few hours, the display becomes quickly unreadable. humanize has support for much larger values that are human-readable, and is also well localized.

It’s inspired by Django’s contrib.humanize module, apparently, so since you are using Django, you should probably use that.


回答 5

他已经有一个timedelta对象,所以为什么不使用其内置方法total_seconds()将其转换为秒,然后使用divmod()获得小时和分钟呢?

hours, remainder = divmod(myTimeDelta.total_seconds(), 3600)
minutes, seconds = divmod(remainder, 60)

# Formatted only for hours and minutes as requested
print '%s:%s' % (hours, minutes)

无论时间增量是偶数天还是数年,这都有效。

He already has a timedelta object so why not use its built-in method total_seconds() to convert it to seconds, then use divmod() to get hours and minutes?

hours, remainder = divmod(myTimeDelta.total_seconds(), 3600)
minutes, seconds = divmod(remainder, 60)

# Formatted only for hours and minutes as requested
print '%s:%s' % (hours, minutes)

This works regardless if the time delta has even days or years.


回答 6

这是一个通用函数,用于将timedelta对象或常规数字(以秒或分钟等形式)转换为格式正确的字符串。我对一个重复的问题做了mpounsett的出色回答,使其更加灵活,可读性更高,并增加了文档。

您会发现,到目前为止,这是最灵活的答案,因为它可以使您:

  1. 即时自定义字符串格式,而不是对其进行硬编码。
  2. 留出一定的时间间隔没有问题(请参见下面的示例)。

功能:

from string import Formatter
from datetime import timedelta

def strfdelta(tdelta, fmt='{D:02}d {H:02}h {M:02}m {S:02}s', inputtype='timedelta'):
    """Convert a datetime.timedelta object or a regular number to a custom-
    formatted string, just like the stftime() method does for datetime.datetime
    objects.

    The fmt argument allows custom formatting to be specified.  Fields can 
    include seconds, minutes, hours, days, and weeks.  Each field is optional.

    Some examples:
        '{D:02}d {H:02}h {M:02}m {S:02}s' --> '05d 08h 04m 02s' (default)
        '{W}w {D}d {H}:{M:02}:{S:02}'     --> '4w 5d 8:04:02'
        '{D:2}d {H:2}:{M:02}:{S:02}'      --> ' 5d  8:04:02'
        '{H}h {S}s'                       --> '72h 800s'

    The inputtype argument allows tdelta to be a regular number instead of the  
    default, which is a datetime.timedelta object.  Valid inputtype strings: 
        's', 'seconds', 
        'm', 'minutes', 
        'h', 'hours', 
        'd', 'days', 
        'w', 'weeks'
    """

    # Convert tdelta to integer seconds.
    if inputtype == 'timedelta':
        remainder = int(tdelta.total_seconds())
    elif inputtype in ['s', 'seconds']:
        remainder = int(tdelta)
    elif inputtype in ['m', 'minutes']:
        remainder = int(tdelta)*60
    elif inputtype in ['h', 'hours']:
        remainder = int(tdelta)*3600
    elif inputtype in ['d', 'days']:
        remainder = int(tdelta)*86400
    elif inputtype in ['w', 'weeks']:
        remainder = int(tdelta)*604800

    f = Formatter()
    desired_fields = [field_tuple[1] for field_tuple in f.parse(fmt)]
    possible_fields = ('W', 'D', 'H', 'M', 'S')
    constants = {'W': 604800, 'D': 86400, 'H': 3600, 'M': 60, 'S': 1}
    values = {}
    for field in possible_fields:
        if field in desired_fields and field in constants:
            values[field], remainder = divmod(remainder, constants[field])
    return f.format(fmt, **values)

演示:

>>> td = timedelta(days=2, hours=3, minutes=5, seconds=8, microseconds=340)

>>> print strfdelta(td)
02d 03h 05m 08s

>>> print strfdelta(td, '{D}d {H}:{M:02}:{S:02}')
2d 3:05:08

>>> print strfdelta(td, '{D:2}d {H:2}:{M:02}:{S:02}')
 2d  3:05:08

>>> print strfdelta(td, '{H}h {S}s')
51h 308s

>>> print strfdelta(12304, inputtype='s')
00d 03h 25m 04s

>>> print strfdelta(620, '{H}:{M:02}', 'm')
10:20

>>> print strfdelta(49, '{D}d {H}h', 'h')
2d 1h

Here is a general purpose function for converting either a timedelta object or a regular number (in the form of seconds or minutes, etc.) to a nicely formatted string. I took mpounsett’s fantastic answer on a duplicate question, made it a bit more flexible, improved readibility, and added documentation.

You will find that it is the most flexible answer here so far since it allows you to:

  1. Customize the string format on the fly instead of it being hard-coded.
  2. Leave out certain time intervals without a problem (see examples below).

Function:

from string import Formatter
from datetime import timedelta

def strfdelta(tdelta, fmt='{D:02}d {H:02}h {M:02}m {S:02}s', inputtype='timedelta'):
    """Convert a datetime.timedelta object or a regular number to a custom-
    formatted string, just like the stftime() method does for datetime.datetime
    objects.

    The fmt argument allows custom formatting to be specified.  Fields can 
    include seconds, minutes, hours, days, and weeks.  Each field is optional.

    Some examples:
        '{D:02}d {H:02}h {M:02}m {S:02}s' --> '05d 08h 04m 02s' (default)
        '{W}w {D}d {H}:{M:02}:{S:02}'     --> '4w 5d 8:04:02'
        '{D:2}d {H:2}:{M:02}:{S:02}'      --> ' 5d  8:04:02'
        '{H}h {S}s'                       --> '72h 800s'

    The inputtype argument allows tdelta to be a regular number instead of the  
    default, which is a datetime.timedelta object.  Valid inputtype strings: 
        's', 'seconds', 
        'm', 'minutes', 
        'h', 'hours', 
        'd', 'days', 
        'w', 'weeks'
    """

    # Convert tdelta to integer seconds.
    if inputtype == 'timedelta':
        remainder = int(tdelta.total_seconds())
    elif inputtype in ['s', 'seconds']:
        remainder = int(tdelta)
    elif inputtype in ['m', 'minutes']:
        remainder = int(tdelta)*60
    elif inputtype in ['h', 'hours']:
        remainder = int(tdelta)*3600
    elif inputtype in ['d', 'days']:
        remainder = int(tdelta)*86400
    elif inputtype in ['w', 'weeks']:
        remainder = int(tdelta)*604800

    f = Formatter()
    desired_fields = [field_tuple[1] for field_tuple in f.parse(fmt)]
    possible_fields = ('W', 'D', 'H', 'M', 'S')
    constants = {'W': 604800, 'D': 86400, 'H': 3600, 'M': 60, 'S': 1}
    values = {}
    for field in possible_fields:
        if field in desired_fields and field in constants:
            values[field], remainder = divmod(remainder, constants[field])
    return f.format(fmt, **values)

Demo:

>>> td = timedelta(days=2, hours=3, minutes=5, seconds=8, microseconds=340)

>>> print strfdelta(td)
02d 03h 05m 08s

>>> print strfdelta(td, '{D}d {H}:{M:02}:{S:02}')
2d 3:05:08

>>> print strfdelta(td, '{D:2}d {H:2}:{M:02}:{S:02}')
 2d  3:05:08

>>> print strfdelta(td, '{H}h {S}s')
51h 308s

>>> print strfdelta(12304, inputtype='s')
00d 03h 25m 04s

>>> print strfdelta(620, '{H}:{M:02}', 'm')
10:20

>>> print strfdelta(49, '{D}d {H}h', 'h')
2d 1h

回答 7

我知道这是一个古老的已回答问题,但我datetime.utcfromtimestamp()为此使用了。它需要秒数并返回datetime可以像其他格式一样设置的datetime

duration = datetime.utcfromtimestamp(end - begin)
print duration.strftime('%H:%M')

只要您停留在合法的时间范围内,它就应该起作用,即,当小时数小于等于23时,它不会返回1234:35。

I know that this is an old answered question, but I use datetime.utcfromtimestamp() for this. It takes the number of seconds and returns a datetime that can be formatted like any other datetime.

duration = datetime.utcfromtimestamp(end - begin)
print duration.strftime('%H:%M')

As long as you stay in the legal ranges for the time parts this should work, i.e. it doesn’t return 1234:35 as hours are <= 23.


回答 8

发问者想要比典型的更好的格式:

  >>> import datetime
  >>> datetime.timedelta(seconds=41000)
  datetime.timedelta(0, 41000)
  >>> str(datetime.timedelta(seconds=41000))
  '11:23:20'
  >>> str(datetime.timedelta(seconds=4102.33))
  '1:08:22.330000'
  >>> str(datetime.timedelta(seconds=413302.33))
  '4 days, 18:48:22.330000'

因此,实际上有两种格式,一种格式的天数为0,而被忽略,另一种格式的文本为“ n days,h:m:s”。但是,秒可能会有分数,并且打印输出中没有前导零,所以列很乱。

如果您喜欢,这是我的日常工作:

def printNiceTimeDelta(stime, etime):
    delay = datetime.timedelta(seconds=(etime - stime))
    if (delay.days > 0):
        out = str(delay).replace(" days, ", ":")
    else:
        out = "0:" + str(delay)
    outAr = out.split(':')
    outAr = ["%02d" % (int(float(x))) for x in outAr]
    out   = ":".join(outAr)
    return out

这将以dd:hh:mm:ss格式返回输出:

00:00:00:15
00:00:00:19
02:01:31:40
02:01:32:22

我确实考虑过要增加几年,但这留给读者练习,因为输出在1年以上是安全的:

>>> str(datetime.timedelta(seconds=99999999))
'1157 days, 9:46:39'

Questioner wants a nicer format than the typical:

  >>> import datetime
  >>> datetime.timedelta(seconds=41000)
  datetime.timedelta(0, 41000)
  >>> str(datetime.timedelta(seconds=41000))
  '11:23:20'
  >>> str(datetime.timedelta(seconds=4102.33))
  '1:08:22.330000'
  >>> str(datetime.timedelta(seconds=413302.33))
  '4 days, 18:48:22.330000'

So, really there’s two formats, one where days are 0 and it’s left out, and another where there’s text “n days, h:m:s”. But, the seconds may have fractions, and there’s no leading zeroes in the printouts, so columns are messy.

Here’s my routine, if you like it:

def printNiceTimeDelta(stime, etime):
    delay = datetime.timedelta(seconds=(etime - stime))
    if (delay.days > 0):
        out = str(delay).replace(" days, ", ":")
    else:
        out = "0:" + str(delay)
    outAr = out.split(':')
    outAr = ["%02d" % (int(float(x))) for x in outAr]
    out   = ":".join(outAr)
    return out

this returns output as dd:hh:mm:ss format:

00:00:00:15
00:00:00:19
02:01:31:40
02:01:32:22

I did think about adding years to this, but this is left as an exercise for the reader, since the output is safe at over 1 year:

>>> str(datetime.timedelta(seconds=99999999))
'1157 days, 9:46:39'

回答 9

我会在这里认真考虑Occam的Razor方法:

td = str(timedelta).split('.')[0]

这将返回不带微秒的字符串

如果要重新生成datetime.timedelta对象,请执行以下操作:

h,m,s = re.split(':', td)
new_delta = datetime.timedelta(hours=int(h),minutes=int(m),seconds=int(s))

2年过去了,我喜欢这种语言!

I would seriously consider the Occam’s Razor approach here:

td = str(timedelta).split('.')[0]

This returns a string without the microseconds

If you want to regenerate the datetime.timedelta object, just do this:

h,m,s = re.split(':', td)
new_delta = datetime.timedelta(hours=int(h),minutes=int(m),seconds=int(s))

2 years in, I love this language!


回答 10

我的datetime.timedelta物品超过一天。因此,这是另一个问题。以上所有讨论都假设不到一天。A timedelta实际上是天,秒和微秒的元组。上面的讨论应该使用td.seconds像joe一样,但是如果您有工作日,则它不包括在seconds值中。

我得到了2个日期时间与打印天数和小时之间的时间跨度。

span = currentdt - previousdt
print '%d,%d\n' % (span.days,span.seconds/3600)

My datetime.timedelta objects went greater than a day. So here is a further problem. All the discussion above assumes less than a day. A timedelta is actually a tuple of days, seconds and microseconds. The above discussion should use td.seconds as joe did, but if you have days it is NOT included in the seconds value.

I am getting a span of time between 2 datetimes and printing days and hours.

span = currentdt - previousdt
print '%d,%d\n' % (span.days,span.seconds/3600)

回答 11

我使用humanfriendlypython库来做到这一点,它工作得很好。

import humanfriendly
from datetime import timedelta
delta = timedelta(seconds = 321)
humanfriendly.format_timespan(delta)

'5 minutes and 21 seconds'

可在https://pypi.org/project/humanfriendly/

I used the humanfriendly python library to do this, it works very well.

import humanfriendly
from datetime import timedelta
delta = timedelta(seconds = 321)
humanfriendly.format_timespan(delta)

'5 minutes and 21 seconds'

Available at https://pypi.org/project/humanfriendly/


回答 12

遵循上面Joe的示例值,因此,我将使用模数算术运算符:

td = datetime.timedelta(hours=10.56)
td_str = "%d:%d" % (td.seconds/3600, td.seconds%3600/60)

注意,Python中的整数除法默认舍入;如果要更明确,请适当使用math.floor()或math.ceil()。

Following Joe’s example value above, I’d use the modulus arithmetic operator, thusly:

td = datetime.timedelta(hours=10.56)
td_str = "%d:%d" % (td.seconds/3600, td.seconds%3600/60)

Note that integer division in Python rounds down by default; if you want to be more explicit, use math.floor() or math.ceil() as appropriate.


回答 13

def seconds_to_time_left_string(total_seconds):
    s = int(total_seconds)
    years = s // 31104000
    if years > 1:
        return '%d years' % years
    s = s - (years * 31104000)
    months = s // 2592000
    if years == 1:
        r = 'one year'
        if months > 0:
            r += ' and %d months' % months
        return r
    if months > 1:
        return '%d months' % months
    s = s - (months * 2592000)
    days = s // 86400
    if months == 1:
        r = 'one month'
        if days > 0:
            r += ' and %d days' % days
        return r
    if days > 1:
        return '%d days' % days
    s = s - (days * 86400)
    hours = s // 3600
    if days == 1:
        r = 'one day'
        if hours > 0:
            r += ' and %d hours' % hours
        return r 
    s = s - (hours * 3600)
    minutes = s // 60
    seconds = s - (minutes * 60)
    if hours >= 6:
        return '%d hours' % hours
    if hours >= 1:
        r = '%d hours' % hours
        if hours == 1:
            r = 'one hour'
        if minutes > 0:
            r += ' and %d minutes' % minutes
        return r
    if minutes == 1:
        r = 'one minute'
        if seconds > 0:
            r += ' and %d seconds' % seconds
        return r
    if minutes == 0:
        return '%d seconds' % seconds
    if seconds == 0:
        return '%d minutes' % minutes
    return '%d minutes and %d seconds' % (minutes, seconds)

for i in range(10):
    print pow(8, i), seconds_to_time_left_string(pow(8, i))


Output:
1 1 seconds
8 8 seconds
64 one minute and 4 seconds
512 8 minutes and 32 seconds
4096 one hour and 8 minutes
32768 9 hours
262144 3 days
2097152 24 days
16777216 6 months
134217728 4 years
def seconds_to_time_left_string(total_seconds):
    s = int(total_seconds)
    years = s // 31104000
    if years > 1:
        return '%d years' % years
    s = s - (years * 31104000)
    months = s // 2592000
    if years == 1:
        r = 'one year'
        if months > 0:
            r += ' and %d months' % months
        return r
    if months > 1:
        return '%d months' % months
    s = s - (months * 2592000)
    days = s // 86400
    if months == 1:
        r = 'one month'
        if days > 0:
            r += ' and %d days' % days
        return r
    if days > 1:
        return '%d days' % days
    s = s - (days * 86400)
    hours = s // 3600
    if days == 1:
        r = 'one day'
        if hours > 0:
            r += ' and %d hours' % hours
        return r 
    s = s - (hours * 3600)
    minutes = s // 60
    seconds = s - (minutes * 60)
    if hours >= 6:
        return '%d hours' % hours
    if hours >= 1:
        r = '%d hours' % hours
        if hours == 1:
            r = 'one hour'
        if minutes > 0:
            r += ' and %d minutes' % minutes
        return r
    if minutes == 1:
        r = 'one minute'
        if seconds > 0:
            r += ' and %d seconds' % seconds
        return r
    if minutes == 0:
        return '%d seconds' % seconds
    if seconds == 0:
        return '%d minutes' % minutes
    return '%d minutes and %d seconds' % (minutes, seconds)

for i in range(10):
    print pow(8, i), seconds_to_time_left_string(pow(8, i))


Output:
1 1 seconds
8 8 seconds
64 one minute and 4 seconds
512 8 minutes and 32 seconds
4096 one hour and 8 minutes
32768 9 hours
262144 3 days
2097152 24 days
16777216 6 months
134217728 4 years

回答 14

我在工作中加班计算的输出也有类似的问题。该值应始终以HH:MM显示,即使该值大于一天并且该值可能会变为负数。我合并了一些所示的解决方案,也许其他人认为此解决方案很有用。我意识到,如果timedelta值为负,则大多数使用divmod方法显示的解决方案都无法立即使用:

def td2HHMMstr(td):
  '''Convert timedelta objects to a HH:MM string with (+/-) sign'''
  if td < datetime.timedelta(seconds=0):
    sign='-'
    td = -td
  else:
    sign = ''
  tdhours, rem = divmod(td.total_seconds(), 3600)
  tdminutes, rem = divmod(rem, 60)
  tdstr = '{}{:}:{:02d}'.format(sign, int(tdhours), int(tdminutes))
  return tdstr

timedelta到HH:MM字符串:

td2HHMMstr(datetime.timedelta(hours=1, minutes=45))
'1:54'

td2HHMMstr(datetime.timedelta(days=2, hours=3, minutes=2))
'51:02'

td2HHMMstr(datetime.timedelta(hours=-3, minutes=-2))
'-3:02'

td2HHMMstr(datetime.timedelta(days=-35, hours=-3, minutes=-2))
'-843:02'

I had a similar problem with the output of overtime calculation at work. The value should always show up in HH:MM, even when it is greater than one day and the value can get negative. I combined some of the shown solutions and maybe someone else find this solution useful. I realized that if the timedelta value is negative most of the shown solutions with the divmod method doesn’t work out of the box:

def td2HHMMstr(td):
  '''Convert timedelta objects to a HH:MM string with (+/-) sign'''
  if td < datetime.timedelta(seconds=0):
    sign='-'
    td = -td
  else:
    sign = ''
  tdhours, rem = divmod(td.total_seconds(), 3600)
  tdminutes, rem = divmod(rem, 60)
  tdstr = '{}{:}:{:02d}'.format(sign, int(tdhours), int(tdminutes))
  return tdstr

timedelta to HH:MM string:

td2HHMMstr(datetime.timedelta(hours=1, minutes=45))
'1:54'

td2HHMMstr(datetime.timedelta(days=2, hours=3, minutes=2))
'51:02'

td2HHMMstr(datetime.timedelta(hours=-3, minutes=-2))
'-3:02'

td2HHMMstr(datetime.timedelta(days=-35, hours=-3, minutes=-2))
'-843:02'

回答 15

import datetime
hours = datetime.timedelta(hours=16, minutes=30)
print((datetime.datetime(1,1,1) + hours).strftime('%H:%M'))
import datetime
hours = datetime.timedelta(hours=16, minutes=30)
print((datetime.datetime(1,1,1) + hours).strftime('%H:%M'))

回答 16

直接解决此问题的模板过滤器。内置函数int()从不舍入。F字符串(即f”)需要python 3.6。

@app_template_filter()
def diffTime(end, start):
    diff = (end - start).total_seconds()
    d = int(diff / 86400)
    h = int((diff - (d * 86400)) / 3600)
    m = int((diff - (d * 86400 + h * 3600)) / 60)
    s = int((diff - (d * 86400 + h * 3600 + m *60)))
    if d > 0:
        fdiff = f'{d}d {h}h {m}m {s}s'
    elif h > 0:
        fdiff = f'{h}h {m}m {s}s'
    elif m > 0:
        fdiff = f'{m}m {s}s'
    else:
        fdiff = f'{s}s'
    return fdiff

A straight forward template filter for this problem. The built-in function int() never rounds up. F-Strings (i.e. f”) require python 3.6.

@app_template_filter()
def diffTime(end, start):
    diff = (end - start).total_seconds()
    d = int(diff / 86400)
    h = int((diff - (d * 86400)) / 3600)
    m = int((diff - (d * 86400 + h * 3600)) / 60)
    s = int((diff - (d * 86400 + h * 3600 + m *60)))
    if d > 0:
        fdiff = f'{d}d {h}h {m}m {s}s'
    elif h > 0:
        fdiff = f'{h}h {m}m {s}s'
    elif m > 0:
        fdiff = f'{m}m {s}s'
    else:
        fdiff = f'{s}s'
    return fdiff

回答 17

from django.utils.translation import ngettext

def localize_timedelta(delta):
    ret = []
    num_years = int(delta.days / 365)
    if num_years > 0:
        delta -= timedelta(days=num_years * 365)
        ret.append(ngettext('%d year', '%d years', num_years) % num_years)

    if delta.days > 0:
        ret.append(ngettext('%d day', '%d days', delta.days) % delta.days)

    num_hours = int(delta.seconds / 3600)
    if num_hours > 0:
        delta -= timedelta(hours=num_hours)
        ret.append(ngettext('%d hour', '%d hours', num_hours) % num_hours)

    num_minutes = int(delta.seconds / 60)
    if num_minutes > 0:
        ret.append(ngettext('%d minute', '%d minutes', num_minutes) % num_minutes)

    return ' '.join(ret)

这将生成:

>>> from datetime import timedelta
>>> localize_timedelta(timedelta(days=3660, minutes=500))
'10 years 10 days 8 hours 20 minutes'
from django.utils.translation import ngettext

def localize_timedelta(delta):
    ret = []
    num_years = int(delta.days / 365)
    if num_years > 0:
        delta -= timedelta(days=num_years * 365)
        ret.append(ngettext('%d year', '%d years', num_years) % num_years)

    if delta.days > 0:
        ret.append(ngettext('%d day', '%d days', delta.days) % delta.days)

    num_hours = int(delta.seconds / 3600)
    if num_hours > 0:
        delta -= timedelta(hours=num_hours)
        ret.append(ngettext('%d hour', '%d hours', num_hours) % num_hours)

    num_minutes = int(delta.seconds / 60)
    if num_minutes > 0:
        ret.append(ngettext('%d minute', '%d minutes', num_minutes) % num_minutes)

    return ' '.join(ret)

This will produce:

>>> from datetime import timedelta
>>> localize_timedelta(timedelta(days=3660, minutes=500))
'10 years 10 days 8 hours 20 minutes'

回答 18

请检查此功能-它会将timedelta对象转换为字符串’HH:MM:SS’

def format_timedelta(td):
    hours, remainder = divmod(td.total_seconds(), 3600)
    minutes, seconds = divmod(remainder, 60)
    hours, minutes, seconds = int(hours), int(minutes), int(seconds)
    if hours < 10:
        hours = '0%s' % int(hours)
    if minutes < 10:
        minutes = '0%s' % minutes
    if seconds < 10:
        seconds = '0%s' % seconds
    return '%s:%s:%s' % (hours, minutes, seconds)

Please check this function – it converts timedelta object into string ‘HH:MM:SS’

def format_timedelta(td):
    hours, remainder = divmod(td.total_seconds(), 3600)
    minutes, seconds = divmod(remainder, 60)
    hours, minutes, seconds = int(hours), int(minutes), int(seconds)
    if hours < 10:
        hours = '0%s' % int(hours)
    if minutes < 10:
        minutes = '0%s' % minutes
    if seconds < 10:
        seconds = '0%s' % seconds
    return '%s:%s:%s' % (hours, minutes, seconds)

回答 19

一支班轮。由于timedelta不提供datetime的strftime,因此请将timedelta带回datetime,然后使用stftime。

这不仅可以实现OP要求的格式Hours:Minutes,现在,如果您的需求更改为其他表示形式,则可以利用datetime的strftime的完整格式化功能。

import datetime
td = datetime.timedelta(hours=2, minutes=10, seconds=5)
print(td)
print(datetime.datetime.strftime(datetime.datetime.strptime(str(td), "%H:%M:%S"), "%H:%M"))

Output:
2:10:05
02:10

这也解决了将时间增量格式化为H:MM:SS而不是HH:MM:SS的麻烦,这导致了我遇到这个问题,并且分享了我的解决方案。

One liner. Since timedeltas do not offer datetime’s strftime, bring the timedelta back to a datetime, and use stftime.

This can not only achieve the OP’s requested format Hours:Minutes, now you can leverage the full formatting power of datetime’s strftime, should your requirements change to another representation.

import datetime
td = datetime.timedelta(hours=2, minutes=10, seconds=5)
print(td)
print(datetime.datetime.strftime(datetime.datetime.strptime(str(td), "%H:%M:%S"), "%H:%M"))

Output:
2:10:05
02:10

This also solves the annoyance that timedeltas are formatted into strings as H:MM:SS rather than HH:MM:SS, which lead me to this problem, and the solution I’ve shared.


回答 20

如果您已经有一个timedelta obj,则只需将该obj转换为字符串即可。删除字符串的最后3个字符并打印。这将截断秒数部分,并以小时:分钟的格式打印其余部分。

t = str(timedeltaobj) 

print t[:-3]

If you already have a timedelta obj then just convert that obj into string. Remove the last 3 characters of the string and print. This will truncate the seconds part and print the rest of it in the format Hours:Minutes.

t = str(timedeltaobj) 

print t[:-3]

回答 21

如果您恰好IPython在包装中(应该如此),则它具有(到目前为止,无论如何)持续时间非常长的格式化程序(以秒为单位)。那是在各个地方使用的,例如%%time细胞魔术。我喜欢它能短期产生的格式:

>>> from IPython.core.magics.execution import _format_time
>>> 
>>> for v in range(-9, 10, 2):
...     dt = 1.25 * 10**v
...     print(_format_time(dt))

1.25 ns
125 ns
12.5 µs
1.25 ms
125 ms
12.5 s
20min 50s
1d 10h 43min 20s
144d 16h 13min 20s
14467d 14h 13min 20s

If you happen to have IPython in your packages (you should), it has (up to now, anyway) a very nice formatter for durations (in float seconds). That is used in various places, for example by the %%time cell magic. I like the format it produces for short durations:

>>> from IPython.core.magics.execution import _format_time
>>> 
>>> for v in range(-9, 10, 2):
...     dt = 1.25 * 10**v
...     print(_format_time(dt))

1.25 ns
125 ns
12.5 µs
1.25 ms
125 ms
12.5 s
20min 50s
1d 10h 43min 20s
144d 16h 13min 20s
14467d 14h 13min 20s

回答 22

t1 = datetime.datetime.strptime(StartTime, "%H:%M:%S %d-%m-%y")

t2 = datetime.datetime.strptime(EndTime, "%H:%M:%S %d-%m-%y")

return str(t2-t1)

因此对于:

StartTime = '15:28:53 21-07-13'
EndTime = '15:32:40 21-07-13'

返回:

'0:03:47'
t1 = datetime.datetime.strptime(StartTime, "%H:%M:%S %d-%m-%y")

t2 = datetime.datetime.strptime(EndTime, "%H:%M:%S %d-%m-%y")

return str(t2-t1)

So for:

StartTime = '15:28:53 21-07-13'
EndTime = '15:32:40 21-07-13'

returns:

'0:03:47'

回答 23

感谢大家的帮助。我采纳了您的许多想法并将它们组合在一起,让我知道您的想法。

我向此类添加了两个方法:

def hours(self):
    retval = ""
    if self.totalTime:
        hoursfloat = self.totalTime.seconds / 3600
        retval = round(hoursfloat)
    return retval

def minutes(self):
    retval = ""
    if self.totalTime:
        minutesfloat = self.totalTime.seconds / 60
        hoursAsMinutes = self.hours() * 60
        retval = round(minutesfloat - hoursAsMinutes)
    return retval

在我的django中,我使用了这个(sum是对象,它在字典中):

<td>{{ sum.0 }}</td>    
<td>{{ sum.1.hours|stringformat:"d" }}:{{ sum.1.minutes|stringformat:"#02.0d" }}</td>

Thanks everyone for your help. I took many of your ideas and put them together, let me know what you think.

I added two methods to the class like this:

def hours(self):
    retval = ""
    if self.totalTime:
        hoursfloat = self.totalTime.seconds / 3600
        retval = round(hoursfloat)
    return retval

def minutes(self):
    retval = ""
    if self.totalTime:
        minutesfloat = self.totalTime.seconds / 60
        hoursAsMinutes = self.hours() * 60
        retval = round(minutesfloat - hoursAsMinutes)
    return retval

In my django I used this (sum is the object and it is in a dictionary):

<td>{{ sum.0 }}</td>    
<td>{{ sum.1.hours|stringformat:"d" }}:{{ sum.1.minutes|stringformat:"#02.0d" }}</td>

Django auto_now和auto_now_add

问题:Django auto_now和auto_now_add

对于Django 1.1。

我的models.py中有这个:

class User(models.Model):
    created = models.DateTimeField(auto_now_add=True)
    modified = models.DateTimeField(auto_now=True)

更新行时,我得到:

[Sun Nov 15 02:18:12 2009] [error] /home/ptarjan/projects/twitter-meme/django/db/backends/mysql/base.py:84: Warning: Column 'created' cannot be null
[Sun Nov 15 02:18:12 2009] [error]   return self.cursor.execute(query, args)

我数据库的相关部分是:

  `created` datetime NOT NULL,
  `modified` datetime NOT NULL,

这值得关注吗?

附带问题:在我的管理工具中,这两个字段没有显示。那是预期的吗?

For Django 1.1.

I have this in my models.py:

class User(models.Model):
    created = models.DateTimeField(auto_now_add=True)
    modified = models.DateTimeField(auto_now=True)

When updating a row I get:

[Sun Nov 15 02:18:12 2009] [error] /home/ptarjan/projects/twitter-meme/django/db/backends/mysql/base.py:84: Warning: Column 'created' cannot be null
[Sun Nov 15 02:18:12 2009] [error]   return self.cursor.execute(query, args)

The relevant part of my database is:

  `created` datetime NOT NULL,
  `modified` datetime NOT NULL,

Is this cause for concern?

Side question: in my admin tool, those two fields aren’t showing up. Is that expected?


回答 0

auto_now设置了属性的任何字段也会继承editable=False,因此不会显示在管理面板中。过去有过关于使auto_nowand auto_now_add参数消失的讨论,尽管它们仍然存在,但我觉得您最好只使用自定义save()方法

因此,为了使其正常工作,我建议不要使用auto_nowauto_now_add而是定义自己的save()方法以确保created仅在id未设置的情况下(例如,首次创建该项目时)对其进行更新,并使其在modified每次该项目更新时进行更新已保存。

我已经使用Django编写的其他项目完成了完全相同的操作,因此您save()将看起来像这样:

from django.utils import timezone

class User(models.Model):
    created     = models.DateTimeField(editable=False)
    modified    = models.DateTimeField()

    def save(self, *args, **kwargs):
        ''' On save, update timestamps '''
        if not self.id:
            self.created = timezone.now()
        self.modified = timezone.now()
        return super(User, self).save(*args, **kwargs)

希望这可以帮助!

编辑以回应评论:

我坚持重载save()与依赖这些字段参数的原因有两个:

  1. 前述的起伏具有其可靠性。这些参数在很大程度上取决于Django知道如何与之交互的每种类型的数据库对待日期/时间戳字段的方式,并且似乎在每个发行版之间都会中断和/或更改。(我相信这是彻底删除它们的呼吁的推动力)。
  2. 它们仅在DateField,DateTimeField和TimeField上起作用,使用这种技术,您可以在每次保存项目时自动填充任何字段类型。
  3. 使用django.utils.timezone.now()vs. datetime.datetime.now(),因为它会根据来返回可感知TZ或天真的datetime.datetime对象settings.USE_TZ

为了解决OP为何看到该错误的原因,我不完全知道,但created尽管有,但看起来根本没有被填充auto_now_add=True。对我来说,它是一个bug,并且在我上面的小列表中强调了项目#1: auto_now并且auto_now_add充其量是片状的。

Any field with the auto_now attribute set will also inherit editable=False and therefore will not show up in the admin panel. There has been talk in the past about making the auto_now and auto_now_add arguments go away, and although they still exist, I feel you’re better off just using a custom save() method.

So, to make this work properly, I would recommend not using auto_now or auto_now_add and instead define your own save() method to make sure that created is only updated if id is not set (such as when the item is first created), and have it update modified every time the item is saved.

I have done the exact same thing with other projects I have written using Django, and so your save() would look like this:

from django.utils import timezone

class User(models.Model):
    created     = models.DateTimeField(editable=False)
    modified    = models.DateTimeField()

    def save(self, *args, **kwargs):
        ''' On save, update timestamps '''
        if not self.id:
            self.created = timezone.now()
        self.modified = timezone.now()
        return super(User, self).save(*args, **kwargs)

Hope this helps!

Edit in response to comments:

The reason why I just stick with overloading save() vs. relying on these field arguments is two-fold:

  1. The aforementioned ups and downs with their reliability. These arguments are heavily reliant on the way each type of database that Django knows how to interact with treats a date/time stamp field, and seems to break and/or change between every release. (Which I believe is the impetus behind the call to have them removed altogether).
  2. The fact that they only work on DateField, DateTimeField, and TimeField, and by using this technique you are able to automatically populate any field type every time an item is saved.
  3. Use django.utils.timezone.now() vs. datetime.datetime.now(), because it will return a TZ-aware or naive datetime.datetime object depending on settings.USE_TZ.

To address why the OP saw the error, I don’t know exactly, but it looks like created isn’t even being populated at all, despite having auto_now_add=True. To me it stands out as a bug, and underscores item #1 in my little list above: auto_now and auto_now_add are flaky at best.


回答 1

但是我想指出的是,已接受答案中表达的观点有些过时。根据最近的讨论(django bug #7634 12785),即使您进入原始讨论,auto_now和auto_now_add也不行。,您也会在自定义保存中找到针对RY的强大论点(如DRY)方法。

提供了一个更好的解决方案(自定义字段类型),但是没有获得足够的动力使其成为django。您可以三行编写自己的代码(这是Jacob Kaplan-Moss的建议)。

from django.db import models
from django.utils import timezone


class AutoDateTimeField(models.DateTimeField):
    def pre_save(self, model_instance, add):
        return timezone.now()

#usage
created_at = models.DateField(default=timezone.now)
updated_at = models.AutoDateTimeField(default=timezone.now)

But I wanted to point out that the opinion expressed in the accepted answer is somewhat outdated. According to more recent discussions (django bugs #7634 and #12785), auto_now and auto_now_add are not going anywhere, and even if you go to the original discussion, you’ll find strong arguments against the RY (as in DRY) in custom save methods.

A better solution has been offered (custom field types), but didn’t gain enough momentum to make it into django. You can write your own in three lines (it’s Jacob Kaplan-Moss’ suggestion).

from django.db import models
from django.utils import timezone


class AutoDateTimeField(models.DateTimeField):
    def pre_save(self, model_instance, add):
        return timezone.now()

#usage
created_at = models.DateField(default=timezone.now)
updated_at = models.AutoDateTimeField(default=timezone.now)

回答 2

谈论一个附带的问题:如果您想在admin中查看此字段(尽管您将无法对其进行编辑),则可以将其添加readonly_fields到admin类中。

class SomeAdmin(ModelAdmin):
    readonly_fields = ("created","modified",)

好吧,这仅适用于最新的Django版本(我相信1.3及更高版本)

Talking about a side question: if you want to see this fields in admin (though, you won’t be able to edit it), you can add readonly_fields to your admin class.

class SomeAdmin(ModelAdmin):
    readonly_fields = ("created","modified",)

Well, this applies only to latest Django versions (I believe, 1.3 and above)


回答 3

我认为这里最简单(也许也是最优雅)的解决方案是利用您可以设置default为可调用对象的事实。因此,要绕过管理员对auto_now的特殊处理,您可以像这样声明字段:

from django.utils import timezone
date_filed = models.DateField(default=timezone.now)

重要的是不要使用timezone.now()默认值,因为默认值不会更新(即,仅在加载代码时设置默认值)。如果您发现自己经常这样做,则可以创建一个自定义字段。但是,我认为这已经很干燥了。

I think the easiest (and maybe most elegant) solution here is to leverage the fact that you can set default to a callable. So, to get around admin’s special handling of auto_now, you can just declare the field like so:

from django.utils import timezone
date_filed = models.DateField(default=timezone.now)

It’s important that you don’t use timezone.now() as the default value wouldn’t update (i.e., default gets set only when the code is loaded). If you find yourself doing this a lot, you could create a custom field. However, this is pretty DRY already I think.


回答 4

如果您像这样更改模型类:

class MyModel(models.Model):
    time = models.DateTimeField(auto_now_add=True)
    time.editable = True

然后,该字段将显示在我的管理员更改页面中

If you alter your model class like this:

class MyModel(models.Model):
    time = models.DateTimeField(auto_now_add=True)
    time.editable = True

Then this field will show up in my admin change page


回答 5

根据我已经阅读的内容以及到目前为止的Django经验,auto_now_add确实存在问题。我同意詹森主义—覆盖干净的普通保存方法,您知道正在发生什么。现在,要使其干燥,请创建一个称为TimeStamped的抽象模型:

from django.utils import timezone

class TimeStamped(models.Model):
    creation_date = models.DateTimeField(editable=False)
    last_modified = models.DateTimeField(editable=False)

    def save(self, *args, **kwargs):
        if not self.creation_date:
            self.creation_date = timezone.now()

        self.last_modified = timezone.now()
        return super(TimeStamped, self).save(*args, **kwargs)

    class Meta:
        abstract = True

然后,当您想要一个具有这种耗时行为的模型时,只需子类化即可:

MyNewTimeStampyModel(TimeStamped):
    field1 = ...

如果您希望这些字段显示在admin中,则只需删除该editable=False选项

Based on what I’ve read and my experience with Django so far, auto_now_add is buggy. I agree with jthanism — override the normal save method it’s clean and you know what’s hapenning. Now, to make it dry, create an abstract model called TimeStamped:

from django.utils import timezone

class TimeStamped(models.Model):
    creation_date = models.DateTimeField(editable=False)
    last_modified = models.DateTimeField(editable=False)

    def save(self, *args, **kwargs):
        if not self.creation_date:
            self.creation_date = timezone.now()

        self.last_modified = timezone.now()
        return super(TimeStamped, self).save(*args, **kwargs)

    class Meta:
        abstract = True

And then, when you want a model that has this time-stampy behavior, just subclass:

MyNewTimeStampyModel(TimeStamped):
    field1 = ...

If you want the fields to show up in admin, then just remove the editable=False option


回答 6

这值得关注吗?

不,Django在保存模型时会自动为您添加它,因此是可以预期的。

附带问题:在我的管理工具中,这两个字段没有显示。那是预期的吗?

由于这些字段是自动添加的,因此不会显示。

正如synack所说的,除此以外,在django邮件列表上已经有辩论将其删除,因为它“设计得不好”并且是“黑客”。

与使用auto_now相比,在我的每个模型上编写自定义的save()要痛苦得多

显然,您不必将其写入每个模型。您可以将其写入一个模型并从中继承其他模型。

但是,因为auto_addauto_now_add在那里,我会用他们,而不是试图写一个方法我自己。

Is this cause for concern?

No, Django automatically adds it for you while saving the models, so, it is expected.

Side question: in my admin tool, those 2 fields aren’t showing up. Is that expected?

Since these fields are auto added, they are not shown.

To add to the above, as synack said, there has been a debate on the django mailing list to remove this, because, it is “not designed well” and is “a hack”

Writing a custom save() on each of my models is much more pain than using the auto_now

Obviously you don’t have to write it to every model. You can write it to one model and inherit others from it.

But, as auto_add and auto_now_add are there, I would use them rather than trying to write a method myself.


回答 7

今天我在工作中需要类似的东西。默认值为timezone.now(),但在继承自的管理视图和类视图中均可编辑FormMixin,因此对于在我中创建models.py的代码,以下代码满足了这些要求:

from __future__ import unicode_literals
import datetime

from django.db import models
from django.utils.functional import lazy
from django.utils.timezone import localtime, now

def get_timezone_aware_now_date():
    return localtime(now()).date()

class TestDate(models.Model):
    created = models.DateField(default=lazy(
        get_timezone_aware_now_date, datetime.date)()
    )

对于DateTimeField,我想.date()从功能中删除并更改datetime.datedatetime.datetime或更好timezone.datetime。我没有尝试过DateTime,只有尝试过Date

I needed something similar today at work. Default value to be timezone.now(), but editable both in admin and class views inheriting from FormMixin, so for created in my models.py the following code fulfilled those requirements:

from __future__ import unicode_literals
import datetime

from django.db import models
from django.utils.functional import lazy
from django.utils.timezone import localtime, now

def get_timezone_aware_now_date():
    return localtime(now()).date()

class TestDate(models.Model):
    created = models.DateField(default=lazy(
        get_timezone_aware_now_date, datetime.date)()
    )

For DateTimeField, I guess remove the .date() from the function and change datetime.date to datetime.datetime or better timezone.datetime. I haven’t tried it with DateTime, only with Date.


回答 8

您可以将其timezone.now()用于创建和auto_now修改:

from django.utils import timezone
class User(models.Model):
    created = models.DateTimeField(default=timezone.now())
    modified = models.DateTimeField(auto_now=True)

如果您使用的是自定义主键而不是默认键auto- increment intauto_now_add将导致错误。

下面是Django默认的代码DateTimeField.pre_saveauto_nowauto_now_add

def pre_save(self, model_instance, add):
    if self.auto_now or (self.auto_now_add and add):
        value = timezone.now()
        setattr(model_instance, self.attname, value)
        return value
    else:
        return super(DateTimeField, self).pre_save(model_instance, add)

我不确定参数add是什么。我希望它会像:

add = True if getattr(model_instance, 'id') else False

新记录将没有attr id,因此getattr(model_instance, 'id')返回False将导致未在字段中设置任何值。

You can use timezone.now() for created and auto_now for modified:

from django.utils import timezone
class User(models.Model):
    created = models.DateTimeField(default=timezone.now())
    modified = models.DateTimeField(auto_now=True)

If you are using a custom primary key instead of the default auto- increment int, auto_now_add will lead to a bug.

Here is the code of Django’s default DateTimeField.pre_save withauto_now and auto_now_add:

def pre_save(self, model_instance, add):
    if self.auto_now or (self.auto_now_add and add):
        value = timezone.now()
        setattr(model_instance, self.attname, value)
        return value
    else:
        return super(DateTimeField, self).pre_save(model_instance, add)

I am not sure what the parameter add is. I hope it will some thing like:

add = True if getattr(model_instance, 'id') else False

The new record will not have attr id, so getattr(model_instance, 'id') will return False will lead to not setting any value in the field.


回答 9

至于您的管理员显示,请参阅此答案

注意:auto_now并且默认auto_now_add设置为editable=False,这就是为什么这样。

As for your Admin display, see this answer.

Note: auto_now and auto_now_add are set to editable=False by default, which is why this applies.


回答 10

auto_now=True在Django 1.4.1中对我不起作用,但是以下代码救了我。用于时区感知日期时间。

from django.utils.timezone import get_current_timezone
from datetime import datetime

class EntryVote(models.Model):
    voted_on = models.DateTimeField(auto_now=True)

    def save(self, *args, **kwargs):
        self.voted_on = datetime.now().replace(tzinfo=get_current_timezone())
        super(EntryVote, self).save(*args, **kwargs)

auto_now=True didn’t work for me in Django 1.4.1, but the below code saved me. It’s for timezone aware datetime.

from django.utils.timezone import get_current_timezone
from datetime import datetime

class EntryVote(models.Model):
    voted_on = models.DateTimeField(auto_now=True)

    def save(self, *args, **kwargs):
        self.voted_on = datetime.now().replace(tzinfo=get_current_timezone())
        super(EntryVote, self).save(*args, **kwargs)

回答 11

class Feedback(models.Model):
   feedback = models.CharField(max_length=100)
   created = models.DateTimeField(auto_now_add=True)
   updated = models.DateTimeField(auto_now=True)

在这里,我们创建并更新了列,这些列在创建时以及有人修改反馈时都会带有时间戳。

auto_now_add将设置创建实例的时间,而auto_now将设置某人修改其反馈的时间。

class Feedback(models.Model):
   feedback = models.CharField(max_length=100)
   created = models.DateTimeField(auto_now_add=True)
   updated = models.DateTimeField(auto_now=True)

Here, we have created and updated columns that will have a timestamp when created, and when someone modified feedback.

auto_now_add will set time when an instance is created whereas auto_now will set time when someone modified his feedback.


回答 12

如果您使用的是南方,并且想要默认为将字段添加到数据库的日期,这就是答案:

选择选项2, 然后: datetime.datetime.now()

看起来像这样:

$ ./manage.py schemamigration myapp --auto
 ? The field 'User.created_date' does not have a default specified, yet is NOT NULL.
 ? Since you are adding this field, you MUST specify a default
 ? value to use for existing rows. Would you like to:
 ?  1. Quit now, and add a default to the field in models.py
 ?  2. Specify a one-off value to use for existing columns now
 ? Please select a choice: 2
 ? Please enter Python code for your one-off default value.
 ? The datetime module is available, so you can do e.g. datetime.date.today()
 >>> datetime.datetime.now()
 + Added field created_date on myapp.User

Here’s the answer if you’re using south and you want to default to the date you add the field to the database:

Choose option 2 then: datetime.datetime.now()

Looks like this:

$ ./manage.py schemamigration myapp --auto
 ? The field 'User.created_date' does not have a default specified, yet is NOT NULL.
 ? Since you are adding this field, you MUST specify a default
 ? value to use for existing rows. Would you like to:
 ?  1. Quit now, and add a default to the field in models.py
 ?  2. Specify a one-off value to use for existing columns now
 ? Please select a choice: 2
 ? Please enter Python code for your one-off default value.
 ? The datetime module is available, so you can do e.g. datetime.date.today()
 >>> datetime.datetime.now()
 + Added field created_date on myapp.User

如何在python中获取当前时间并分解为年,月,日,小时,分钟?

问题:如何在python中获取当前时间并分解为年,月,日,小时,分钟?

我想获得当前时间在Python,并将它们分配到变量喜欢yearmonthdayhourminute。如何在Python 2.7中完成?

I would like to get the current time in Python and assign them into variables like year, month, day, hour, minute. How can this be done in Python 2.7?


回答 0

datetime模块是您的朋友:

import datetime
now = datetime.datetime.now()
print now.year, now.month, now.day, now.hour, now.minute, now.second
# 2015 5 6 8 53 40

您不需要单独的变量,返回datetime对象上的属性就可以满足您的所有需求。

The datetime module is your friend:

import datetime
now = datetime.datetime.now()
print(now.year, now.month, now.day, now.hour, now.minute, now.second)
# 2015 5 6 8 53 40

You don’t need separate variables, the attributes on the returned datetime object have all you need.


回答 1

这是一个单线,最大字符数不超过80个字符。

import time
year, month, day, hour, min = map(int, time.strftime("%Y %m %d %H %M").split())

Here’s a one-liner that comes in just under the 80 char line max.

import time
year, month, day, hour, min = map(int, time.strftime("%Y %m %d %H %M").split())

回答 2

tzamandatetime答案要干净得多,但是您可以使用原始的python 模块来实现:time

import time
strings = time.strftime("%Y,%m,%d,%H,%M,%S")
t = strings.split(',')
numbers = [ int(x) for x in t ]
print numbers

输出:

[2016, 3, 11, 8, 29, 47]

The datetime answer by tzaman is much cleaner, but you can do it with the original python time module:

import time
strings = time.strftime("%Y,%m,%d,%H,%M,%S")
t = strings.split(',')
numbers = [ int(x) for x in t ]
print numbers

Output:

[2016, 3, 11, 8, 29, 47]

回答 3

通过解压缩timetupledatetime对象,您应该得到想要的东西:

from datetime import datetime

n = datetime.now()
t = n.timetuple()
y, m, d, h, min, sec, wd, yd, i = t

By unpacking timetuple of datetime object, you should get what you want:

from datetime import datetime

n = datetime.now()
t = n.timetuple()
y, m, d, h, min, sec, wd, yd, i = t

回答 4

对于python 3

import datetime
now = datetime.datetime.now()
print(now.year, now.month, now.day, now.hour, now.minute, now.second)

For python 3

import datetime
now = datetime.datetime.now()
print(now.year, now.month, now.day, now.hour, now.minute, now.second)

回答 5

让我们看看如何从当前时间获取并打印python中的日,月,年:

import datetime

now = datetime.datetime.now()
year = '{:02d}'.format(now.year)
month = '{:02d}'.format(now.month)
day = '{:02d}'.format(now.day)
hour = '{:02d}'.format(now.hour)
minute = '{:02d}'.format(now.minute)
day_month_year = '{}-{}-{}'.format(year, month, day)

print('day_month_year: ' + day_month_year)

结果:

day_month_year: 2019-03-26

Let’s see how to get and print day,month,year in python from current time:

import datetime

now = datetime.datetime.now()
year = '{:02d}'.format(now.year)
month = '{:02d}'.format(now.month)
day = '{:02d}'.format(now.day)
hour = '{:02d}'.format(now.hour)
minute = '{:02d}'.format(now.minute)
day_month_year = '{}-{}-{}'.format(year, month, day)

print('day_month_year: ' + day_month_year)

result:

day_month_year: 2019-03-26

回答 6

import time
year = time.strftime("%Y") # or "%y"
import time
year = time.strftime("%Y") # or "%y"

回答 7

三个用于访问和操纵日期和时间的库,即日期时间,箭头和摆锤,都使这些项在命名元组中可用,命名元组的元素可通过名称或索引访问。此外,可以完全相同的方式访问项目。(我想如果我更聪明,我不会感到惊讶。)

>>> YEARS, MONTHS, DAYS, HOURS, MINUTES = range(5)
>>> import datetime
>>> import arrow
>>> import pendulum
>>> [datetime.datetime.now().timetuple()[i] for i in [YEARS, MONTHS, DAYS, HOURS, MINUTES]]
[2017, 6, 16, 19, 15]
>>> [arrow.now().timetuple()[i] for i in [YEARS, MONTHS, DAYS, HOURS, MINUTES]]
[2017, 6, 16, 19, 15]
>>> [pendulum.now().timetuple()[i] for i in [YEARS, MONTHS, DAYS, HOURS, MINUTES]]
[2017, 6, 16, 19, 16]

Three libraries for accessing and manipulating dates and times, namely datetime, arrow and pendulum, all make these items available in namedtuples whose elements are accessible either by name or index. Moreover, the items are accessible in precisely the same way. (I suppose if I were more intelligent I wouldn’t be surprised.)

>>> YEARS, MONTHS, DAYS, HOURS, MINUTES = range(5)
>>> import datetime
>>> import arrow
>>> import pendulum
>>> [datetime.datetime.now().timetuple()[i] for i in [YEARS, MONTHS, DAYS, HOURS, MINUTES]]
[2017, 6, 16, 19, 15]
>>> [arrow.now().timetuple()[i] for i in [YEARS, MONTHS, DAYS, HOURS, MINUTES]]
[2017, 6, 16, 19, 15]
>>> [pendulum.now().timetuple()[i] for i in [YEARS, MONTHS, DAYS, HOURS, MINUTES]]
[2017, 6, 16, 19, 16]

回答 8

您可以使用gmtime

from time import gmtime

detailed_time = gmtime() 
#returns a struct_time object for current time

year = detailed_time.tm_year
month = detailed_time.tm_mon
day = detailed_time.tm_mday
hour = detailed_time.tm_hour
minute = detailed_time.tm_min

注意:可以将时间戳传递给gmtime,默认为time()返回的当前时间

eg.
gmtime(1521174681)

参见struct_time

You can use gmtime

from time import gmtime

detailed_time = gmtime() 
#returns a struct_time object for current time

year = detailed_time.tm_year
month = detailed_time.tm_mon
day = detailed_time.tm_mday
hour = detailed_time.tm_hour
minute = detailed_time.tm_min

Note: A time stamp can be passed to gmtime, default is current time as returned by time()

eg.
gmtime(1521174681)

See struct_time


回答 9

这是一个比较老的问题,但是我想出了一个我认为其他人可能会喜欢的解决方案。

def get_current_datetime_as_dict():
n = datetime.now()
t = n.timetuple()
field_names = ["year",
               "month",
               "day",
               "hour",
               "min",
               "sec",
               "weekday",
               "md",
               "yd"]
return dict(zip(field_names, t))

timetuple()可以与另一个数组一起压缩,这将创建带标签的元组。将其转换为字典,然后可以使用生成的产品get_current_datetime_as_dict()['year']

这比这里的其他一些解决方案有更多的开销,但是我发现能够在代码中为清楚起见而访问命名值真是太好了。

This is an older question, but I came up with a solution I thought others might like.

def get_current_datetime_as_dict():
n = datetime.now()
t = n.timetuple()
field_names = ["year",
               "month",
               "day",
               "hour",
               "min",
               "sec",
               "weekday",
               "md",
               "yd"]
return dict(zip(field_names, t))

timetuple() can be zipped with another array, which creates labeled tuples. Cast that to a dictionary and the resultant product can be consumed with get_current_datetime_as_dict()['year'].

This has a little more overhead than some of the other solutions on here, but I’ve found it’s so nice to be able to access named values for clartiy’s sake in the code.


回答 10

您可以使用datetime模块获取Python 2.7中的当前日期和时间

import datetime
print datetime.datetime.now()

输出:

2015-05-06 14:44:14.369392

you can use datetime module to get current Date and Time in Python 2.7

import datetime
print datetime.datetime.now()

Output :

2015-05-06 14:44:14.369392

如何在Python中获取“时区感知”的datetime.today()值?

问题:如何在Python中获取“时区感知”的datetime.today()值?

我正在尝试从的值中减去一个日期值,datetime.today()以计算某物是多久以前的。但它抱怨:

TypeError: can't subtract offset-naive and offset-aware datetimes

该值datetime.today()似乎不是“时区感知”的,而我的其他日期值是。如何获得datetime.today()时区感知的值?

现在,这给了我当地时间,正好是PST,即UTC-8个小时。最坏的情况是,有没有一种方法可以手动将时区值输入datetime返回的对象datetime.today()并将其设置为UTC-8?

当然,理想的解决方案是让它自动知道时区。

I am trying to subtract one date value from the value of datetime.today() to calculate how long ago something was. But it complains:

TypeError: can't subtract offset-naive and offset-aware datetimes

The value datetime.today() doesn’t seem to be “timezone aware”, while my other date value is. How do I get a value of datetime.today() that is timezone aware?

Right now, it’s giving me the time in local time, which happens to be PST, i.e. UTC – 8 hours. Worst case, is there a way I can manually enter a timezone value into the datetime object returned by datetime.today() and set it to UTC-8?

Of course, the ideal solution would be for it to automatically know the timezone.


回答 0

在标准库中,没有跨平台的方法来创建感知时区而不创建自己的时区类。

在Windows上有win32timezone.utcnow(),但这是pywin32的一部分。我宁愿建议使用pytz库,该库具有大多数时区的不断更新的数据库。

使用本地时区可能非常棘手(请参见下面的“更多阅读”链接),因此您可能希望在整个应用程序中使用UTC,尤其是对于算术运算(如计算两个时间点之间的差)。

您可以像这样获取当前日期/时间:

import pytz
from datetime import datetime
datetime.utcnow().replace(tzinfo=pytz.utc)

记住这一点datetime.today()datetime.now()返回本地时间,而不是UTC时间,因此.replace(tzinfo=pytz.utc)向他们申请是不正确的。

另一个好的方法是:

datetime.now(pytz.utc)

这有点短,并且执行相同的操作。


进一步阅读/观看为什么在许多情况下更喜欢UTC:

In the standard library, there is no cross-platform way to create aware timezones without creating your own timezone class.

On Windows, there’s win32timezone.utcnow(), but that’s part of pywin32. I would rather suggest to use the pytz library, which has a constantly updated database of most timezones.

Working with local timezones can be very tricky (see “Further reading” links below), so you may rather want to use UTC throughout your application, especially for arithmetic operations like calculating the difference between two time points.

You can get the current date/time like so:

import pytz
from datetime import datetime
datetime.utcnow().replace(tzinfo=pytz.utc)

Mind that datetime.today() and datetime.now() return the local time, not the UTC time, so applying .replace(tzinfo=pytz.utc) to them would not be correct.

Another nice way to do it is:

datetime.now(pytz.utc)

which is a bit shorter and does the same.


Further reading/watching why to prefer UTC in many cases:


回答 1

获取特定时区的当前时间:

import datetime
import pytz
my_date = datetime.datetime.now(pytz.timezone('US/Pacific'))

Get the current time, in a specific timezone:

import datetime
import pytz
my_date = datetime.datetime.now(pytz.timezone('US/Pacific'))

回答 2

在Python 3中,标准库使将UTC指定为时区变得容易得多:

>>> import datetime
>>> datetime.datetime.now(datetime.timezone.utc)
datetime.datetime(2016, 8, 26, 14, 34, 34, 74823, tzinfo=datetime.timezone.utc)

如果您想要一个仅使用标准库并且在Python 2和Python 3中均可使用的解决方案,请参见jfs的答案

如果您需要当地时区而不是UTC,请参见MihaiCapotă的答案

In Python 3, the standard library makes it much easier to specify UTC as the timezone:

>>> import datetime
>>> datetime.datetime.now(datetime.timezone.utc)
datetime.datetime(2016, 8, 26, 14, 34, 34, 74823, tzinfo=datetime.timezone.utc)

If you want a solution that uses only the standard library and that works in both Python 2 and Python 3, see jfs’ answer.

If you need the local timezone, not UTC, see Mihai Capotă’s answer


回答 3

这是一个适用于Python 2和3的stdlib解决方案:

from datetime import datetime

now = datetime.now(utc) # Timezone-aware datetime.utcnow()
today = datetime(now.year, now.month, now.day, tzinfo=utc) # Midnight

其中today是一个已知的datetime实例,表示UTC中的一天的开始(午夜),并且utc是tzinfo对象(来自文档的示例):

from datetime import tzinfo, timedelta

ZERO = timedelta(0)

class UTC(tzinfo):
    def utcoffset(self, dt):
        return ZERO

    def tzname(self, dt):
        return "UTC"

    def dst(self, dt):
        return ZERO

utc = UTC()

相关:在给定UTC时间获得午夜(一天的开始)几种方法的性能比较。注意:要获取具有非固定UTC偏移量的时区的午夜更为复杂。

Here’s a stdlib solution that works on both Python 2 and 3:

from datetime import datetime

now = datetime.now(utc) # Timezone-aware datetime.utcnow()
today = datetime(now.year, now.month, now.day, tzinfo=utc) # Midnight

where today is an aware datetime instance representing the beginning of the day (midnight) in UTC and utc is a tzinfo object (example from the documentation):

from datetime import tzinfo, timedelta

ZERO = timedelta(0)

class UTC(tzinfo):
    def utcoffset(self, dt):
        return ZERO

    def tzname(self, dt):
        return "UTC"

    def dst(self, dt):
        return ZERO

utc = UTC()

Related: performance comparison of several ways to get midnight (start of a day) for a given UTC time. Note: it is more complex, to get midnight for a time zone with a non-fixed UTC offset.


回答 4

构造表示当前时间的时区感知日期时间对象的另一种方法:

import datetime
import pytz

pytz.utc.localize( datetime.datetime.utcnow() )  

Another method to construct time zone aware datetime object representing current time:

import datetime
import pytz

pytz.utc.localize( datetime.datetime.utcnow() )  

回答 5

从Python 3.3开始,仅使用标准库的单行代码就可以使用。您可以datetime使用来获取本地时区感知对象astimezone(如johnchen902建议):

from datetime import datetime, timezone

aware_local_now = datetime.now(timezone.utc).astimezone()

print(aware_local_now)
# 2020-03-03 09:51:38.570162+01:00

print(repr(aware_local_now))
# datetime.datetime(2020, 3, 3, 9, 51, 38, 570162, tzinfo=datetime.timezone(datetime.timedelta(0, 3600), 'CET'))

A one-liner using only the standard library works starting with Python 3.3. You can get a local timezone aware datetime object using astimezone (as suggested by johnchen902):

from datetime import datetime, timezone

aware_local_now = datetime.now(timezone.utc).astimezone()

print(aware_local_now)
# 2020-03-03 09:51:38.570162+01:00

print(repr(aware_local_now))
# datetime.datetime(2020, 3, 3, 9, 51, 38, 570162, tzinfo=datetime.timezone(datetime.timedelta(0, 3600), 'CET'))

回答 6

如果您使用的是Django,则可以将日期设置为非tz感知(仅UTC)。

在settings.py中注释以下行:

USE_TZ = True

If you are using Django, you can set dates non-tz aware (only UTC).

Comment the following line in settings.py:

USE_TZ = True

回答 7

pytz是一个Python库,可以使用Python 2.3或更高版本进行准确的跨平台时区计算。

使用stdlib,这是不可能的。

SO上看到类似的问题。

pytz is a Python library that allows accurate and cross platform timezone calculations using Python 2.3 or higher.

With the stdlib, this is not possible.

See a similar question on SO.


回答 8

这是使用stdlib生成它的一种方法:

import time
from datetime import datetime

FORMAT='%Y-%m-%dT%H:%M:%S%z'
date=datetime.strptime(time.strftime(FORMAT, time.localtime()),FORMAT)

date将存储本地日期和相对于UTC偏移量,而不是UTC时区的日期,因此,如果需要确定日期在哪个时区生成,可以使用此解决方案。在此示例中以及我的本地时区:

date
datetime.datetime(2017, 8, 1, 12, 15, 44, tzinfo=datetime.timezone(datetime.timedelta(0, 7200)))

date.tzname()
'UTC+02:00'

关键是将%z指令添加到表示形式FORMAT中,以指示生成的时间结构的UTC偏移量。其他表示形式可以在datetime模块文档中查询

如果您需要UTC时区的日期,则可以将time.localtime()替换为time.gmtime()

date=datetime.strptime(time.strftime(FORMAT, time.gmtime()),FORMAT)

date    
datetime.datetime(2017, 8, 1, 10, 23, 51, tzinfo=datetime.timezone.utc)

date.tzname()
'UTC'

编辑

这仅适用于python3。z指令在python 2 _strptime.py代码上不可用

Here is one way to generate it with the stdlib:

import time
from datetime import datetime

FORMAT='%Y-%m-%dT%H:%M:%S%z'
date=datetime.strptime(time.strftime(FORMAT, time.localtime()),FORMAT)

date will store the local date and the offset from UTC, not the date at UTC timezone, so you can use this solution if you need to identify which timezone the date is generated at. In this example and in my local timezone:

date
datetime.datetime(2017, 8, 1, 12, 15, 44, tzinfo=datetime.timezone(datetime.timedelta(0, 7200)))

date.tzname()
'UTC+02:00'

The key is adding the %z directive to the representation FORMAT, to indicate the UTC offset of the generated time struct. Other representation formats can be consulted in the datetime module docs

If you need the date at the UTC timezone, you can replace time.localtime() with time.gmtime()

date=datetime.strptime(time.strftime(FORMAT, time.gmtime()),FORMAT)

date    
datetime.datetime(2017, 8, 1, 10, 23, 51, tzinfo=datetime.timezone.utc)

date.tzname()
'UTC'

Edit

This works only on python3. The z directive is not available on python 2 _strptime.py code


回答 9

使用可识别时区的Python datetime.datetime.now()中所述的dateutil :

from dateutil.tz import tzlocal
# Get the current date/time with the timezone.
now = datetime.datetime.now(tzlocal())

Use dateutil as described in Python datetime.datetime.now() that is timezone aware:

from dateutil.tz import tzlocal
# Get the current date/time with the timezone.
now = datetime.datetime.now(tzlocal())

回答 10

在时区中获取可识别时区的日期utc足以使日期减法起作用。

但是,如果您想在当前时区使用时区感知日期,tzlocal则可以采用以下方法:

from tzlocal import get_localzone  # pip install tzlocal
from datetime import datetime
datetime.now(get_localzone())

PS dateutil具有类似的功能(dateutil.tz.tzlocal)。但是,尽管共享名称,但它具有完全不同的代码库,正如JF Sebastian 指出的那样,可能会产生错误的结果。

Getting a timezone-aware date in utc timezone is enough for date subtraction to work.

But if you want a timezone-aware date in your current time zone, tzlocal is the way to go:

from tzlocal import get_localzone  # pip install tzlocal
from datetime import datetime
datetime.now(get_localzone())

PS dateutil has a similar function (dateutil.tz.tzlocal). But inspite of sharing the name it has a completely different code base, which as noted by J.F. Sebastian can give wrong results.


回答 11

这是一个使用可读时区的解决方案,该解决方案适用于today():

from pytz import timezone

datetime.now(timezone('Europe/Berlin'))
datetime.now(timezone('Europe/Berlin')).today()

您可以列出所有时区,如下所示:

import pytz

pytz.all_timezones
pytz.common_timezones # or

Here is a solution using a readable timezone and that works with today():

from pytz import timezone

datetime.now(timezone('Europe/Berlin'))
datetime.now(timezone('Europe/Berlin')).today()

You can list all timezones as follows:

import pytz

pytz.all_timezones
pytz.common_timezones # or

回答 12

特别是对于非UTC时区:

唯一具有自己方法的时区是timezone.utc,但是如果需要,您可以使用timedeltatimezone,并使用强制使用UTC偏移量来伪装时区.replace

In [1]: from datetime import datetime, timezone, timedelta

In [2]: def force_timezone(dt, utc_offset=0):
   ...:     return dt.replace(tzinfo=timezone(timedelta(hours=utc_offset)))
   ...:

In [3]: dt = datetime(2011,8,15,8,15,12,0)

In [4]: str(dt)
Out[4]: '2011-08-15 08:15:12'

In [5]: str(force_timezone(dt, -8))
Out[5]: '2011-08-15 08:15:12-08:00'

在这里使用timezone(timedelta(hours=n))时区是真正的灵丹妙药,它还有许多其他有用的应用程序。

Especially for non-UTC timezones:

The only timezone that has its own method is timezone.utc, but you can fudge a timezone with any UTC offset if you need to by using timedelta & timezone, and forcing it using .replace.

In [1]: from datetime import datetime, timezone, timedelta

In [2]: def force_timezone(dt, utc_offset=0):
   ...:     return dt.replace(tzinfo=timezone(timedelta(hours=utc_offset)))
   ...:

In [3]: dt = datetime(2011,8,15,8,15,12,0)

In [4]: str(dt)
Out[4]: '2011-08-15 08:15:12'

In [5]: str(force_timezone(dt, -8))
Out[5]: '2011-08-15 08:15:12-08:00'

Using timezone(timedelta(hours=n)) as the time zone is the real silver bullet here, and it has lots of other useful applications.


回答 13

如果您在python中获得了当前时间和日期,则在导入日期和时间后,您将在python中获得当前日期和时间,如下所示。

from datetime import datetime
import pytz
import time
str(datetime.strftime(datetime.now(pytz.utc),"%Y-%m-%d %H:%M:%S%t"))

If you get current time and date in python then import date and time,pytz package in python after you will get current date and time like as..

from datetime import datetime
import pytz
import time
str(datetime.strftime(datetime.now(pytz.utc),"%Y-%m-%d %H:%M:%S%t"))

回答 14

在我看来,另一种替代方法是使用Pendulum代替pytz。考虑以下简单代码:

>>> import pendulum

>>> dt = pendulum.now().to_iso8601_string()
>>> print (dt)
2018-03-27T13:59:49+03:00
>>>

要安装Pendulum并查看其文档,请转到此处。它具有大量选项(例如简单的ISO8601,RFC3339和许多其他格式支持),更好的性能并倾向于产生更简单的代码。

Another alternative, in my mind a better one, is using Pendulum instead of pytz. Consider the following simple code:

>>> import pendulum

>>> dt = pendulum.now().to_iso8601_string()
>>> print (dt)
2018-03-27T13:59:49+03:00
>>>

To install Pendulum and see their documentation, go here. It have tons of options (like simple ISO8601, RFC3339 and many others format support), better performance and tend to yield simpler code.


回答 15

如下所示,将时区用于可识别时区的日期时间。默认为UTC:

from django.utils import timezone
today = timezone.now()

Use the timezone as shown below for a timezone-aware date time. The default is UTC:

from django.utils import timezone
today = timezone.now()

回答 16

来自“ howchoo”的Tyler撰写了一篇非常出色的文章,帮助我对Datetime Objects有了更好的了解,请点击以下链接

使用日期时间

本质上,我只是在两个datetime对象的末尾添加了以下内容

.replace(tzinfo=pytz.utc)

例:

import pytz
import datetime from datetime

date = datetime.now().replace(tzinfo=pytz.utc)

Tyler from ‘howchoo’ made a really great article that helped me get a better idea of the Datetime Objects, link below

Working with Datetime

essentially, I just added the following to the end of both my datetime objects

.replace(tzinfo=pytz.utc)

Example:

import pytz
import datetime from datetime

date = datetime.now().replace(tzinfo=pytz.utc)

回答 17

尝试pnp_datetime,所有使用和返回的时间都是带时区的,不会造成任何天真偏移和可感知偏移的问题。

>>> from pnp_datetime.pnp_datetime import Pnp_Datetime
>>>
>>> Pnp_Datetime.utcnow()
datetime.datetime(2020, 6, 5, 12, 26, 18, 958779, tzinfo=<UTC>)

try pnp_datetime, all the time been used and returned is with timezone, and will not cause any offset-naive and offset-aware issues.

>>> from pnp_datetime.pnp_datetime import Pnp_Datetime
>>>
>>> Pnp_Datetime.utcnow()
datetime.datetime(2020, 6, 5, 12, 26, 18, 958779, tzinfo=<UTC>)

回答 18

应该强调的是,从Python 3.6开始,您只需要标准的lib即可获取表示本地时间(操作系统的设置)的时区感知日期时间对象。使用astimezone()

import datetime

datetime.datetime(2010, 12, 25, 10, 59).astimezone()
# e.g.
# datetime.datetime(2010, 12, 25, 10, 59, tzinfo=datetime.timezone(datetime.timedelta(seconds=3600), 'Mitteleuropäische Zeit'))

datetime.datetime(2010, 12, 25, 12, 59).astimezone().isoformat()
# e.g.
# '2010-12-25T12:59:00+01:00'

# I'm on CET/CEST

(请参阅@ johnchen902的评论)。

It should be emphasized that since Python 3.6, you only need the standard lib to get a timezone aware datetime object that represents local time (the setting of your OS). Using astimezone()

import datetime

datetime.datetime(2010, 12, 25, 10, 59).astimezone()
# e.g.
# datetime.datetime(2010, 12, 25, 10, 59, tzinfo=datetime.timezone(datetime.timedelta(seconds=3600), 'Mitteleuropäische Zeit'))

datetime.datetime(2010, 12, 25, 12, 59).astimezone().isoformat()
# e.g.
# '2010-12-25T12:59:00+01:00'

# I'm on CET/CEST

(see @johnchen902’s comment). Note there’s a small caveat though, astimezone(None) gives aware datetime, unaware of DST.


如何将本地时间字符串转换为UTC?

问题:如何将本地时间字符串转换为UTC?

如何将本地时间的datetime 字符串转换为UTC时间字符串

我确定我之前已经做过,但是找不到它,因此SO希望将来可以帮助我(和其他人)做到这一点。

说明:例如,如果我2008-09-17 14:02:00在当地的时区(+10)中,我想生成一个具有相等UTC时间的字符串:2008-09-17 04:02:00

另外,从http://lucumr.pocoo.org/2011/7/15/eppur-si-muove/,请注意,一般来说这是不可能的,因为DST和其他问题没有从本地时间到本地的唯一转换。 UTC时间。

How do I convert a datetime string in local time to a string in UTC time?

I’m sure I’ve done this before, but can’t find it and SO will hopefully help me (and others) do that in future.

Clarification: For example, if I have 2008-09-17 14:02:00 in my local timezone (+10), I’d like to generate a string with the equivalent UTC time: 2008-09-17 04:02:00.

Also, from http://lucumr.pocoo.org/2011/7/15/eppur-si-muove/, note that in general this isn’t possible as with DST and other issues there is no unique conversion from local time to UTC time.


回答 0

首先,将字符串解析为一个简单的datetime对象。这是的实例,datetime.datetime没有附加的时区信息。请参阅文档以datetime.strptime获取有关解析日期字符串的信息。

使用pytz包含时区+ UTC完整列表的模块。弄清楚本地时区是什么,从中构造一个时区对象,然后将其操纵并附加到原始日期时间。

最后,使用datetime.astimezone()方法将日期时间转换为UTC。

使用本地时区“ America / Los_Angeles”的字符串“ 2001-2-3 10:11:12”的源代码:

import pytz, datetime
local = pytz.timezone ("America/Los_Angeles")
naive = datetime.datetime.strptime ("2001-2-3 10:11:12", "%Y-%m-%d %H:%M:%S")
local_dt = local.localize(naive, is_dst=None)
utc_dt = local_dt.astimezone(pytz.utc)

从那里,您可以strftime()根据需要使用该方法格式化UTC日期时间:

utc_dt.strftime ("%Y-%m-%d %H:%M:%S")

First, parse the string into a naive datetime object. This is an instance of datetime.datetime with no attached timezone information. See documentation for datetime.strptime for information on parsing the date string.

Use the pytz module, which comes with a full list of time zones + UTC. Figure out what the local timezone is, construct a timezone object from it, and manipulate and attach it to the naive datetime.

Finally, use datetime.astimezone() method to convert the datetime to UTC.

Source code, using local timezone “America/Los_Angeles”, for the string “2001-2-3 10:11:12”:

import pytz, datetime
local = pytz.timezone ("America/Los_Angeles")
naive = datetime.datetime.strptime ("2001-2-3 10:11:12", "%Y-%m-%d %H:%M:%S")
local_dt = local.localize(naive, is_dst=None)
utc_dt = local_dt.astimezone(pytz.utc)

From there, you can use the strftime() method to format the UTC datetime as needed:

utc_dt.strftime ("%Y-%m-%d %H:%M:%S")

回答 1

datetime模块的utcnow()函数可用于获取当前UTC时间。

>>> import datetime
>>> utc_datetime = datetime.datetime.utcnow()
>>> utc_datetime.strftime("%Y-%m-%d %H:%M:%S")
'2010-02-01 06:59:19'

正如汤姆在上面提到的链接:http : //lucumr.pocoo.org/2011/7/15/eppur-si-muove/ 所说:

UTC是没有夏令时的时区,并且仍然是过去没有配置更改的时区。

始终在UTC中测量和存储时间

如果您需要记录时间,将其分开存储。 不要存储本地时间+时区信息!

注意 -如果您的任何数据位于使用DST的区域中,请使用pytz并查看John Millikin的答案。

如果您想从给定的字符串中获取UTC时间,并且很幸运地处于世界上不使用DST的区域中,或者您的数据仅与UTC偏移而未应用DST:

->使用本地时间作为偏移值的基础:

>>> # Obtain the UTC Offset for the current system:
>>> UTC_OFFSET_TIMEDELTA = datetime.datetime.utcnow() - datetime.datetime.now()
>>> local_datetime = datetime.datetime.strptime("2008-09-17 14:04:00", "%Y-%m-%d %H:%M:%S")
>>> result_utc_datetime = local_datetime + UTC_OFFSET_TIMEDELTA
>>> result_utc_datetime.strftime("%Y-%m-%d %H:%M:%S")
'2008-09-17 04:04:00'

->或者,使用已知的偏移量,使用datetime.timedelta():

>>> UTC_OFFSET = 10
>>> result_utc_datetime = local_datetime - datetime.timedelta(hours=UTC_OFFSET)
>>> result_utc_datetime.strftime("%Y-%m-%d %H:%M:%S")
'2008-09-17 04:04:00'

更新:

由于python 3.2 datetime.timezone可用。您可以使用以下命令生成时区感知日期时间对象:

import datetime

timezone_aware_dt = datetime.datetime.now(datetime.timezone.utc)

如果您准备进行时区转换,请阅读以下内容:

https://medium.com/@eleroy/10-things-you-need-to-know-about-date-and-time-in-python-with-datetime-pytz-dateutil-timedelta-309bfbafb3f7

NOTE — As of 2020 you should not be using .utcnow() or .utcfromtimestamp(xxx). As you’ve presumably moved on to python3,you should be using timezone aware datetime objects.

>>> from datetime import timezone
>>> dt_now = datetime.now(tz=timezone.utc)
>>> dt_ts = datetime.fromtimestamp(1571595618.0, tz=timezone.utc)

for details see: see: https://blog.ganssle.io/articles/2019/11/utcnow.html

original answer (from 2010):

The datetime module’s utcnow() function can be used to obtain the current UTC time.

>>> import datetime
>>> utc_datetime = datetime.datetime.utcnow()
>>> utc_datetime.strftime("%Y-%m-%d %H:%M:%S")
'2010-02-01 06:59:19'

As the link mentioned above by Tom: http://lucumr.pocoo.org/2011/7/15/eppur-si-muove/ says:

UTC is a timezone without daylight saving time and still a timezone without configuration changes in the past.

Always measure and store time in UTC.

If you need to record where the time was taken, store that separately. Do not store the local time + timezone information!

NOTE – If any of your data is in a region that uses DST, use pytz and take a look at John Millikin’s answer.

If you want to obtain the UTC time from a given string and your lucky enough to be in a region in the world that either doesn’t use DST, or you have data that is only offset from UTC without DST applied:

–> using local time as the basis for the offset value:

>>> # Obtain the UTC Offset for the current system:
>>> UTC_OFFSET_TIMEDELTA = datetime.datetime.utcnow() - datetime.datetime.now()
>>> local_datetime = datetime.datetime.strptime("2008-09-17 14:04:00", "%Y-%m-%d %H:%M:%S")
>>> result_utc_datetime = local_datetime + UTC_OFFSET_TIMEDELTA
>>> result_utc_datetime.strftime("%Y-%m-%d %H:%M:%S")
'2008-09-17 04:04:00'

–> Or, from a known offset, using datetime.timedelta():

>>> UTC_OFFSET = 10
>>> result_utc_datetime = local_datetime - datetime.timedelta(hours=UTC_OFFSET)
>>> result_utc_datetime.strftime("%Y-%m-%d %H:%M:%S")
'2008-09-17 04:04:00'

UPDATE:

Since python 3.2 datetime.timezone is available. You can generate a timezone aware datetime object with the command below:

import datetime

timezone_aware_dt = datetime.datetime.now(datetime.timezone.utc)

If your ready to take on timezone conversions go read this:

https://medium.com/@eleroy/10-things-you-need-to-know-about-date-and-time-in-python-with-datetime-pytz-dateutil-timedelta-309bfbafb3f7


回答 2

感谢@rofly,从字符串到字符串的完整转换如下:

time.strftime("%Y-%m-%d %H:%M:%S", 
              time.gmtime(time.mktime(time.strptime("2008-09-17 14:04:00", 
                                                    "%Y-%m-%d %H:%M:%S"))))

我对time/ calendar函数的总结:

time.strptime
字符串->元组(未应用时区,因此匹配字符串)

time.mktime
当地时间元组->自纪元以来的秒数(始终为当地时间)

time.gmtime
自纪元以来的秒数-> UTC中的元组

calendar.timegm
以UTC表示的元组->自历元以来的秒数

time.localtime
自纪元以来的秒数->当地时区中的元组

Thanks @rofly, the full conversion from string to string is as follows:

time.strftime("%Y-%m-%d %H:%M:%S", 
              time.gmtime(time.mktime(time.strptime("2008-09-17 14:04:00", 
                                                    "%Y-%m-%d %H:%M:%S"))))

My summary of the time/calendar functions:

time.strptime
string –> tuple (no timezone applied, so matches string)

time.mktime
local time tuple –> seconds since epoch (always local time)

time.gmtime
seconds since epoch –> tuple in UTC

and

calendar.timegm
tuple in UTC –> seconds since epoch

time.localtime
seconds since epoch –> tuple in local timezone


回答 3

这是常见的Python时间转换的摘要。

某些方法会损失几分之一秒,并用(s)标记。ts = (d - epoch) / unit可以使用诸如的显式公式代替(感谢jfs)。

  • struct_time(UTC)→POSIX (s)
    calendar.timegm(struct_time)
  • 原始日期时间(本地)→POSIX (秒):(
    calendar.timegm(stz.localize(dt, is_dst=None).utctimetuple())
    DST转换期间的异常,请参阅jfs的注释)
  • 原始日期时间(UTC)→POSIX (s)
    calendar.timegm(dt.utctimetuple())
  • 知道日期时间→POSIX (S)
    calendar.timegm(dt.utctimetuple())
  • POSIX→struct_time(UTC,s):(
    time.gmtime(t)
    请参阅jfs的评论)
  • 原始日期时间(本地)→struct_time(UTC,s):(
    stz.localize(dt, is_dst=None).utctimetuple()
    DST转换期间的异常,请参阅jfs的注释)
  • 原始日期时间(UTC)→struct_time(UTC,s):
    dt.utctimetuple()
  • 知道日期时间→struct_time(UTC,s):
    dt.utctimetuple()
  • POSIX→原始日期时间(本地):(
    datetime.fromtimestamp(t, None)
    在某些情况下可能会失败,请参见下面来自jfs的评论)
  • struct_time(UTC)→原始日期时间(本地,s):
    datetime.datetime(struct_time[:6], tzinfo=UTC).astimezone(tz).replace(tzinfo=None)
    不能表示leap秒,请参见jfs的注释)
  • 原始日期时间(UTC)→原始日期时间(本地):
    dt.replace(tzinfo=UTC).astimezone(tz).replace(tzinfo=None)
  • 知道日期时间→天真日期时间(本地):
    dt.astimezone(tz).replace(tzinfo=None)
  • POSIX→原始日期时间(UTC):
    datetime.utcfromtimestamp(t)
  • struct_time(UTC)→原始日期时间(UTC,s):(
    datetime.datetime(*struct_time[:6])
    不能表示leap秒,请参阅jfs的注释)
  • 原始日期时间(本地)→原始日期时间(UTC):
    stz.localize(dt, is_dst=None).astimezone(UTC).replace(tzinfo=None)
    DST转换期间的异常,请参阅jfs的注释)
  • 知道日期时间→原始日期时间(UTC):
    dt.astimezone(UTC).replace(tzinfo=None)
  • POSIX→知道日期时间:
    datetime.fromtimestamp(t, tz)
    对于非pytz时区可能会失败)
  • struct_time(UTC)→感知日期时间(S)
    datetime.datetime(struct_time[:6], tzinfo=UTC).astimezone(tz)
    不能表示leap秒,请参阅jfs的注释)
  • 原始日期时间(本地)→感知日期时间:
    stz.localize(dt, is_dst=None)
    (DST转换期间的异常,请参阅jfs的注释)
  • 原始日期时间(UTC)→知道日期时间:
    dt.replace(tzinfo=UTC)

资料来源:taaviburns.ca

Here’s a summary of common Python time conversions.

Some methods drop fractions of seconds, and are marked with (s). An explicit formula such as ts = (d - epoch) / unit can be used instead (thanks jfs).

  • struct_time (UTC) → POSIX (s):
    calendar.timegm(struct_time)
  • Naïve datetime (local) → POSIX (s):
    calendar.timegm(stz.localize(dt, is_dst=None).utctimetuple())
    (exception during DST transitions, see comment from jfs)
  • Naïve datetime (UTC) → POSIX (s):
    calendar.timegm(dt.utctimetuple())
  • Aware datetime → POSIX (s):
    calendar.timegm(dt.utctimetuple())
  • POSIX → struct_time (UTC, s):
    time.gmtime(t)
    (see comment from jfs)
  • Naïve datetime (local) → struct_time (UTC, s):
    stz.localize(dt, is_dst=None).utctimetuple()
    (exception during DST transitions, see comment from jfs)
  • Naïve datetime (UTC) → struct_time (UTC, s):
    dt.utctimetuple()
  • Aware datetime → struct_time (UTC, s):
    dt.utctimetuple()
  • POSIX → Naïve datetime (local):
    datetime.fromtimestamp(t, None)
    (may fail in certain conditions, see comment from jfs below)
  • struct_time (UTC) → Naïve datetime (local, s):
    datetime.datetime(struct_time[:6], tzinfo=UTC).astimezone(tz).replace(tzinfo=None)
    (can’t represent leap seconds, see comment from jfs)
  • Naïve datetime (UTC) → Naïve datetime (local):
    dt.replace(tzinfo=UTC).astimezone(tz).replace(tzinfo=None)
  • Aware datetime → Naïve datetime (local):
    dt.astimezone(tz).replace(tzinfo=None)
  • POSIX → Naïve datetime (UTC):
    datetime.utcfromtimestamp(t)
  • struct_time (UTC) → Naïve datetime (UTC, s):
    datetime.datetime(*struct_time[:6])
    (can’t represent leap seconds, see comment from jfs)
  • Naïve datetime (local) → Naïve datetime (UTC):
    stz.localize(dt, is_dst=None).astimezone(UTC).replace(tzinfo=None)
    (exception during DST transitions, see comment from jfs)
  • Aware datetime → Naïve datetime (UTC):
    dt.astimezone(UTC).replace(tzinfo=None)
  • POSIX → Aware datetime:
    datetime.fromtimestamp(t, tz)
    (may fail for non-pytz timezones)
  • struct_time (UTC) → Aware datetime (s):
    datetime.datetime(struct_time[:6], tzinfo=UTC).astimezone(tz)
    (can’t represent leap seconds, see comment from jfs)
  • Naïve datetime (local) → Aware datetime:
    stz.localize(dt, is_dst=None)
    (exception during DST transitions, see comment from jfs)
  • Naïve datetime (UTC) → Aware datetime:
    dt.replace(tzinfo=UTC)

Source: taaviburns.ca


回答 4

def local_to_utc(t):
    secs = time.mktime(t)
    return time.gmtime(secs)

def utc_to_local(t):
    secs = calendar.timegm(t)
    return time.localtime(secs)

资料来源:http : //feihonghsu.blogspot.com/2008/02/converting-from-local-time-to-utc.html

bd808的用法示例:如果您的源是datetime.datetimeobject t,则调用为:

local_to_utc(t.timetuple())
def local_to_utc(t):
    secs = time.mktime(t)
    return time.gmtime(secs)

def utc_to_local(t):
    secs = calendar.timegm(t)
    return time.localtime(secs)

Source: http://feihonghsu.blogspot.com/2008/02/converting-from-local-time-to-utc.html

Example usage from bd808: If your source is a datetime.datetime object t, call as:

local_to_utc(t.timetuple())

回答 5

我对dateutil感到好运(广泛建议在SO上解决其他相关问题):

from datetime import *
from dateutil import *
from dateutil.tz import *

# METHOD 1: Hardcode zones:
utc_zone = tz.gettz('UTC')
local_zone = tz.gettz('America/Chicago')
# METHOD 2: Auto-detect zones:
utc_zone = tz.tzutc()
local_zone = tz.tzlocal()

# Convert time string to datetime
local_time = datetime.strptime("2008-09-17 14:02:00", '%Y-%m-%d %H:%M:%S')

# Tell the datetime object that it's in local time zone since 
# datetime objects are 'naive' by default
local_time = local_time.replace(tzinfo=local_zone)
# Convert time to UTC
utc_time = local_time.astimezone(utc_zone)
# Generate UTC time string
utc_string = utc_time.strftime('%Y-%m-%d %H:%M:%S')

(代码从此答案派生而来,将UTC datetime字符串转换为本地datetime

I’m having good luck with dateutil (which is widely recommended on SO for other related questions):

from datetime import *
from dateutil import *
from dateutil.tz import *

# METHOD 1: Hardcode zones:
utc_zone = tz.gettz('UTC')
local_zone = tz.gettz('America/Chicago')
# METHOD 2: Auto-detect zones:
utc_zone = tz.tzutc()
local_zone = tz.tzlocal()

# Convert time string to datetime
local_time = datetime.strptime("2008-09-17 14:02:00", '%Y-%m-%d %H:%M:%S')

# Tell the datetime object that it's in local time zone since 
# datetime objects are 'naive' by default
local_time = local_time.replace(tzinfo=local_zone)
# Convert time to UTC
utc_time = local_time.astimezone(utc_zone)
# Generate UTC time string
utc_string = utc_time.strftime('%Y-%m-%d %H:%M:%S')

(Code was derived from this answer to Convert UTC datetime string to local datetime)


回答 6

pytz的另一个示例,但包含localize(),这节省了我的时间。

import pytz, datetime
utc = pytz.utc
fmt = '%Y-%m-%d %H:%M:%S'
amsterdam = pytz.timezone('Europe/Amsterdam')

dt = datetime.datetime.strptime("2012-04-06 10:00:00", fmt)
am_dt = amsterdam.localize(dt)
print am_dt.astimezone(utc).strftime(fmt)
'2012-04-06 08:00:00'

One more example with pytz, but includes localize(), which saved my day.

import pytz, datetime
utc = pytz.utc
fmt = '%Y-%m-%d %H:%M:%S'
amsterdam = pytz.timezone('Europe/Amsterdam')

dt = datetime.datetime.strptime("2012-04-06 10:00:00", fmt)
am_dt = amsterdam.localize(dt)
print am_dt.astimezone(utc).strftime(fmt)
'2012-04-06 08:00:00'

回答 7

我在python-dateutil上获得了最大的成功:

from dateutil import tz

def datetime_to_utc(date):
    """Returns date in UTC w/o tzinfo"""
    return date.astimezone(tz.gettz('UTC')).replace(tzinfo=None) if date.tzinfo else date

I’ve had the most success with python-dateutil:

from dateutil import tz

def datetime_to_utc(date):
    """Returns date in UTC w/o tzinfo"""
    return date.astimezone(tz.gettz('UTC')).replace(tzinfo=None) if date.tzinfo else date

回答 8

import time

import datetime

def Local2UTC(LocalTime):

    EpochSecond = time.mktime(LocalTime.timetuple())
    utcTime = datetime.datetime.utcfromtimestamp(EpochSecond)

    return utcTime

>>> LocalTime = datetime.datetime.now()

>>> UTCTime = Local2UTC(LocalTime)

>>> LocalTime.ctime()

'Thu Feb  3 22:33:46 2011'

>>> UTCTime.ctime()

'Fri Feb  4 05:33:46 2011'
import time

import datetime

def Local2UTC(LocalTime):

    EpochSecond = time.mktime(LocalTime.timetuple())
    utcTime = datetime.datetime.utcfromtimestamp(EpochSecond)

    return utcTime

>>> LocalTime = datetime.datetime.now()

>>> UTCTime = Local2UTC(LocalTime)

>>> LocalTime.ctime()

'Thu Feb  3 22:33:46 2011'

>>> UTCTime.ctime()

'Fri Feb  4 05:33:46 2011'

回答 9

如果您更喜欢datetime.datetime:

dt = datetime.strptime("2008-09-17 14:04:00","%Y-%m-%d %H:%M:%S")
utc_struct_time = time.gmtime(time.mktime(dt.timetuple()))
utc_dt = datetime.fromtimestamp(time.mktime(utc_struct_time))
print dt.strftime("%Y-%m-%d %H:%M:%S")

if you prefer datetime.datetime:

dt = datetime.strptime("2008-09-17 14:04:00","%Y-%m-%d %H:%M:%S")
utc_struct_time = time.gmtime(time.mktime(dt.timetuple()))
utc_dt = datetime.fromtimestamp(time.mktime(utc_struct_time))
print dt.strftime("%Y-%m-%d %H:%M:%S")

回答 10

简单

我这样做是这样的:

>>> utc_delta = datetime.utcnow()-datetime.now()
>>> utc_time = datetime(2008, 9, 17, 14, 2, 0) + utc_delta
>>> print(utc_time)
2008-09-17 19:01:59.999996

花式实施

如果想花哨的话,可以将其变成仿函数:

class to_utc():
    utc_delta = datetime.utcnow() - datetime.now()

    def __call__(cls, t):
        return t + cls.utc_delta

结果:

>>> utc_converter = to_utc()
>>> print(utc_converter(datetime(2008, 9, 17, 14, 2, 0)))
2008-09-17 19:01:59.999996

Simple

I did it like this:

>>> utc_delta = datetime.utcnow()-datetime.now()
>>> utc_time = datetime(2008, 9, 17, 14, 2, 0) + utc_delta
>>> print(utc_time)
2008-09-17 19:01:59.999996

Fancy Implementation

If you want to get fancy, you can turn this into a functor:

class to_utc():
    utc_delta = datetime.utcnow() - datetime.now()

    def __call__(cls, t):
        return t + cls.utc_delta

Result:

>>> utc_converter = to_utc()
>>> print(utc_converter(datetime(2008, 9, 17, 14, 2, 0)))
2008-09-17 19:01:59.999996

回答 11

您可以执行以下操作:

>>> from time import strftime, gmtime, localtime
>>> strftime('%H:%M:%S', gmtime()) #UTC time
>>> strftime('%H:%M:%S', localtime()) # localtime

You can do it with:

>>> from time import strftime, gmtime, localtime
>>> strftime('%H:%M:%S', gmtime()) #UTC time
>>> strftime('%H:%M:%S', localtime()) # localtime

回答 12

怎么样 –

time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime(seconds))

如果以秒为单位None,则将本地时间转换为UTC时间,否则将传入的时间转换为UTC。

How about –

time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime(seconds))

if seconds is None then it converts the local time to UTC time else converts the passed in time to UTC.


回答 13

用于避开日光节约等。

上述答案都没有特别帮助我。以下代码适用于GMT。

def get_utc_from_local(date_time, local_tz=None):
    assert date_time.__class__.__name__ == 'datetime'
    if local_tz is None:
        local_tz = pytz.timezone(settings.TIME_ZONE) # Django eg, "Europe/London"
    local_time = local_tz.normalize(local_tz.localize(date_time))
    return local_time.astimezone(pytz.utc)

import pytz
from datetime import datetime

summer_11_am = datetime(2011, 7, 1, 11)
get_utc_from_local(summer_11_am)
>>>datetime.datetime(2011, 7, 1, 10, 0, tzinfo=<UTC>)

winter_11_am = datetime(2011, 11, 11, 11)
get_utc_from_local(winter_11_am)
>>>datetime.datetime(2011, 11, 11, 11, 0, tzinfo=<UTC>)

For getting around day-light saving, etc.

None of the above answers particularly helped me. The code below works for GMT.

def get_utc_from_local(date_time, local_tz=None):
    assert date_time.__class__.__name__ == 'datetime'
    if local_tz is None:
        local_tz = pytz.timezone(settings.TIME_ZONE) # Django eg, "Europe/London"
    local_time = local_tz.normalize(local_tz.localize(date_time))
    return local_time.astimezone(pytz.utc)

import pytz
from datetime import datetime

summer_11_am = datetime(2011, 7, 1, 11)
get_utc_from_local(summer_11_am)
>>>datetime.datetime(2011, 7, 1, 10, 0, tzinfo=<UTC>)

winter_11_am = datetime(2011, 11, 11, 11)
get_utc_from_local(winter_11_am)
>>>datetime.datetime(2011, 11, 11, 11, 0, tzinfo=<UTC>)

回答 14

使用http://crsmithdev.com/arrow/

arrowObj = arrow.Arrow.strptime('2017-02-20 10:00:00', '%Y-%m-%d %H:%M:%S' , 'US/Eastern')

arrowObj.to('UTC') or arrowObj.to('local') 

这个图书馆让生活变得轻松:)

Using http://crsmithdev.com/arrow/

arrowObj = arrow.Arrow.strptime('2017-02-20 10:00:00', '%Y-%m-%d %H:%M:%S' , 'US/Eastern')

arrowObj.to('UTC') or arrowObj.to('local') 

This library makes life easy :)


回答 15

我在这里找到了另一个问题的最佳答案。它仅使用python内置库,不需要您输入本地时区(在我的情况下是要求)

import time
import calendar

local_time = time.strptime("2018-12-13T09:32:00.000", "%Y-%m-%dT%H:%M:%S.%f")
local_seconds = time.mktime(local_time)
utc_time = time.gmtime(local_seconds)

我在此重新发布答案,因为此问题会在Google中弹出,而不是根据搜索关键字在链接的问题中弹出。

I found the best answer on another question here. It only uses python built-in libraries and does not require you to input your local timezone (a requirement in my case)

import time
import calendar

local_time = time.strptime("2018-12-13T09:32:00.000", "%Y-%m-%dT%H:%M:%S.%f")
local_seconds = time.mktime(local_time)
utc_time = time.gmtime(local_seconds)

I’m reposting the answer here since this question pops up in google instead of the linked question depending on the search keywords.


回答 16

我的一个项目中有以下代码:

from datetime import datetime
## datetime.timezone works in newer versions of python
try:
    from datetime import timezone
    utc_tz = timezone.utc
except:
    import pytz
    utc_tz = pytz.utc

def _to_utc_date_string(ts):
    # type (Union[date,datetime]]) -> str
    """coerce datetimes to UTC (assume localtime if nothing is given)"""
    if (isinstance(ts, datetime)):
        try:
            ## in python 3.6 and higher, ts.astimezone() will assume a
            ## naive timestamp is localtime (and so do we)
            ts = ts.astimezone(utc_tz)
        except:
            ## in python 2.7 and 3.5, ts.astimezone() will fail on
            ## naive timestamps, but we'd like to assume they are
            ## localtime
            import tzlocal
            ts = tzlocal.get_localzone().localize(ts).astimezone(utc_tz)
    return ts.strftime("%Y%m%dT%H%M%SZ")

I have this code in one of my projects:

from datetime import datetime
## datetime.timezone works in newer versions of python
try:
    from datetime import timezone
    utc_tz = timezone.utc
except:
    import pytz
    utc_tz = pytz.utc

def _to_utc_date_string(ts):
    # type (Union[date,datetime]]) -> str
    """coerce datetimes to UTC (assume localtime if nothing is given)"""
    if (isinstance(ts, datetime)):
        try:
            ## in python 3.6 and higher, ts.astimezone() will assume a
            ## naive timestamp is localtime (and so do we)
            ts = ts.astimezone(utc_tz)
        except:
            ## in python 2.7 and 3.5, ts.astimezone() will fail on
            ## naive timestamps, but we'd like to assume they are
            ## localtime
            import tzlocal
            ts = tzlocal.get_localzone().localize(ts).astimezone(utc_tz)
    return ts.strftime("%Y%m%dT%H%M%SZ")

回答 17

在python3中:

pip install python-dateutil

from dateutil.parser import tz

mydt.astimezone(tz.gettz('UTC')).replace(tzinfo=None) 

In python3:

pip install python-dateutil

from dateutil.parser import tz

mydt.astimezone(tz.gettz('UTC')).replace(tzinfo=None) 

回答 18

怎么样 –

time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime(seconds))

如果以秒为单位None,则将本地时间转换为UTC时间,否则将传入的时间转换为UTC。

How about –

time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime(seconds))

if seconds is None then it converts the local time to UTC time else converts the passed in time to UTC.


无法减去天真偏移和可感知偏移的日期时间

问题:无法减去天真偏移和可感知偏移的日期时间

timestamptz在PostgreSQL中有一个时区识别字段。当我从表中提取数据时,我想现在减去时间,以便确定时间。

我遇到的问题是,无论是datetime.datetime.now()datetime.datetime.utcnow()似乎回到时区不知道时间戳,这导致我得到这个错误:

TypeError: can't subtract offset-naive and offset-aware datetimes 

有没有一种方法可以避免这种情况(最好不要使用第三方模块)。

编辑:感谢您的建议,但是尝试调整时区似乎给了我错误..所以我只打算在PG中使用不知道时区的时间戳,并始终使用以下命令插入:

NOW() AT TIME ZONE 'UTC'

这样,默认情况下,我所有的时间戳都是UTC(即使这样做比较烦人)。

I have a timezone aware timestamptz field in PostgreSQL. When I pull data from the table, I then want to subtract the time right now so I can get it’s age.

The problem I’m having is that both datetime.datetime.now() and datetime.datetime.utcnow() seem to return timezone unaware timestamps, which results in me getting this error:

TypeError: can't subtract offset-naive and offset-aware datetimes 

Is there a way to avoid this (preferably without a third-party module being used).

EDIT: Thanks for the suggestions, however trying to adjust the timezone seems to give me errors.. so I’m just going to use timezone unaware timestamps in PG and always insert using:

NOW() AT TIME ZONE 'UTC'

That way all my timestamps are UTC by default (even though it’s more annoying to do this).


回答 0

您是否尝试删除时区意识?

来自http://pytz.sourceforge.net/

naive = dt.replace(tzinfo=None)

可能还必须添加时区转换。

编辑:请注意这个答案的年龄。以下是Python 3的答案。

have you tried to remove the timezone awareness?

from http://pytz.sourceforge.net/

naive = dt.replace(tzinfo=None)

may have to add time zone conversion as well.

edit: Please be aware the age of this answer. An answer involving ADDing the timezone info instead of removing it in python 3 is below. https://stackoverflow.com/a/25662061/93380


回答 1

正确的解决方案是添加时区信息,例如,将当前时间作为Python 3中已知的datetime对象获取:

from datetime import datetime, timezone

now = datetime.now(timezone.utc)

在较旧的Python版本上,您可以utc自己定义tzinfo对象(例如datetime docs中的示例):

from datetime import tzinfo, timedelta, datetime

ZERO = timedelta(0)

class UTC(tzinfo):
  def utcoffset(self, dt):
    return ZERO
  def tzname(self, dt):
    return "UTC"
  def dst(self, dt):
    return ZERO

utc = UTC()

然后:

now = datetime.now(utc)

The correct solution is to add the timezone info e.g., to get the current time as an aware datetime object in Python 3:

from datetime import datetime, timezone

now = datetime.now(timezone.utc)

On older Python versions, you could define the utc tzinfo object yourself (example from datetime docs):

from datetime import tzinfo, timedelta, datetime

ZERO = timedelta(0)

class UTC(tzinfo):
  def utcoffset(self, dt):
    return ZERO
  def tzname(self, dt):
    return "UTC"
  def dst(self, dt):
    return ZERO

utc = UTC()

then:

now = datetime.now(utc)

回答 2

我知道有人专门使用Django作为抽象此类数据库交互的接口。Django提供了可用于此目的的实用程序:

from django.utils import timezone
now_aware = timezone.now()

您确实需要设置基本的Django设置基础结构,即使您只是使用这种类型的界面(在设置中,也需要包括在内USE_TZ=True以获取已知的日期时间)。

就其本身而言,这可能还远远不足以激发您使用Django作为界面,但是还有许多其他好处。另一方面,如果您是因为要破坏Django应用(如我所做的那样)而在这里偶然发现的,那么这可能会有所帮助…

I know some people use Django specifically as an interface to abstract this type of database interaction. Django provides utilities that can be used for this:

from django.utils import timezone
now_aware = timezone.now()

You do need to set up a basic Django settings infrastructure, even if you are just using this type of interface (in settings, you need to include USE_TZ=True to get an aware datetime).

By itself, this is probably nowhere near enough to motivate you to use Django as an interface, but there are many other perks. On the other hand, if you stumbled here because you were mangling your Django app (as I did), then perhaps this helps…


回答 3

这是一个非常简单明了的解决方案
两行代码

# First we obtain de timezone info o some datatime variable    

tz_info = your_timezone_aware_variable.tzinfo

# Now we can subtract two variables using the same time zone info
# For instance
# Lets obtain the Now() datetime but for the tz_info we got before

diff = datetime.datetime.now(tz_info)-your_timezone_aware_variable

结论:您必须使用相同的时间信息来管理日期时间变量

This is a very simple and clear solution
Two lines of code

# First we obtain de timezone info o some datatime variable    

tz_info = your_timezone_aware_variable.tzinfo

# Now we can subtract two variables using the same time zone info
# For instance
# Lets obtain the Now() datetime but for the tz_info we got before

diff = datetime.datetime.now(tz_info)-your_timezone_aware_variable

Conclusion: You must mange your datetime variables with the same time info


回答 4

psycopg2模块具有自己的时区定义,因此我最终围绕utcnow编写了自己的包装器:

def pg_utcnow():
    import psycopg2
    return datetime.utcnow().replace(
        tzinfo=psycopg2.tz.FixedOffsetTimezone(offset=0, name=None))

并且只pg_utcnow在需要当前时间与PostgreSQL比较时使用timestamptz

The psycopg2 module has its own timezone definitions, so I ended up writing my own wrapper around utcnow:

def pg_utcnow():
    import psycopg2
    return datetime.utcnow().replace(
        tzinfo=psycopg2.tz.FixedOffsetTimezone(offset=0, name=None))

and just use pg_utcnow whenever you need the current time to compare against a PostgreSQL timestamptz


回答 5

我也面临同样的问题。经过大量搜索之后,我找到了解决方案。

问题是,当我们从模型或表单获取datetime对象时,它是偏移量感知的;如果通过系统获取时间,则它是偏移量天真的

所以我要做的是使用timezone.now()获得当前时间,并从django.utils import timezone导入时区,并将USE_TZ = True放入项目设置文件中。

I also faced the same problem. Then I found a solution after a lot of searching .

The problem was that when we get the datetime object from model or form it is offset aware and if we get the time by system it is offset naive.

So what I did is I got the current time using timezone.now() and import the timezone by from django.utils import timezone and put the USE_TZ = True in your project settings file.


回答 6

我想出了一个超简单的解决方案:

import datetime

def calcEpochSec(dt):
    epochZero = datetime.datetime(1970,1,1,tzinfo = dt.tzinfo)
    return (dt - epochZero).total_seconds()

它适用于时区感知和时区原始日期时间值。并且不需要其他库或数据库解决方法。

I came up with an ultra-simple solution:

import datetime

def calcEpochSec(dt):
    epochZero = datetime.datetime(1970,1,1,tzinfo = dt.tzinfo)
    return (dt - epochZero).total_seconds()

It works with both timezone-aware and timezone-naive datetime values. And no additional libraries or database workarounds are required.


回答 7

我发现timezone.make_aware(datetime.datetime.now())在Django中很有帮助(我在1.9.1上)。不幸的是,您不能简单地使datetime对象具有偏移意识timetz()。您必须做一个,datetime并在此基础上进行比较。

I’ve found timezone.make_aware(datetime.datetime.now()) is helpful in django (I’m on 1.9.1). Unfortunately you can’t simply make a datetime object offset-aware, then timetz() it. You have to make a datetime and make comparisons based on that.


回答 8

有一些紧迫的原因导致您无法在PostgreSQL本身中处理年龄计算吗?就像是

select *, age(timeStampField) as timeStampAge from myTable

Is there some pressing reason why you can’t handle the age calculation in PostgreSQL itself? Something like

select *, age(timeStampField) as timeStampAge from myTable

回答 9

我知道这很旧,但只是想我会添加我的解决方案,以防万一有人觉得有用。

我想将本地原始日期时间与时间服务器的已知日期时间进行比较。我基本上使用感知的datetime对象创建了一个新的朴素的datetime对象。这有点骇人听闻,看起来并不漂亮,但是可以完成工作。

import ntplib
import datetime
from datetime import timezone

def utc_to_local(utc_dt):
    return utc_dt.replace(tzinfo=timezone.utc).astimezone(tz=None)    

try:
    ntpt = ntplib.NTPClient()
    response = ntpt.request('pool.ntp.org')
    date = utc_to_local(datetime.datetime.utcfromtimestamp(response.tx_time))
    sysdate = datetime.datetime.now()

…软糖来了…

    temp_date = datetime.datetime(int(str(date)[:4]),int(str(date)[5:7]),int(str(date)[8:10]),int(str(date)[11:13]),int(str(date)[14:16]),int(str(date)[17:19]))
    dt_delta = temp_date-sysdate
except Exception:
    print('Something went wrong :-(')

I know this is old, but just thought I would add my solution just in case someone finds it useful.

I wanted to compare the local naive datetime with an aware datetime from a timeserver. I basically created a new naive datetime object using the aware datetime object. It’s a bit of a hack and doesn’t look very pretty but gets the job done.

import ntplib
import datetime
from datetime import timezone

def utc_to_local(utc_dt):
    return utc_dt.replace(tzinfo=timezone.utc).astimezone(tz=None)    

try:
    ntpt = ntplib.NTPClient()
    response = ntpt.request('pool.ntp.org')
    date = utc_to_local(datetime.datetime.utcfromtimestamp(response.tx_time))
    sysdate = datetime.datetime.now()

…here comes the fudge…

    temp_date = datetime.datetime(int(str(date)[:4]),int(str(date)[5:7]),int(str(date)[8:10]),int(str(date)[11:13]),int(str(date)[14:16]),int(str(date)[17:19]))
    dt_delta = temp_date-sysdate
except Exception:
    print('Something went wrong :-(')

Python将来五分钟创建unix时间戳

问题:Python将来五分钟创建unix时间戳

我必须在将来的5分钟内创建一个“ Expires”值,但是我必须以UNIX Timestamp格式提供它。到目前为止,我已经掌握了这个功能,但似乎有点。

def expires():
    '''return a UNIX style timestamp representing 5 minutes from now'''
    epoch = datetime.datetime(1970, 1, 1)
    seconds_in_a_day = 60 * 60 * 24
    five_minutes = datetime.timedelta(seconds=5*60)
    five_minutes_from_now = datetime.datetime.now() + five_minutes
    since_epoch = five_minutes_from_now - epoch
    return since_epoch.days * seconds_in_a_day + since_epoch.seconds

是否有为我转换时间戳的模块或功能?

I have to create an “Expires” value 5 minutes in the future, but I have to supply it in UNIX Timestamp format. I have this so far, but it seems like a hack.

def expires():
    '''return a UNIX style timestamp representing 5 minutes from now'''
    epoch = datetime.datetime(1970, 1, 1)
    seconds_in_a_day = 60 * 60 * 24
    five_minutes = datetime.timedelta(seconds=5*60)
    five_minutes_from_now = datetime.datetime.now() + five_minutes
    since_epoch = five_minutes_from_now - epoch
    return since_epoch.days * seconds_in_a_day + since_epoch.seconds

Is there a module or function that does the timestamp conversion for me?


回答 0

另一种方法是使用calendar.timegm

future = datetime.datetime.utcnow() + datetime.timedelta(minutes=5)
return calendar.timegm(future.timetuple())

它比%s标记为strftime(在Windows上不起作用)更可移植。

Another way is to use calendar.timegm:

future = datetime.datetime.utcnow() + datetime.timedelta(minutes=5)
return calendar.timegm(future.timetuple())

It’s also more portable than %s flag to strftime (which doesn’t work on Windows).


回答 1

现在,在Python> = 3.3中,您只需调用timestamp()方法即可将时间戳记作为浮点数获取。

import datetime
current_time = datetime.datetime.now(datetime.timezone.utc)
unix_timestamp = current_time.timestamp() # works if Python >= 3.3

unix_timestamp_plus_5_min = unix_timestamp + (5 * 60)  # 5 min * 60 seconds

Now in Python >= 3.3 you can just call the timestamp() method to get the timestamp as a float.

import datetime
current_time = datetime.datetime.now(datetime.timezone.utc)
unix_timestamp = current_time.timestamp() # works if Python >= 3.3

unix_timestamp_plus_5_min = unix_timestamp + (5 * 60)  # 5 min * 60 seconds

回答 2

刚发现,它甚至更短。

import time
def expires():
    '''return a UNIX style timestamp representing 5 minutes from now'''
    return int(time.time()+300)

Just found this, and its even shorter.

import time
def expires():
    '''return a UNIX style timestamp representing 5 minutes from now'''
    return int(time.time()+300)

回答 3

这是您需要的:

import time
import datetime
n = datetime.datetime.now()
unix_time = time.mktime(n.timetuple())

This is what you need:

import time
import datetime
n = datetime.datetime.now()
unix_time = time.mktime(n.timetuple())

回答 4

您可以使用datetime.strftime以下%s格式的字符串以Epoch格式获取时间:

def expires():
    future = datetime.datetime.now() + datetime.timedelta(seconds=5*60)
    return int(future.strftime("%s"))

注意:此方法仅在linux下有效,而此方法不适用于时区。

You can use datetime.strftime to get the time in Epoch form, using the %s format string:

def expires():
    future = datetime.datetime.now() + datetime.timedelta(seconds=5*60)
    return int(future.strftime("%s"))

Note: This only works under linux, and this method doesn’t work with timezones.


回答 5

这是一个datetime从日期时间对象转换为posix时间戳记的基于基础的解决方案:

future = datetime.datetime.utcnow() + datetime.timedelta(minutes=5)
return (future - datetime.datetime(1970, 1, 1)).total_seconds()

在Python中将datetime.date转换为UTC时间戳,请参见更多详细信息。

Here’s a less broken datetime-based solution to convert from datetime object to posix timestamp:

future = datetime.datetime.utcnow() + datetime.timedelta(minutes=5)
return (future - datetime.datetime(1970, 1, 1)).total_seconds()

See more details at Converting datetime.date to UTC timestamp in Python.


回答 6

def in_unix(input):
  start = datetime.datetime(year=1970,month=1,day=1)
  diff = input - start
  return diff.total_seconds()
def in_unix(input):
  start = datetime.datetime(year=1970,month=1,day=1)
  diff = input - start
  return diff.total_seconds()

回答 7

关键是在开始转换之前,确保您使用的所有日期都在utc时区中。请参阅http://pytz.sourceforge.net/了解如何正确执行此操作。通过对utc进行标准化,可以消除夏令时转换的歧义。然后,您可以安全地使用timedelta来计算距Unix纪元的距离,然后将其转换为秒或毫秒。

请注意,生成的unix时间戳本身就是UTC时区。如果您希望查看本地化时区中的时间戳,则需要进行另一次转换。

另请注意,这仅适用于1970年之后的日期。

   import datetime
   import pytz

   UNIX_EPOCH = datetime.datetime(1970, 1, 1, 0, 0, tzinfo = pytz.utc)
   def EPOCH(utc_datetime):
      delta = utc_datetime - UNIX_EPOCH
      seconds = delta.total_seconds()
      ms = seconds * 1000
      return ms

The key is to ensure all the dates you are using are in the utc timezone before you start converting. See http://pytz.sourceforge.net/ to learn how to do that properly. By normalizing to utc, you eliminate the ambiguity of daylight savings transitions. Then you can safely use timedelta to calculate distance from the unix epoch, and then convert to seconds or milliseconds.

Note that the resulting unix timestamp is itself in the UTC timezone. If you wish to see the timestamp in a localized timezone, you will need to make another conversion.

Also note that this will only work for dates after 1970.

   import datetime
   import pytz

   UNIX_EPOCH = datetime.datetime(1970, 1, 1, 0, 0, tzinfo = pytz.utc)
   def EPOCH(utc_datetime):
      delta = utc_datetime - UNIX_EPOCH
      seconds = delta.total_seconds()
      ms = seconds * 1000
      return ms

回答 8

以下内容基于上述答案(加上毫秒数的更正),并datetime.timestamp()在使用时区时针对3.3之前的Python 3进行了仿真。

def datetime_timestamp(datetime):
    '''
    Equivalent to datetime.timestamp() for pre-3.3
    '''
    try:
        return datetime.timestamp()
    except AttributeError:
        utc_datetime = datetime.astimezone(utc)
        return timegm(utc_datetime.timetuple()) + utc_datetime.microsecond / 1e6

要严格按照要求回答问题,您需要:

datetime_timestamp(my_datetime) + 5 * 60

datetime_timestampsimple-date的一部分。但是,如果您使用的是该软件包,则可能要输入:

SimpleDate(my_datetime).timestamp + 5 * 60

可以为my_datetime处理更多格式/类型。

The following is based on the answers above (plus a correction for the milliseconds) and emulates datetime.timestamp() for Python 3 before 3.3 when timezones are used.

def datetime_timestamp(datetime):
    '''
    Equivalent to datetime.timestamp() for pre-3.3
    '''
    try:
        return datetime.timestamp()
    except AttributeError:
        utc_datetime = datetime.astimezone(utc)
        return timegm(utc_datetime.timetuple()) + utc_datetime.microsecond / 1e6

To strictly answer the question as asked, you’d want:

datetime_timestamp(my_datetime) + 5 * 60

datetime_timestamp is part of simple-date. But if you were using that package you’d probably type:

SimpleDate(my_datetime).timestamp + 5 * 60

which handles many more formats / types for my_datetime.


回答 9

def expiration_time():
    import datetime,calendar
    timestamp = calendar.timegm(datetime.datetime.now().timetuple())
    returnValue = datetime.timedelta(minutes=5).total_seconds() + timestamp
    return returnValue
def expiration_time():
    import datetime,calendar
    timestamp = calendar.timegm(datetime.datetime.now().timetuple())
    returnValue = datetime.timedelta(minutes=5).total_seconds() + timestamp
    return returnValue

回答 10

请注意,timedelta.total_seconds()适用于python-2.7 +的解决方案。使用calendar.timegm(future.utctimetuple())较低版本的Python。

Note that solutions with timedelta.total_seconds() work on python-2.7+. Use calendar.timegm(future.utctimetuple()) for lower versions of Python.