标签归档:datetime

无法比较幼稚和知道的datetime.now()<= Challenge.datetime_end

问题:无法比较幼稚和知道的datetime.now()<= Challenge.datetime_end

我正在尝试使用比较运算符将当前日期和时间与模型中指定的日期和时间进行比较:

if challenge.datetime_start <= datetime.now() <= challenge.datetime_end:

脚本错误如下:

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

这些模型如下所示:

class Fundraising_Challenge(models.Model):
    name = models.CharField(max_length=100)
    datetime_start = models.DateTimeField()
    datetime_end = models.DateTimeField()

我也有使用区域设置日期和时间的django。

我找不到的是django用于DateTimeField()的格式。天真还是知道?以及如何获取datetime.now()来识别语言环境datetime?

I am trying to compare the current date and time with dates and times specified in models using comparison operators:

if challenge.datetime_start <= datetime.now() <= challenge.datetime_end:

The script errors out with:

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

The models look like this:

class Fundraising_Challenge(models.Model):
    name = models.CharField(max_length=100)
    datetime_start = models.DateTimeField()
    datetime_end = models.DateTimeField()

I also have django using locale date and times.

What I haven’t been able to find is the format django uses for DateTimeField(). Is it naive or aware? And how do I get datetime.now() to recognize locale datetime?


回答 0

默认情况下,该datetime对象naive位于Python中,因此您需要将它们都设为天真或感知datetime对象。可以使用以下方法完成:

import datetime
import pytz

utc=pytz.UTC

challenge.datetime_start = utc.localize(challenge.datetime_start) 
challenge.datetime_end = utc.localize(challenge.datetime_end) 
# now both the datetime objects are aware, and you can compare them

注意:这将引发一个ValueErrorif tzinfo值。如果您不确定,请使用

start_time = challenge.datetime_start.replace(tzinfo=utc)
end_time = challenge.datetime_end.replace(tzinfo=utc)

顺便说一句,您可以在带有时区信息的datetime.datetime对象中格式化UNIX时间戳,如下所示

d = datetime.datetime.utcfromtimestamp(int(unix_timestamp))
d_with_tz = datetime.datetime(
    year=d.year,
    month=d.month,
    day=d.day,
    hour=d.hour,
    minute=d.minute,
    second=d.second,
    tzinfo=pytz.UTC)

By default, the datetime object is naive in Python, so you need to make both of them either naive or aware datetime objects. This can be done using:

import datetime
import pytz

utc=pytz.UTC

challenge.datetime_start = utc.localize(challenge.datetime_start) 
challenge.datetime_end = utc.localize(challenge.datetime_end) 
# now both the datetime objects are aware, and you can compare them

Note: This would raise a ValueError if tzinfo is already set. If you are not sure about that, just use

start_time = challenge.datetime_start.replace(tzinfo=utc)
end_time = challenge.datetime_end.replace(tzinfo=utc)

BTW, you could format a UNIX timestamp in datetime.datetime object with timezone info as following

d = datetime.datetime.utcfromtimestamp(int(unix_timestamp))
d_with_tz = datetime.datetime(
    year=d.year,
    month=d.month,
    day=d.day,
    hour=d.hour,
    minute=d.minute,
    second=d.second,
    tzinfo=pytz.UTC)

回答 1

datetime.datetime.now 不了解时区。

Django为此提供了一个帮助程序,它需要 pytz

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

你应该能够比较nowchallenge.datetime_start

datetime.datetime.now is not timezone aware.

Django comes with a helper for this, which requires pytz

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

You should be able to compare now to challenge.datetime_start


回答 2

一行代码解决方案

if timezone_aware_var <= datetime.datetime.now(timezone_aware_var.tzinfo):
    pass #some code

解释版

# Timezone info of your timezone aware variable
timezone = your_timezone_aware_variable.tzinfo

# Current datetime for the timezone of your variable
now_in_timezone = datetime.datetime.now(timezone)

# Now you can do a fair comparison, both datetime variables have the same time zone
if your_timezone_aware_variable <= now_in_timezone:
    pass #some code

摘要

您必须将时区信息添加到now()日期时间。
但是,您必须添加参考变量的相同时区。这就是为什么我首先阅读该tzinfo属性的原因。

One line of code solution

if timezone_aware_var <= datetime.datetime.now(timezone_aware_var.tzinfo):
    pass #some code

Explained version

# Timezone info of your timezone aware variable
timezone = your_timezone_aware_variable.tzinfo

# Current datetime for the timezone of your variable
now_in_timezone = datetime.datetime.now(timezone)

# Now you can do a fair comparison, both datetime variables have the same time zone
if your_timezone_aware_variable <= now_in_timezone:
    pass #some code

Summary

You must add the timezone info to your now() datetime.
However, you must add the same timezone of the reference variable; that is why I first read the tzinfo attribute.


回答 3

禁用时区。用challenge.datetime_start.replace(tzinfo=None);

您还可以将其replace(tzinfo=None)用于其他datetime

if challenge.datetime_start.replace(tzinfo=None) <= datetime.now().replace(tzinfo=None) <= challenge.datetime_end.replace(tzinfo=None):

Disable time zone. Use challenge.datetime_start.replace(tzinfo=None);

You can also use replace(tzinfo=None) for other datetime.

if challenge.datetime_start.replace(tzinfo=None) <= datetime.now().replace(tzinfo=None) <= challenge.datetime_end.replace(tzinfo=None):

回答 4

因此,我要解决此问题的方法是确保两个日期时间在正确的时区中。

我可以看到您正在使用datetime.now()它将返回系统的当前时间,而未设置tzinfo。

tzinfo是附加在日期时间上的信息,以使其知道它所在的时区。如果使用的是朴素的日期时间,则需要在整个系统中保持一致。我强烈建议只使用datetime.utcnow()

看到您正在创建与tzinfo相关联的日期时间,您需要做的是确保将它们本地化(与tzinfo相关联)到正确的时区。

看一下Delorean,它使处理这种事情变得更加容易。

So the way I would solve this problem is to make sure the two datetimes are in the right timezone.

I can see that you are using datetime.now() which will return the systems current time, with no tzinfo set.

tzinfo is the information attached to a datetime to let it know what timezone it is in. If you are using naive datetime you need to be consistent through out your system. I would highly recommend only using datetime.utcnow()

seeing as somewhere your are creating datetime that have tzinfo associated with them, what you need to do is make sure those are localized (has tzinfo associated) to the correct timezone.

Take a look at Delorean, it makes dealing with this sort of thing much easier.


回答 5

这是我的工作。在这里,我对创建的日期时间的表进行geet,并在日期时间上添加10分钟。稍后根据当前时间,完成到期操作。

from datetime import datetime, time, timedelta
import pytz

在数据库日期时间增加了10分钟

table_datetime =’2019-06-13 07:49:02.832969’(示例)

# Added 10 minutes on database datetime
# table_datetime = '2019-06-13 07:49:02.832969' (example)

table_expire_datetime = table_datetime + timedelta(minutes=10 )

# Current datetime
current_datetime = datetime.now()


# replace the timezone in both time
expired_on = table_expire_datetime.replace(tzinfo=utc)
checked_on = current_datetime.replace(tzinfo=utc)


if expired_on < checked_on:
    print("Time Crossed)
else:
    print("Time not crossed ")

它为我工作。

It is working form me. Here I am geeting the table created datetime and adding 10 minutes on the datetime. later depending on the current time, Expiry Operations are done.

from datetime import datetime, time, timedelta
import pytz

Added 10 minutes on database datetime

table_datetime = ‘2019-06-13 07:49:02.832969’ (example)

# Added 10 minutes on database datetime
# table_datetime = '2019-06-13 07:49:02.832969' (example)

table_expire_datetime = table_datetime + timedelta(minutes=10 )

# Current datetime
current_datetime = datetime.now()


# replace the timezone in both time
expired_on = table_expire_datetime.replace(tzinfo=utc)
checked_on = current_datetime.replace(tzinfo=utc)


if expired_on < checked_on:
    print("Time Crossed)
else:
    print("Time not crossed ")

It worked for me.


回答 6

只是:

dt = datetimeObject.strftime(format) # format = your datetime format ex) '%Y %d %m'
dt = datetime.datetime.strptime(dt,format)

这样做:

start_time = challenge.datetime_start.strftime('%Y %d %m %H %M %S')
start_time = datetime.datetime.strptime(start_time,'%Y %d %m %H %M %S')

end_time = challenge.datetime_end.strftime('%Y %d %m %H %M %S')
end_time = datetime.datetime.strptime(end_time,'%Y %d %m %H %M %S')

然后使用start_timeend_time

Just:

dt = datetimeObject.strftime(format) # format = your datetime format ex) '%Y %d %m'
dt = datetime.datetime.strptime(dt,format)

So do this:

start_time = challenge.datetime_start.strftime('%Y %d %m %H %M %S')
start_time = datetime.datetime.strptime(start_time,'%Y %d %m %H %M %S')

end_time = challenge.datetime_end.strftime('%Y %d %m %H %M %S')
end_time = datetime.datetime.strptime(end_time,'%Y %d %m %H %M %S')

and then use start_time and end_time


如何使用strftime来计算期间(AM / PM)?

问题:如何使用strftime来计算期间(AM / PM)?

具体来说,我有简化此代码:

from datetime import datetime
date_string = '2009-11-29 03:17 PM'
format = '%Y-%m-%d %H:%M %p'
my_date = datetime.strptime(date_string, format)

# This prints '2009-11-29 03:17 AM'
print my_date.strftime(format)

是什么赋予了?Python解析日期时是否只是忽略句点说明符,还是我做一些愚蠢的事情?

Specifically I have code that simplifies to this:

from datetime import datetime
date_string = '2009-11-29 03:17 PM'
format = '%Y-%m-%d %H:%M %p'
my_date = datetime.strptime(date_string, format)

# This prints '2009-11-29 03:17 AM'
print my_date.strftime(format)

What gives? Does Python just ignore the period specifier when parsing dates or am I doing something stupid?


回答 0

Python time.strftime文档说:

当与strptime()函数一起使用时,该%p指令仅在%I使用该指令解析小时时才影响输出小时字段。

果然,将其更改%H%I有效。

The Python time.strftime docs say:

When used with the strptime() function, the %p directive only affects the output hour field if the %I directive is used to parse the hour.

Sure enough, changing your %H to %I makes it work.


回答 1

format = '%Y-%m-%d %H:%M %p'

格式使用%H代替%I。由于%H是“ 24小时制”格式,因此很可能只是丢弃%p信息。它的工作原理,如果你改变了就好%H%I

format = '%Y-%m-%d %H:%M %p'

The format is using %H instead of %I. Since %H is the “24-hour” format, it’s likely just discarding the %p information. It works just fine if you change the %H to %I.


回答 2

您使用%H(24小时格式)而不是%I(12小时格式)。

You used %H (24 hour format) instead of %I (12 hour format).


回答 3

尝试将%H(24小时制)设置为%I(12小时制)。

Try replacing %H (Hour on a 24-hour clock) with %I (Hour on a 12-hour clock) ?


如何将日期时间增加一天?

问题:如何将日期时间增加一天?

如何增加日期时间的一天?

for i in range(1, 35)
    date = datetime.datetime(2003, 8, i)
    print(date)

但是我需要正确通过几个月和几年吗?有任何想法吗?

How to increment the day of a datetime?

for i in range(1, 35)
    date = datetime.datetime(2003, 8, i)
    print(date)

But I need pass through months and years correctly? Any ideas?


回答 0

date = datetime.datetime(2003,8,1,12,4,5)
for i in range(5): 
    date += datetime.timedelta(days=1)
    print(date) 
date = datetime.datetime(2003,8,1,12,4,5)
for i in range(5): 
    date += datetime.timedelta(days=1)
    print(date) 

回答 1

可以使用timedelta对象完成日期递增:

import datetime

datetime.datetime.now() + datetime.timedelta(days=1)

在Python文档中查找timedelta对象:http://docs.python.org/library/datetime.html

Incrementing dates can be accomplished using timedelta objects:

import datetime

datetime.datetime.now() + datetime.timedelta(days=1)

Look up timedelta objects in the Python docs: http://docs.python.org/library/datetime.html


回答 2

这是使用dateutil的relativedelta添加日期的另一种方法。

from datetime import datetime
from dateutil.relativedelta import relativedelta

print 'Today: ',datetime.now().strftime('%d/%m/%Y %H:%M:%S') 
date_after_month = datetime.now()+ relativedelta(day=1)
print 'After a Days:', date_after_month.strftime('%d/%m/%Y %H:%M:%S')

输出:

今天:25/06/2015 20:41:44

几天后:01/06/2015 20:41:44

Here is another method to add days on date using dateutil’s relativedelta.

from datetime import datetime
from dateutil.relativedelta import relativedelta

print 'Today: ',datetime.now().strftime('%d/%m/%Y %H:%M:%S') 
date_after_month = datetime.now()+ relativedelta(day=1)
print 'After a Days:', date_after_month.strftime('%d/%m/%Y %H:%M:%S')

Output:

Today: 25/06/2015 20:41:44

After a Days: 01/06/2015 20:41:44


回答 3

在某些情况下,所有当前答案都是错误的,因为它们不认为时区相对于UTC会更改其偏移量。因此,在某些情况下,添加24小时不同于添加日历日。

拟议的解决方案

以下解决方案适用于萨摩亚,并保持当地时间恒定。

def add_day(today):
    """
    Add a day to the current day.

    This takes care of historic offset changes and DST.

    Parameters
    ----------
    today : timezone-aware datetime object

    Returns
    -------
    tomorrow : timezone-aware datetime object
    """
    today_utc = today.astimezone(datetime.timezone.utc)
    tz = today.tzinfo
    tomorrow_utc = today_utc + datetime.timedelta(days=1)
    tomorrow_utc_tz = tomorrow_utc.astimezone(tz)
    tomorrow_utc_tz = tomorrow_utc_tz.replace(hour=today.hour,
                                              minute=today.minute,
                                              second=today.second)
    return tomorrow_utc_tz

测试代码

# core modules
import datetime

# 3rd party modules
import pytz


# add_day methods
def add_day(today):
    """
    Add a day to the current day.

    This takes care of historic offset changes and DST.

    Parameters
    ----------
    today : timezone-aware datetime object

    Returns
    -------
    tomorrow : timezone-aware datetime object
    """
    today_utc = today.astimezone(datetime.timezone.utc)
    tz = today.tzinfo
    tomorrow_utc = today_utc + datetime.timedelta(days=1)
    tomorrow_utc_tz = tomorrow_utc.astimezone(tz)
    tomorrow_utc_tz = tomorrow_utc_tz.replace(hour=today.hour,
                                              minute=today.minute,
                                              second=today.second)
    return tomorrow_utc_tz


def add_day_datetime_timedelta_conversion(today):
    # Correct for Samoa, but dst shift
    today_utc = today.astimezone(datetime.timezone.utc)
    tz = today.tzinfo
    tomorrow_utc = today_utc + datetime.timedelta(days=1)
    tomorrow_utc_tz = tomorrow_utc.astimezone(tz)
    return tomorrow_utc_tz


def add_day_dateutil_relativedelta(today):
    # WRONG!
    from dateutil.relativedelta import relativedelta
    return today + relativedelta(days=1)


def add_day_datetime_timedelta(today):
    # WRONG!
    return today + datetime.timedelta(days=1)


# Test cases
def test_samoa(add_day):
    """
    Test if add_day properly increases the calendar day for Samoa.

    Due to economic considerations, Samoa went from 2011-12-30 10:00-11:00
    to 2011-12-30 10:00+13:00. Hence the country skipped 2011-12-30 in its
    local time.

    See https://stackoverflow.com/q/52084423/562769

    A common wrong result here is 2011-12-30T23:59:00-10:00. This date never
    happened in Samoa.
    """
    tz = pytz.timezone('Pacific/Apia')
    today_utc = datetime.datetime(2011, 12, 30, 9, 59,
                                  tzinfo=datetime.timezone.utc)
    today_tz = today_utc.astimezone(tz)  # 2011-12-29T23:59:00-10:00
    tomorrow = add_day(today_tz)
    return tomorrow.isoformat() == '2011-12-31T23:59:00+14:00'


def test_dst(add_day):
    """Test if add_day properly increases the calendar day if DST happens."""
    tz = pytz.timezone('Europe/Berlin')
    today_utc = datetime.datetime(2018, 3, 25, 0, 59,
                                  tzinfo=datetime.timezone.utc)
    today_tz = today_utc.astimezone(tz)  # 2018-03-25T01:59:00+01:00
    tomorrow = add_day(today_tz)
    return tomorrow.isoformat() == '2018-03-26T01:59:00+02:00'


to_test = [(add_day_dateutil_relativedelta, 'relativedelta'),
           (add_day_datetime_timedelta, 'timedelta'),
           (add_day_datetime_timedelta_conversion, 'timedelta+conversion'),
           (add_day, 'timedelta+conversion+dst')]
print('{:<25}: {:>5} {:>5}'.format('Method', 'Samoa', 'DST'))
for method, name in to_test:
    print('{:<25}: {:>5} {:>5}'
          .format(name,
                  test_samoa(method),
                  test_dst(method)))

检测结果

Method                   : Samoa   DST
relativedelta            :     0     0
timedelta                :     0     0
timedelta+conversion     :     1     0
timedelta+conversion+dst :     1     1

All of the current answers are wrong in some cases as they do not consider that timezones change their offset relative to UTC. So in some cases adding 24h is different from adding a calendar day.

Proposed solution

The following solution works for Samoa and keeps the local time constant.

def add_day(today):
    """
    Add a day to the current day.

    This takes care of historic offset changes and DST.

    Parameters
    ----------
    today : timezone-aware datetime object

    Returns
    -------
    tomorrow : timezone-aware datetime object
    """
    today_utc = today.astimezone(datetime.timezone.utc)
    tz = today.tzinfo
    tomorrow_utc = today_utc + datetime.timedelta(days=1)
    tomorrow_utc_tz = tomorrow_utc.astimezone(tz)
    tomorrow_utc_tz = tomorrow_utc_tz.replace(hour=today.hour,
                                              minute=today.minute,
                                              second=today.second)
    return tomorrow_utc_tz

Tested Code

# core modules
import datetime

# 3rd party modules
import pytz


# add_day methods
def add_day(today):
    """
    Add a day to the current day.

    This takes care of historic offset changes and DST.

    Parameters
    ----------
    today : timezone-aware datetime object

    Returns
    -------
    tomorrow : timezone-aware datetime object
    """
    today_utc = today.astimezone(datetime.timezone.utc)
    tz = today.tzinfo
    tomorrow_utc = today_utc + datetime.timedelta(days=1)
    tomorrow_utc_tz = tomorrow_utc.astimezone(tz)
    tomorrow_utc_tz = tomorrow_utc_tz.replace(hour=today.hour,
                                              minute=today.minute,
                                              second=today.second)
    return tomorrow_utc_tz


def add_day_datetime_timedelta_conversion(today):
    # Correct for Samoa, but dst shift
    today_utc = today.astimezone(datetime.timezone.utc)
    tz = today.tzinfo
    tomorrow_utc = today_utc + datetime.timedelta(days=1)
    tomorrow_utc_tz = tomorrow_utc.astimezone(tz)
    return tomorrow_utc_tz


def add_day_dateutil_relativedelta(today):
    # WRONG!
    from dateutil.relativedelta import relativedelta
    return today + relativedelta(days=1)


def add_day_datetime_timedelta(today):
    # WRONG!
    return today + datetime.timedelta(days=1)


# Test cases
def test_samoa(add_day):
    """
    Test if add_day properly increases the calendar day for Samoa.

    Due to economic considerations, Samoa went from 2011-12-30 10:00-11:00
    to 2011-12-30 10:00+13:00. Hence the country skipped 2011-12-30 in its
    local time.

    See https://stackoverflow.com/q/52084423/562769

    A common wrong result here is 2011-12-30T23:59:00-10:00. This date never
    happened in Samoa.
    """
    tz = pytz.timezone('Pacific/Apia')
    today_utc = datetime.datetime(2011, 12, 30, 9, 59,
                                  tzinfo=datetime.timezone.utc)
    today_tz = today_utc.astimezone(tz)  # 2011-12-29T23:59:00-10:00
    tomorrow = add_day(today_tz)
    return tomorrow.isoformat() == '2011-12-31T23:59:00+14:00'


def test_dst(add_day):
    """Test if add_day properly increases the calendar day if DST happens."""
    tz = pytz.timezone('Europe/Berlin')
    today_utc = datetime.datetime(2018, 3, 25, 0, 59,
                                  tzinfo=datetime.timezone.utc)
    today_tz = today_utc.astimezone(tz)  # 2018-03-25T01:59:00+01:00
    tomorrow = add_day(today_tz)
    return tomorrow.isoformat() == '2018-03-26T01:59:00+02:00'


to_test = [(add_day_dateutil_relativedelta, 'relativedelta'),
           (add_day_datetime_timedelta, 'timedelta'),
           (add_day_datetime_timedelta_conversion, 'timedelta+conversion'),
           (add_day, 'timedelta+conversion+dst')]
print('{:<25}: {:>5} {:>5}'.format('Method', 'Samoa', 'DST'))
for method, name in to_test:
    print('{:<25}: {:>5} {:>5}'
          .format(name,
                  test_samoa(method),
                  test_dst(method)))

Test results

Method                   : Samoa   DST
relativedelta            :     0     0
timedelta                :     0     0
timedelta+conversion     :     1     0
timedelta+conversion+dst :     1     1

回答 4

这对我来说是一个简单的解决方案:

from datetime import timedelta, datetime

today = datetime.today().strftime("%Y-%m-%d")
tomorrow = datetime.today() + timedelta(1)

This was a straightforward solution for me:

from datetime import timedelta, datetime

today = datetime.today().strftime("%Y-%m-%d")
tomorrow = datetime.today() + timedelta(1)


回答 5

您还可以导入timedelta,以使代码更简洁。

from datetime import datetime, timedelta
date = datetime.now() + timedelta(seconds=[delta_value])

然后将日期转换为字符串

date = date.strftime('%Y-%m-%d %H:%M:%S')

Python一线是

date = (datetime.now() + timedelta(seconds=[delta_value])).strftime('%Y-%m-%d %H:%M:%S')

You can also import timedelta so the code is cleaner.

from datetime import datetime, timedelta
date = datetime.now() + timedelta(seconds=[delta_value])

Then convert to date to string

date = date.strftime('%Y-%m-%d %H:%M:%S')

Python one liner is

date = (datetime.now() + timedelta(seconds=[delta_value])).strftime('%Y-%m-%d %H:%M:%S')

回答 6

根本没有库的简短解决方案。:)

d = "8/16/18"
day_value = d[(d.find('/')+1):d.find('/18')]
tomorrow = f"{d[0:d.find('/')]}/{int(day_value)+1}{d[d.find('/18'):len(d)]}".format()
print(tomorrow)
# 8/17/18

确保“ string d ”实际上是的形式,%m/%d/%Y这样您就不会在从一个月过渡到下一个月时遇到问题。

A short solution without libraries at all. :)

d = "8/16/18"
day_value = d[(d.find('/')+1):d.find('/18')]
tomorrow = f"{d[0:d.find('/')]}/{int(day_value)+1}{d[d.find('/18'):len(d)]}".format()
print(tomorrow)
# 8/17/18

Make sure that “string d” is actually in the form of %m/%d/%Y so that you won’t have problems transitioning from one month to the next.


找出一个python脚本完成执行所花费的时间

问题:找出一个python脚本完成执行所花费的时间

我在python脚本中有以下代码:

def fun(): 
  #Code here

fun()

我要执行此脚本,还要找出执行几分钟所需的时间。我如何找出执行此脚本需要多少时间?一个例子将不胜感激。

I have the following code in a python script:

def fun(): 
  #Code here

fun()

I want to execute this script and also find out how much time it took to execute in minutes. How do I find out how much time it took for this script to execute ? An example would be really appreciated.


回答 0

from datetime import datetime
startTime = datetime.now()

#do something

#Python 2: 
print datetime.now() - startTime 

#Python 3: 
print(datetime.now() - startTime)
from datetime import datetime
startTime = datetime.now()

#do something

#Python 2: 
print datetime.now() - startTime 

#Python 3: 
print(datetime.now() - startTime)

回答 1

您是在Linux还是UNIX上从命令行执行脚本?在这种情况下,您可以使用

time ./script.py

Do you execute the script from the command line on Linux or UNIX? In that case, you could just use

time ./script.py

回答 2

import time
start = time.time()

fun()

# python 2
print 'It took', time.time()-start, 'seconds.'

# python 3
print('It took', time.time()-start, 'seconds.')
import time
start = time.time()

fun()

# python 2
print 'It took', time.time()-start, 'seconds.'

# python 3
print('It took', time.time()-start, 'seconds.')

回答 3

我通常要做的是使用clock()time()time库中获取。clock测量口译员时间,同时time测量系统时间。其他注意事项可在docs中找到。

例如,

def fn():
    st = time()
    dostuff()
    print 'fn took %.2f seconds' % (time() - st)

或者,您可以使用timeittime由于可以快速解决问题,因此我经常使用该方法,但是如果您正在计时可隔离的代码段,那么timeit它会派上用场。

timeit文档中

def test():
    "Stupid test function"
    L = []
    for i in range(100):
        L.append(i)

if __name__=='__main__':
    from timeit import Timer
    t = Timer("test()", "from __main__ import test")
    print t.timeit()

然后将其转换为分钟,只需除以60。如果您希望脚本运行时以易于理解的格式显示,无论是秒还是天,都可以转换为a timedeltastr然后将其转换为:

runtime = time() - st
print 'runtime:', timedelta(seconds=runtime)

然后打印出某种形式[D day[s], ][H]H:MM:SS[.UUUUUU]。您可以查看timedelta文档

最后,如果实际上是在对代码进行概要分析,那么Python也将提供概要文件库

What I usually do is use clock() or time() from the time library. clock measures interpreter time, while time measures system time. Additional caveats can be found in the docs.

For example,

def fn():
    st = time()
    dostuff()
    print 'fn took %.2f seconds' % (time() - st)

Or alternatively, you can use timeit. I often use the time approach due to how fast I can bang it out, but if you’re timing an isolate-able piece of code, timeit comes in handy.

From the timeit docs,

def test():
    "Stupid test function"
    L = []
    for i in range(100):
        L.append(i)

if __name__=='__main__':
    from timeit import Timer
    t = Timer("test()", "from __main__ import test")
    print t.timeit()

Then to convert to minutes, you can simply divide by 60. If you want the script runtime in an easily readable format, whether it’s seconds or days, you can convert to a timedelta and str it:

runtime = time() - st
print 'runtime:', timedelta(seconds=runtime)

and that’ll print out something of the form [D day[s], ][H]H:MM:SS[.UUUUUU]. You can check out the timedelta docs.

And finally, if what you’re actually after is profiling your code, Python makes available the profile library as well.


回答 4

import time 

startTime = time.time()
# Your code here !
print ('The script took {0} second !'.format(time.time() - startTime))

之前的代码对我来说毫无问题!

import time 

startTime = time.time()
# Your code here !
print ('The script took {0} second !'.format(time.time() - startTime))

The previous code works for me with no problem !


回答 5

import sys
import timeit

start = timeit.default_timer()

#do some nice things...

stop = timeit.default_timer()
total_time = stop - start

# output running time in a nice format.
mins, secs = divmod(total_time, 60)
hours, mins = divmod(mins, 60)

sys.stdout.write("Total running time: %d:%d:%d.\n" % (hours, mins, secs))
import sys
import timeit

start = timeit.default_timer()

#do some nice things...

stop = timeit.default_timer()
total_time = stop - start

# output running time in a nice format.
mins, secs = divmod(total_time, 60)
hours, mins = divmod(mins, 60)

sys.stdout.write("Total running time: %d:%d:%d.\n" % (hours, mins, secs))

回答 6

使用timeit模块。很简单 运行example.py文件,使其在Python Shell中处于活动状态,现在您应该能够在Shell中调用函数。试试看以检查是否有效

>>>fun(input)
output

很好,可以,现在导入timeit并设置一个计时器

>>>import timeit
>>>t = timeit.Timer('example.fun(input)','import example')
>>>

现在我们已经设置好计时器,我们可以看到需要多长时间

>>>t.timeit(number=1)
some number here

到这里,它将告诉您执行该功能花费了几秒钟(或更短的时间)。如果这是一个简单函数,则可以将其增加到t.timeit(number = 1000)(或任何数字!),然后将答案除以数字即可得出平均值。

我希望这有帮助。

Use the timeit module. It’s very easy. Run your example.py file so it is active in the Python Shell, you should now be able to call your function in the shell. Try it out to check it works

>>>fun(input)
output

Good, that works, now import timeit and set up a timer

>>>import timeit
>>>t = timeit.Timer('example.fun(input)','import example')
>>>

Now we have our timer set up we can see how long it takes

>>>t.timeit(number=1)
some number here

And there we go, it will tell you how many seconds (or less) it took to execute that function. If it’s a simple function then you can increase it to t.timeit(number=1000) (or any number!) and then divide the answer by the number to get the average.

I hope this helps.


回答 7

使用时间和日期时间包。

如果有人要执行此脚本,并找出执行几分钟所需的时间

import time
from time import strftime
from datetime import datetime 
from time import gmtime

def start_time_():    
    #import time
    start_time = time.time()
    return(start_time)

def end_time_():
    #import time
    end_time = time.time()
    return(end_time)

def Execution_time(start_time_,end_time_):
   #import time
   #from time import strftime
   #from datetime import datetime 
   #from time import gmtime
   return(strftime("%H:%M:%S",gmtime(int('{:.0f}'.format(float(str((end_time-start_time))))))))

start_time = start_time_()
# your code here #
[i for i in range(0,100000000)]
# your code here #
end_time = end_time_()
print("Execution_time is :", Execution_time(start_time,end_time))

上面的代码对我有用。我希望这有帮助。

use the time and datetime packages.

if anybody want to execute this script and also find out how much time it took to execute in minutes

import time
from time import strftime
from datetime import datetime 
from time import gmtime

def start_time_():    
    #import time
    start_time = time.time()
    return(start_time)

def end_time_():
    #import time
    end_time = time.time()
    return(end_time)

def Execution_time(start_time_,end_time_):
   #import time
   #from time import strftime
   #from datetime import datetime 
   #from time import gmtime
   return(strftime("%H:%M:%S",gmtime(int('{:.0f}'.format(float(str((end_time-start_time))))))))

start_time = start_time_()
# your code here #
[i for i in range(0,100000000)]
# your code here #
end_time = end_time_()
print("Execution_time is :", Execution_time(start_time,end_time))

The above code works for me. I hope this helps.


如何在Python中以毫秒为单位创建日期时间?

问题:如何在Python中以毫秒为单位创建日期时间?

我可以通过java.util.Date(milliseconds)在Java 创建类似的Date对象。如何在Python中创建可比对象?

分配一个Date对象,并将其初始化为表示自标准基准时间(即epoch)以来的指定毫秒数,即标准时间1970年1月1日,格林尼治标准时间00:00:00。

I can create a similar Date object in Java by java.util.Date(milliseconds). How do I create the comparable in Python?

Allocates a Date object and initializes it to represent the specified number of milliseconds since the standard base time known as “the epoch”, namely January 1, 1970, 00:00:00 GMT.


回答 0

只需将其转换为时间戳

datetime.datetime.fromtimestamp(ms/1000.0)

Just convert it to timestamp

datetime.datetime.fromtimestamp(ms/1000.0)

回答 1

那这个呢?我认为可以指望它处理1970年之前和2038年之后的日期。

target_date_time_ms = 200000 # or whatever
base_datetime = datetime.datetime( 1970, 1, 1 )
delta = datetime.timedelta( 0, 0, 0, target_date_time_ms )
target_date = base_datetime + delta

如Python标准库中所述:

如果时间戳超出平台C localtime()或gmtime()函数支持的值范围,则fromtimestamp()可能会引发ValueError。通常将此限制在1970年到2038年之间。

What about this? I presume it can be counted on to handle dates before 1970 and after 2038.

target_date_time_ms = 200000 # or whatever
base_datetime = datetime.datetime( 1970, 1, 1 )
delta = datetime.timedelta( 0, 0, 0, target_date_time_ms )
target_date = base_datetime + delta

as mentioned in the Python standard lib:

fromtimestamp() may raise ValueError, if the timestamp is out of the range of values supported by the platform C localtime() or gmtime() functions. It’s common for this to be restricted to years in 1970 through 2038.


回答 2

由于使用了熊猫而有点沉重,但可以:

import pandas as pd
pd.to_datetime(msec_from_java, unit='ms').to_pydatetime()

Bit heavy because of using pandas but works:

import pandas as pd
pd.to_datetime(msec_from_java, unit='ms').to_pydatetime()

回答 3

import pandas as pd

Date_Time = pd.to_datetime(df.NameOfColumn, unit='ms')
import pandas as pd

Date_Time = pd.to_datetime(df.NameOfColumn, unit='ms')

Python timedelta年

问题:Python timedelta年

我需要检查自某个日期以来是否已有数年的时间。目前,我timedelta来自datetime模块,我不知道如何将其转换为年份。

I need to check if some number of years have been since some date. Currently I’ve got timedelta from datetime module and I don’t know how to convert it to years.


回答 0

timedelta要说明已经过去了多少年,您需要做更多的工作;您还需要知道开始(或结束)日期。(这是a年。)

最好的选择是使用dateutil.relativedelta object,但这是一个第三方模块。如果你想知道datetime那是n几年一些日期(默认为现在),你可以做以下::

from dateutil.relativedelta import relativedelta

def yearsago(years, from_date=None):
    if from_date is None:
        from_date = datetime.now()
    return from_date - relativedelta(years=years)

如果您愿意使用标准库,则答案要复杂一些:

from datetime import datetime
def yearsago(years, from_date=None):
    if from_date is None:
        from_date = datetime.now()
    try:
        return from_date.replace(year=from_date.year - years)
    except ValueError:
        # Must be 2/29!
        assert from_date.month == 2 and from_date.day == 29 # can be removed
        return from_date.replace(month=2, day=28,
                                 year=from_date.year-years)

如果是2/29,而18年前还没有2/29,则此函数将返回2/28。如果您希望返回3/1,只需将最后一条return语句更改为:

    return from_date.replace(month=3, day=1,
                             year=from_date.year-years)

您的问题最初是说您想知道自某个日期以来已有多少年了。假设您想要整数年,则可以基于每年365.25天进行猜测,然后使用yearsago上面定义的任何一个函数进行检查:

def num_years(begin, end=None):
    if end is None:
        end = datetime.now()
    num_years = int((end - begin).days / 365.25)
    if begin > yearsago(num_years, end):
        return num_years - 1
    else:
        return num_years

You need more than a timedelta to tell how many years have passed; you also need to know the beginning (or ending) date. (It’s a leap year thing.)

Your best bet is to use the dateutil.relativedelta object, but that’s a 3rd party module. If you want to know the datetime that was n years from some date (defaulting to right now), you can do the following::

from dateutil.relativedelta import relativedelta

def yearsago(years, from_date=None):
    if from_date is None:
        from_date = datetime.now()
    return from_date - relativedelta(years=years)

If you’d rather stick with the standard library, the answer is a little more complex::

from datetime import datetime
def yearsago(years, from_date=None):
    if from_date is None:
        from_date = datetime.now()
    try:
        return from_date.replace(year=from_date.year - years)
    except ValueError:
        # Must be 2/29!
        assert from_date.month == 2 and from_date.day == 29 # can be removed
        return from_date.replace(month=2, day=28,
                                 year=from_date.year-years)

If it’s 2/29, and 18 years ago there was no 2/29, this function will return 2/28. If you’d rather return 3/1, just change the last return statement to read::

    return from_date.replace(month=3, day=1,
                             year=from_date.year-years)

Your question originally said you wanted to know how many years it’s been since some date. Assuming you want an integer number of years, you can guess based on 365.25 days per year and then check using either of the yearsago functions defined above::

def num_years(begin, end=None):
    if end is None:
        end = datetime.now()
    num_years = int((end - begin).days / 365.25)
    if begin > yearsago(num_years, end):
        return num_years - 1
    else:
        return num_years

回答 1

如果您要检查某人是否18岁,请使用 timedelta在某些极端情况下将无法正常工作。例如,某人出生于2000年1月1日,将在2018年1月1日(恰好包括5个leap年)之后的16575天整整18岁,但某人在2001年1月1日出生的人,将在1月1日在整整6574天之后整整18岁。 2019(包括4个leap年)。因此,如果某人的年龄恰好是6574天,则在不了解有关其出生日期的更多信息的情况下就无法确定他们是17岁还是18岁。

正确的方法是直接从日期中减去年龄,然后减去两年,如果当前月份/日期在出生月份/日期之前,则减去一年。

If you’re trying to check if someone is 18 years of age, using timedelta will not work correctly on some edge cases because of leap years. For example, someone born on January 1, 2000, will turn 18 exactly 6575 days later on January 1, 2018 (5 leap years included), but someone born on January 1, 2001, will turn 18 exactly 6574 days later on January 1, 2019 (4 leap years included). Thus, you if someone is exactly 6574 days old, you can’t determine if they are 17 or 18 without knowing a little more information about their birthdate.

The correct way to do this is to calculate the age directly from the dates, by subtracting the two years, and then subtracting one if the current month/day precedes the birth month/day.


回答 2

首先,在最详细的级别上,无法完全解决问题。年份长短不一,对于年份长短没有明确的“正确选择”。

也就是说,获得“自然”单位(可能是秒)之间的差异,然后除以该单位与年份之间的比率。例如

delta_in_days / (365.25)
delta_in_seconds / (365.25*24*60*60)

…管他呢。远离月份,因为它们的定义甚至没有几年之久。

First off, at the most detailed level, the problem can’t be solved exactly. Years vary in length, and there isn’t a clear “right choice” for year length.

That said, get the difference in whatever units are “natural” (probably seconds) and divide by the ratio between that and years. E.g.

delta_in_days / (365.25)
delta_in_seconds / (365.25*24*60*60)

…or whatever. Stay away from months, since they are even less well defined than years.


回答 3

这是一个更新的DOB函数,该函数以与人类相同的方式计算生日:

import datetime
import locale


# Source: https://en.wikipedia.org/wiki/February_29
PRE = [
    'US',
    'TW',
]
POST = [
    'GB',
    'HK',
]


def get_country():
    code, _ = locale.getlocale()
    try:
        return code.split('_')[1]
    except IndexError:
        raise Exception('Country cannot be ascertained from locale.')


def get_leap_birthday(year):
    country = get_country()
    if country in PRE:
        return datetime.date(year, 2, 28)
    elif country in POST:
        return datetime.date(year, 3, 1)
    else:
        raise Exception('It is unknown whether your country treats leap year '
                      + 'birthdays as being on the 28th of February or '
                      + 'the 1st of March. Please consult your country\'s '
                      + 'legal code for in order to ascertain an answer.')
def age(dob):
    today = datetime.date.today()
    years = today.year - dob.year

    try:
        birthday = datetime.date(today.year, dob.month, dob.day)
    except ValueError as e:
        if dob.month == 2 and dob.day == 29:
            birthday = get_leap_birthday(today.year)
        else:
            raise e

    if today < birthday:
        years -= 1
    return years

print(age(datetime.date(1988, 2, 29)))

Here’s a updated DOB function, which calculates birthdays the same way humans do:

import datetime
import locale


# Source: https://en.wikipedia.org/wiki/February_29
PRE = [
    'US',
    'TW',
]
POST = [
    'GB',
    'HK',
]


def get_country():
    code, _ = locale.getlocale()
    try:
        return code.split('_')[1]
    except IndexError:
        raise Exception('Country cannot be ascertained from locale.')


def get_leap_birthday(year):
    country = get_country()
    if country in PRE:
        return datetime.date(year, 2, 28)
    elif country in POST:
        return datetime.date(year, 3, 1)
    else:
        raise Exception('It is unknown whether your country treats leap year '
                      + 'birthdays as being on the 28th of February or '
                      + 'the 1st of March. Please consult your country\'s '
                      + 'legal code for in order to ascertain an answer.')
def age(dob):
    today = datetime.date.today()
    years = today.year - dob.year

    try:
        birthday = datetime.date(today.year, dob.month, dob.day)
    except ValueError as e:
        if dob.month == 2 and dob.day == 29:
            birthday = get_leap_birthday(today.year)
        else:
            raise e

    if today < birthday:
        years -= 1
    return years

print(age(datetime.date(1988, 2, 29)))

回答 4

得到天数,然后除以365.2425(平均公历年)为年。除以30.436875(平均公历月)为月。

Get the number of days, then divide by 365.2425 (the mean Gregorian year) for years. Divide by 30.436875 (the mean Gregorian month) for months.


回答 5

def age(dob):
    import datetime
    today = datetime.date.today()

    if today.month < dob.month or \
      (today.month == dob.month and today.day < dob.day):
        return today.year - dob.year - 1
    else:
        return today.year - dob.year

>>> import datetime
>>> datetime.date.today()
datetime.date(2009, 12, 1)
>>> age(datetime.date(2008, 11, 30))
1
>>> age(datetime.date(2008, 12, 1))
1
>>> age(datetime.date(2008, 12, 2))
0
def age(dob):
    import datetime
    today = datetime.date.today()

    if today.month < dob.month or \
      (today.month == dob.month and today.day < dob.day):
        return today.year - dob.year - 1
    else:
        return today.year - dob.year

>>> import datetime
>>> datetime.date.today()
datetime.date(2009, 12, 1)
>>> age(datetime.date(2008, 11, 30))
1
>>> age(datetime.date(2008, 12, 1))
1
>>> age(datetime.date(2008, 12, 2))
0

回答 6

您需要多精确? td.days / 365.25如果您担心leap年,它将使您更加接近。

How exact do you need it to be? td.days / 365.25 will get you pretty close, if you’re worried about leap years.


回答 7

此处未提及的另一个第三方库lib是mxDateTime(python datetime和3rd party的前身timeutil)可用于此任务。

前面提到的yearsago是:

from mx.DateTime import now, RelativeDateTime

def years_ago(years, from_date=None):
    if from_date == None:
        from_date = now()
    return from_date-RelativeDateTime(years=years)

第一个参数应该是一个DateTime实例。

要转换普通datetimeDateTime你可以使用这个1秒精度):

def DT_from_dt_s(t):
    return DT.DateTimeFromTicks(time.mktime(t.timetuple()))

或1微秒的精度:

def DT_from_dt_u(t):
    return DT.DateTime(t.year, t.month, t.day, t.hour,
  t.minute, t.second + t.microsecond * 1e-6)

是的,即使与使用timeutil(由Rick Copeland建议)相比,为有问题的单个任务添加依赖绝对是一个过大的杀伤力。

Yet another 3rd party lib not mentioned here is mxDateTime (predecessor of both python datetime and 3rd party timeutil) could be used for this task.

The aforementioned yearsago would be:

from mx.DateTime import now, RelativeDateTime

def years_ago(years, from_date=None):
    if from_date == None:
        from_date = now()
    return from_date-RelativeDateTime(years=years)

First parameter is expected to be a DateTime instance.

To convert ordinary datetime to DateTime you could use this for 1 second precision):

def DT_from_dt_s(t):
    return DT.DateTimeFromTicks(time.mktime(t.timetuple()))

or this for 1 microsecond precision:

def DT_from_dt_u(t):
    return DT.DateTime(t.year, t.month, t.day, t.hour,
  t.minute, t.second + t.microsecond * 1e-6)

And yes, adding the dependency for this single task in question would definitely be an overkill compared even with using timeutil (suggested by Rick Copeland).


回答 8

最后,您遇到的是数学问题。如果每隔4年我们有额外的一天,那么可以在几天之内(而不是365天,而是365 * 4 +1)潜水timedelta,那么您的时间就是4年。然后再将其除以4。timedelta /((365 * 4)+1)/ 4 = timedelta * 4 /(365 * 4 +1)

In the end what you have is a maths issue. If every 4 years we have an extra day lets then dived the timedelta in days, not by 365 but 365*4 + 1, that would give you the amount of 4 years. Then divide it again by 4. timedelta / ((365*4) +1) / 4 = timedelta * 4 / (365*4 +1)


回答 9

这是我制定的解决方案,希望对您有所帮助;-)

def menor_edad_legal(birthday):
    """ returns true if aged<18 in days """ 
    try:

        today = time.localtime()                        

        fa_divuit_anys=date(year=today.tm_year-18, month=today.tm_mon, day=today.tm_mday)

        if birthday>fa_divuit_anys:
            return True
        else:
            return False            

    except Exception, ex_edad:
        logging.error('Error menor de edad: %s' % ex_edad)
        return True

This is the solution I worked out, I hope can help ;-)

def menor_edad_legal(birthday):
    """ returns true if aged<18 in days """ 
    try:

        today = time.localtime()                        

        fa_divuit_anys=date(year=today.tm_year-18, month=today.tm_mon, day=today.tm_mday)

        if birthday>fa_divuit_anys:
            return True
        else:
            return False            

    except Exception, ex_edad:
        logging.error('Error menor de edad: %s' % ex_edad)
        return True

回答 10

即使该线程已经死了,我还是可以为我面临的这个同样的问题提出一个可行的解决方案。这是(日期是格式为dd-mm-yyyy的字符串):

def validatedate(date):
    parts = date.strip().split('-')

    if len(parts) == 3 and False not in [x.isdigit() for x in parts]: 
        birth = datetime.date(int(parts[2]), int(parts[1]), int(parts[0]))
        today = datetime.date.today()

        b = (birth.year * 10000) + (birth.month * 100) + (birth.day)
        t = (today.year * 10000) + (today.month * 100) + (today.day)

        if (t - 18 * 10000) >= b:
            return True

    return False

Even though this thread is already dead, might i suggest a working solution for this very same problem i was facing. Here it is (date is a string in the format dd-mm-yyyy):

def validatedate(date):
    parts = date.strip().split('-')

    if len(parts) == 3 and False not in [x.isdigit() for x in parts]: 
        birth = datetime.date(int(parts[2]), int(parts[1]), int(parts[0]))
        today = datetime.date.today()

        b = (birth.year * 10000) + (birth.month * 100) + (birth.day)
        t = (today.year * 10000) + (today.month * 100) + (today.day)

        if (t - 18 * 10000) >= b:
            return True

    return False

回答 11

此函数返回两个日期之间的年份差(以ISO格式作为字符串,但是可以轻松修改以采用任何格式)

import time
def years(earlydateiso,  laterdateiso):
    """difference in years between two dates in ISO format"""

    ed =  time.strptime(earlydateiso, "%Y-%m-%d")
    ld =  time.strptime(laterdateiso, "%Y-%m-%d")
    #switch dates if needed
    if  ld < ed:
        ld,  ed = ed,  ld            

    res = ld[0] - ed [0]
    if res > 0:
        if ld[1]< ed[1]:
            res -= 1
        elif  ld[1] == ed[1]:
            if ld[2]< ed[2]:
                res -= 1
    return res

this function returns the difference in years between two dates (taken as strings in ISO format, but it can easily modified to take in any format)

import time
def years(earlydateiso,  laterdateiso):
    """difference in years between two dates in ISO format"""

    ed =  time.strptime(earlydateiso, "%Y-%m-%d")
    ld =  time.strptime(laterdateiso, "%Y-%m-%d")
    #switch dates if needed
    if  ld < ed:
        ld,  ed = ed,  ld            

    res = ld[0] - ed [0]
    if res > 0:
        if ld[1]< ed[1]:
            res -= 1
        elif  ld[1] == ed[1]:
            if ld[2]< ed[2]:
                res -= 1
    return res

回答 12

我建议Pyfdate

什么是pyfdate?

鉴于Python的目标是成为功能强大且易于使用的脚本语言,因此其用于日期和时间的功能并不像应该的那样友好。pyfdate的目的是通过提供与日期和时间一起使用的功能来补救这种情况,这些功能与Python的其余部分一样强大且易于使用。

教程

I’ll suggest Pyfdate

What is pyfdate?

Given Python’s goal to be a powerful and easy-to-use scripting language, its features for working with dates and times are not as user-friendly as they should be. The purpose of pyfdate is to remedy that situation by providing features for working with dates and times that are as powerful and easy-to-use as the rest of Python.

the tutorial


回答 13

import datetime

def check_if_old_enough(years_needed, old_date):

    limit_date = datetime.date(old_date.year + years_needed,  old_date.month, old_date.day)

    today = datetime.datetime.now().date()

    old_enough = False

    if limit_date <= today:
        old_enough = True

    return old_enough



def test_ages():

    years_needed = 30

    born_date_Logan = datetime.datetime(1988, 3, 5)

    if check_if_old_enough(years_needed, born_date_Logan):
        print("Logan is old enough")
    else:
        print("Logan is not old enough")


    born_date_Jessica = datetime.datetime(1997, 3, 6)

    if check_if_old_enough(years_needed, born_date_Jessica):
        print("Jessica is old enough")
    else:
        print("Jessica is not old enough")


test_ages()

这是Carrousel操作员在Logan的Run电影中运行的代码;)

https://zh.wikipedia.org/wiki/Logan%27s_Run_(电影)

import datetime

def check_if_old_enough(years_needed, old_date):

    limit_date = datetime.date(old_date.year + years_needed,  old_date.month, old_date.day)

    today = datetime.datetime.now().date()

    old_enough = False

    if limit_date <= today:
        old_enough = True

    return old_enough



def test_ages():

    years_needed = 30

    born_date_Logan = datetime.datetime(1988, 3, 5)

    if check_if_old_enough(years_needed, born_date_Logan):
        print("Logan is old enough")
    else:
        print("Logan is not old enough")


    born_date_Jessica = datetime.datetime(1997, 3, 6)

    if check_if_old_enough(years_needed, born_date_Jessica):
        print("Jessica is old enough")
    else:
        print("Jessica is not old enough")


test_ages()

This is the code that the Carrousel operator was running in Logan’s Run film ;)

https://en.wikipedia.org/wiki/Logan%27s_Run_(film)


回答 14

我遇到这个问题,发现亚当斯回答了最有帮助的https://stackoverflow.com/a/765862/2964689

但是没有python方法的示例,但这是我最终使用的方法。

输入:日期时间对象

输出:整年的整数年龄

def age(birthday):
    birthday = birthday.date()
    today = date.today()

    years = today.year - birthday.year

    if (today.month < birthday.month or
       (today.month == birthday.month and today.day < birthday.day)):

        years = years - 1

    return years

I came across this question and found Adams answer the most helpful https://stackoverflow.com/a/765862/2964689

But there was no python example of his method but here’s what I ended up using.

input: datetime object

output: integer age in whole years

def age(birthday):
    birthday = birthday.date()
    today = date.today()

    years = today.year - birthday.year

    if (today.month < birthday.month or
       (today.month == birthday.month and today.day < birthday.day)):

        years = years - 1

    return years

回答 15

我喜欢John Mee的解决方案,因为它简单易用,我也不担心在2月28日或3月1日(不是a年)如何确定2月29日出生的人的年龄。但这是他的代码的一些调整我认为可以解决这些投诉:

def age(dob):
    import datetime
    today = datetime.date.today()
    age = today.year - dob.year
    if ( today.month == dob.month == 2 and
         today.day == 28 and dob.day == 29 ):
         pass
    elif today.month < dob.month or \
      (today.month == dob.month and today.day < dob.day):
        age -= 1
    return age

I liked John Mee’s solution for its simplicity, and I am not that concerned about how, on Feb 28 or March 1 when it is not a leap year, to determine age of people born on Feb 29. But here is a tweak of his code which I think addresses the complaints:

def age(dob):
    import datetime
    today = datetime.date.today()
    age = today.year - dob.year
    if ( today.month == dob.month == 2 and
         today.day == 28 and dob.day == 29 ):
         pass
    elif today.month < dob.month or \
      (today.month == dob.month and today.day < dob.day):
        age -= 1
    return age

在Python中将字符串日期转换为时间戳

问题:在Python中将字符串日期转换为时间戳

如何将格式转换"%d/%m/%Y"为时间戳的字符串?

"01/12/2011" -> 1322697600

How to convert a string in the format "%d/%m/%Y" to timestamp?

"01/12/2011" -> 1322697600

回答 0

>>> import time
>>> import datetime
>>> s = "01/12/2011"
>>> time.mktime(datetime.datetime.strptime(s, "%d/%m/%Y").timetuple())
1322697600.0
>>> import time
>>> import datetime
>>> s = "01/12/2011"
>>> time.mktime(datetime.datetime.strptime(s, "%d/%m/%Y").timetuple())
1322697600.0

回答 1

我使用ciso8601,它比datetime的strptime快62倍。

t = "01/12/2011"
ts = ciso8601.parse_datetime(t)
# to get time in seconds:
time.mktime(ts.timetuple())

您可以在此处了解更多信息

I use ciso8601, which is 62x faster than datetime’s strptime.

t = "01/12/2011"
ts = ciso8601.parse_datetime(t)
# to get time in seconds:
time.mktime(ts.timetuple())

You can learn more here.


回答 2

要将字符串转换为日期对象:

from datetime import date, datetime

date_string = "01/12/2011"
date_object = date(*map(int, reversed(date_string.split("/"))))
assert date_object == datetime.strptime(date_string, "%d/%m/%Y").date()

将日期对象转换为POSIX时间戳的方式取决于时区。从Python中的转换datetime.date为UTC时间戳

  • 日期对象代表UTC的午夜

    import calendar
    
    timestamp1 = calendar.timegm(utc_date.timetuple())
    timestamp2 = (utc_date.toordinal() - date(1970, 1, 1).toordinal()) * 24*60*60
    assert timestamp1 == timestamp2
  • 日期对象代表当地时间的午夜

    import time
    
    timestamp3 = time.mktime(local_date.timetuple())
    assert timestamp3 != timestamp1 or (time.gmtime() == time.localtime())

时间戳是不同的,除非UTC和当地时间的午夜是同一时间实例。

To convert the string into a date object:

from datetime import date, datetime

date_string = "01/12/2011"
date_object = date(*map(int, reversed(date_string.split("/"))))
assert date_object == datetime.strptime(date_string, "%d/%m/%Y").date()

The way to convert the date object into POSIX timestamp depends on timezone. From Converting datetime.date to UTC timestamp in Python:

  • date object represents midnight in UTC

    import calendar
    
    timestamp1 = calendar.timegm(utc_date.timetuple())
    timestamp2 = (utc_date.toordinal() - date(1970, 1, 1).toordinal()) * 24*60*60
    assert timestamp1 == timestamp2
    
  • date object represents midnight in local time

    import time
    
    timestamp3 = time.mktime(local_date.timetuple())
    assert timestamp3 != timestamp1 or (time.gmtime() == time.localtime())
    

The timestamps are different unless midnight in UTC and in local time is the same time instance.


回答 3

>>> int(datetime.datetime.strptime('01/12/2011', '%d/%m/%Y').strftime("%s"))
1322683200
>>> int(datetime.datetime.strptime('01/12/2011', '%d/%m/%Y').strftime("%s"))
1322683200

回答 4

答案还取决于您输入的日期时区。如果您的日期是本地日期,则可以像katrielalex所说的那样使用mktime()-只有我不明白他为什么使用datetime而不是这个较短的版本:

>>> time.mktime(time.strptime('01/12/2011', "%d/%m/%Y"))
1322694000.0

但是请注意,我的结果与他的结果不同,因为我可能位于不同的TZ中(结果是无时区的UNIX时间戳)

现在,如果输入日期已经是UTC,那么我认为正确的解决方案是:

>>> calendar.timegm(time.strptime('01/12/2011', '%d/%m/%Y'))
1322697600

The answer depends also on your input date timezone. If your date is a local date, then you can use mktime() like katrielalex said – only I don’t see why he used datetime instead of this shorter version:

>>> time.mktime(time.strptime('01/12/2011', "%d/%m/%Y"))
1322694000.0

But observe that my result is different than his, as I am probably in a different TZ (and the result is timezone-free UNIX timestamp)

Now if the input date is already in UTC, than I believe the right solution is:

>>> calendar.timegm(time.strptime('01/12/2011', '%d/%m/%Y'))
1322697600

回答 5

只需使用datetime.datetime.strptime

import datetime
stime = "01/12/2011"
print(datetime.datetime.strptime(stime, "%d/%m/%Y").timestamp())

结果:

1322697600

要使用UTC代替本地时区,请使用.replace

datetime.datetime.strptime(stime, "%d/%m/%Y").replace(tzinfo=datetime.timezone.utc).timestamp()

Simply use datetime.datetime.strptime:

import datetime
stime = "01/12/2011"
print(datetime.datetime.strptime(stime, "%d/%m/%Y").timestamp())

Result:

1322697600

To use UTC instead of the local timezone use .replace:

datetime.datetime.strptime(stime, "%d/%m/%Y").replace(tzinfo=datetime.timezone.utc).timestamp()

回答 6

首先,您必须将strptime类将字符串转换为struct_time格式。

然后只需从那里使用mktime即可获得浮动。

First you must the strptime class to convert the string to a struct_time format.

Then just use mktime from there to get your float.


回答 7

这些答案中有很多都不必考虑日期是幼稚的

为正确起见,您需要先将天真日期设为可识别时区的日期时间

import datetime
import pytz
# naive datetime
d = datetime.datetime.strptime('01/12/2011', '%d/%m/%Y')
>>> datetime.datetime(2011, 12, 1, 0, 0)

# add proper timezone
pst = pytz.timezone('America/Los_Angeles')
d = pst.localize(d)
>>> datetime.datetime(2011, 12, 1, 0, 0,
tzinfo=<DstTzInfo 'America/Los_Angeles' PST-1 day, 16:00:00 STD>)

# convert to UTC timezone
utc = pytz.UTC
d = d.astimezone(utc)
>>> datetime.datetime(2011, 12, 1, 8, 0, tzinfo=<UTC>)

# epoch is the beginning of time in the UTC timestamp world
epoch = datetime.datetime(1970,1,1,0,0,0,tzinfo=pytz.UTC)
>>> datetime.datetime(1970, 1, 1, 0, 0, tzinfo=<UTC>)

# get the total second difference
ts = (d - epoch).total_seconds()
>>> 1322726400.0

也:

请注意,在许多时区中都使用pytz“ 不工作”。请参见带有pytz时区的datetime。不同的偏移量取决于tzinfo的设置方式tzinfodatetime.datetime

# Don't do this:
d = datetime.datetime(2011, 12, 1,0,0,0, tzinfo=pytz.timezone('America/Los_Angeles'))
>>> datetime.datetime(2011, 1, 12, 0, 0, 
tzinfo=<DstTzInfo 'America/Los_Angeles' LMT-1 day, 16:07:00 STD>)
# tzinfo in not PST but LMT here, with a 7min offset !!!

# when converting to UTC:
d = d.astimezone(pytz.UTC)
>>> datetime.datetime(2011, 1, 12, 7, 53, tzinfo=<UTC>)
# you end up with an offset

https://zh.wikipedia.org/wiki/Local_mean_time

A lot of these answers don’t bother to consider that the date is naive to begin with

To be correct, you need to make the naive date a timezone aware datetime first

import datetime
import pytz
# naive datetime
d = datetime.datetime.strptime('01/12/2011', '%d/%m/%Y')
>>> datetime.datetime(2011, 12, 1, 0, 0)

# add proper timezone
pst = pytz.timezone('America/Los_Angeles')
d = pst.localize(d)
>>> datetime.datetime(2011, 12, 1, 0, 0,
tzinfo=<DstTzInfo 'America/Los_Angeles' PST-1 day, 16:00:00 STD>)

# convert to UTC timezone
utc = pytz.UTC
d = d.astimezone(utc)
>>> datetime.datetime(2011, 12, 1, 8, 0, tzinfo=<UTC>)

# epoch is the beginning of time in the UTC timestamp world
epoch = datetime.datetime(1970,1,1,0,0,0,tzinfo=pytz.UTC)
>>> datetime.datetime(1970, 1, 1, 0, 0, tzinfo=<UTC>)

# get the total second difference
ts = (d - epoch).total_seconds()
>>> 1322726400.0

Also:

Be careful, using pytz for tzinfo in a datetime.datetime DOESN’T WORK for many timezones. See datetime with pytz timezone. Different offset depending on how tzinfo is set

# Don't do this:
d = datetime.datetime(2011, 12, 1,0,0,0, tzinfo=pytz.timezone('America/Los_Angeles'))
>>> datetime.datetime(2011, 1, 12, 0, 0, 
tzinfo=<DstTzInfo 'America/Los_Angeles' LMT-1 day, 16:07:00 STD>)
# tzinfo in not PST but LMT here, with a 7min offset !!!

# when converting to UTC:
d = d.astimezone(pytz.UTC)
>>> datetime.datetime(2011, 1, 12, 7, 53, tzinfo=<UTC>)
# you end up with an offset

https://en.wikipedia.org/wiki/Local_mean_time


回答 8

我建议dateutil

import dateutil.parser
dateutil.parser.parse("01/12/2011", dayfirst=True).timestamp()

I would suggest dateutil:

import dateutil.parser
dateutil.parser.parse("01/12/2011", dayfirst=True).timestamp()

回答 9

似乎相当有效:

import datetime
day, month, year = '01/12/2011'.split('/')
datetime.datetime(int(year), int(month), int(day)).timestamp()

每个循环1.61 µs±120 ns(平均±标准偏差,共运行7次,每个循环100000个)

Seems to be quite efficient:

import datetime
day, month, year = '01/12/2011'.split('/')
datetime.datetime(int(year), int(month), int(day)).timestamp()

1.61 µs ± 120 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)


回答 10

只需使用datetime.timestamp(您的datetime实例),datetime实例将包含时区信息,因此该时间戳将是标准utc时间戳。如果将datetime转换为timetuple,它将丢失其时区,因此结果将是错误的。如果要提供接口,则应这样编写:int(datetime.timestamp(time_instance))* 1000

just use datetime.timestamp(your datetime instanse), datetime instance contains the timezone infomation, so the timestamp will be a standard utc timestamp. if you transform the datetime to timetuple, it will lose it’s timezone, so the result will be error. if you want to provide an interface, you should write like this: int(datetime.timestamp(time_instance)) * 1000


回答 11

您可以参考以下链接,以使用strptimefrom中的函数datetime.datetime将日期转换为任何格式以及时区。

https://docs.python.org/3/library/datetime.html#strftime-and-strptime-behavior

You can refer this following link for using strptime function from datetime.datetime, to convert date from any format along with time zone.

https://docs.python.org/3/library/datetime.html#strftime-and-strptime-behavior


回答 12

您可以转换为isoformat

my_date = '2020/08/08'
my_date = my_date.replace('/','-') # just to adapte to your question
date_timestamp = datetime.datetime.fromisoformat(my_date).timestamp()

you can convert to isoformat

my_date = '2020/08/08'
my_date = my_date.replace('/','-') # just to adapte to your question
date_timestamp = datetime.datetime.fromisoformat(my_date).timestamp()

回答 13

一个获取UNIX Epoch时间的简单函数。

注意:此功能假定输入的日期时间为UTC格式(请参阅此处的注释)。

def utctimestamp(ts: str, DATETIME_FORMAT: str = "%d/%m/%Y"):
    import datetime, calendar
    ts = datetime.datetime.utcnow() if ts is None else datetime.datetime.strptime(ts, DATETIME_FORMAT)
    return calendar.timegm(ts.utctimetuple())

用法

>>> utctimestamp("01/12/2011")
1322697600
>>> utctimestamp("2011-12-01", "%Y-%m-%d")
1322697600

A simple function to get UNIX Epoch time.

NOTE: This function assumes the input date time is in UTC format (Refer to comments here).

def utctimestamp(ts: str, DATETIME_FORMAT: str = "%d/%m/%Y"):
    import datetime, calendar
    ts = datetime.datetime.utcnow() if ts is None else datetime.datetime.strptime(ts, DATETIME_FORMAT)
    return calendar.timegm(ts.utctimetuple())

Usage:

>>> utctimestamp("01/12/2011")
1322697600
>>> utctimestamp("2011-12-01", "%Y-%m-%d")
1322697600

使用strftime将python datetime转换为纪元

问题:使用strftime将python datetime转换为纪元

我在UTC有一个时间,我想要从纪元开始经过的秒数。

我正在使用strftime将其转换为秒数。以2012年4月1日为例。

>>>datetime.datetime(2012,04,01,0,0).strftime('%s')
'1333234800'

从纪元开始的UTC时间为2012年4月1日,但以上返回1333234800,相差1小时。

因此,看来strftime正在考虑我的系统时间,并在某处应用了时区偏移。我以为日期时间纯粹是天真的?

我该如何解决?如果可能,除非标准,否则避免导入其他库。(我有可移植性问题)。

I have a time in UTC from which I want the number of seconds since epoch.

I am using strftime to convert it to the number of seconds. Taking 1st April 2012 as an example.

>>>datetime.datetime(2012,04,01,0,0).strftime('%s')
'1333234800'

1st of April 2012 UTC from epoch is 1333238400 but this above returns 1333234800 which is different by 1 hour.

So it looks like that strftime is taking my system time into account and applies a timezone shift somewhere. I thought datetime was purely naive?

How can I get around that? If possible avoiding to import other libraries unless standard. (I have portability concerns).


回答 0

如果要将python日期时间转换为自纪元以来的秒数,则可以明确地执行以下操作:

>>> (datetime.datetime(2012,04,01,0,0) - datetime.datetime(1970,1,1)).total_seconds()
1333238400.0

在Python 3.3+中,您可以timestamp()改用:

>>> datetime.datetime(2012,4,1,0,0).timestamp()
1333234800.0

为什么不应该使用 datetime.strftime('%s')

Python实际上并不支持%s作为strftime的参数(如果您不在http://docs.python.org/library/datetime.html#strftime-and-strptime-behavior中查看,则不在列表中),唯一之所以起作用,是因为Python会将信息传递到使用本地时区的系统的strftime中。

>>> datetime.datetime(2012,04,01,0,0).strftime('%s')
'1333234800'

If you want to convert a python datetime to seconds since epoch you could do it explicitly:

>>> (datetime.datetime(2012,04,01,0,0) - datetime.datetime(1970,1,1)).total_seconds()
1333238400.0

In Python 3.3+ you can use timestamp() instead:

>>> datetime.datetime(2012,4,1,0,0).timestamp()
1333234800.0

Why you should not use datetime.strftime('%s')

Python doesn’t actually support %s as an argument to strftime (if you check at http://docs.python.org/library/datetime.html#strftime-and-strptime-behavior it’s not in the list), the only reason it’s working is because Python is passing the information to your system’s strftime, which uses your local timezone.

>>> datetime.datetime(2012,04,01,0,0).strftime('%s')
'1333234800'

回答 1

我在时区等方面遇到了严重问题。Python处理所有事情的方式(对我而言)非常令人困惑。事情似乎使用日历模块(参见链接被精细工作1234)。

>>> import datetime
>>> import calendar
>>> aprilFirst=datetime.datetime(2012, 04, 01, 0, 0)
>>> calendar.timegm(aprilFirst.timetuple())
1333238400

I had serious issues with Timezones and such. The way Python handles all that happen to be pretty confusing (to me). Things seem to be working fine using the calendar module (see links 1, 2, 3 and 4).

>>> import datetime
>>> import calendar
>>> aprilFirst=datetime.datetime(2012, 04, 01, 0, 0)
>>> calendar.timegm(aprilFirst.timetuple())
1333238400

回答 2

import time
from datetime import datetime
now = datetime.now()

time.mktime(now.timetuple())
import time
from datetime import datetime
now = datetime.now()

time.mktime(now.timetuple())

回答 3

import time
from datetime import datetime
now = datetime.now()

# same as above except keeps microseconds
time.mktime(now.timetuple()) + now.microsecond * 1e-6

(对不起,它不会让我对现有答案发表评论)

import time
from datetime import datetime
now = datetime.now()

# same as above except keeps microseconds
time.mktime(now.timetuple()) + now.microsecond * 1e-6

(Sorry, it wouldn’t let me comment on existing answer)


回答 4

如果您只需要使用unix / epoch时间的时间戳,则此行可以工作:

created_timestamp = int((datetime.datetime.now() - datetime.datetime(1970,1,1)).total_seconds())
>>> created_timestamp
1522942073L

并且仅取决于datetime python2和python3中的作品

if you just need a timestamp in unix /epoch time, this one line works:

created_timestamp = int((datetime.datetime.now() - datetime.datetime(1970,1,1)).total_seconds())
>>> created_timestamp
1522942073L

and depends only on datetime works in python2 and python3


回答 5

这适用于Python 2和3:

>>> import time
>>> import calendar
>>> calendar.timegm(time.gmtime())
1504917998

仅遵循官方文档… https://docs.python.org/2/library/time.html#module-time

This works in Python 2 and 3:

>>> import time
>>> import calendar
>>> calendar.timegm(time.gmtime())
1504917998

Just following the official docs… https://docs.python.org/2/library/time.html#module-time


回答 6

对于明确的时区独立解决方案,请使用pytz库。

import datetime
import pytz

pytz.utc.localize(datetime.datetime(2012,4,1,0,0), is_dst=False).timestamp()

输出(浮动):1333238400.0

For an explicit timezone-independent solution, use the pytz library.

import datetime
import pytz

pytz.utc.localize(datetime.datetime(2012,4,1,0,0), is_dst=False).timestamp()

Output (float): 1333238400.0


回答 7

在Python 3.7中

以date.isoformat()和datetime.isoformat()发出的格式之一返回与date_string对应的datetime。具体来说,此函数支持格式为YYYY-MM-DD [* HH [:MM [:SS [.fff [fff]]]] [+ HH:MM [:SS [.ffffff]]]]的字符串,其中*可以匹配任何单个字符。

https://docs.python.org/3/library/datetime.html#datetime.datetime.fromisoformat

In Python 3.7

Return a datetime corresponding to a date_string in one of the formats emitted by date.isoformat() and datetime.isoformat(). Specifically, this function supports strings in the format(s) YYYY-MM-DD[*HH[:MM[:SS[.fff[fff]]]][+HH:MM[:SS[.ffffff]]]], where * can match any single character.

https://docs.python.org/3/library/datetime.html#datetime.datetime.fromisoformat


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

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

我从来没有不得不将时间与UTC转换。最近有人要求我的应用注意时区,而且我一直在圈子里奔波。我发现很多关于将本地时间转换为UTC的信息,这很基本(也许我也做错了),但是我找不到任何有关将UTC时间轻松转换为最终用户时区的信息。

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

datetime.utcfromtimestamp(timestamp)

那似乎行得通。当我的应用存储数据时,存储时间要提前5个小时(我是EST -5)

数据存储在Appengine的BigTable上,并且在检索时会以如下所示的字符串形式出现:

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

如何在用户正确的时区将此字符串转换为DateTime?

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

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

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

datetime.utcfromtimestamp(timestamp)

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

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

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

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

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


回答 0

如果您不想提供自己的tzinfo对象,请签出python-dateutil库。它tzinfozoneinfo(Olson)数据库的顶部提供了实现,因此您可以使用一些规范的名称来引用时区规则。

from datetime import datetime
from dateutil import tz

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

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

# utc = datetime.utcnow()
utc = datetime.strptime('2011-01-21 02:37:21', '%Y-%m-%d %H:%M:%S')

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

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

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

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

编辑3种包含的时区自动检测方法(雅林)

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

from datetime import datetime
from dateutil import tz

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

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

# utc = datetime.utcnow()
utc = datetime.strptime('2011-01-21 02:37:21', '%Y-%m-%d %H:%M:%S')

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

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

Edit Expanded example to show strptime usage

Edit 2 Fixed API usage to show better entry point method

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


回答 1

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

from datetime import datetime
import time

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

这避免了DelboyJay示例中的计时问题。以及Erik van Oosten修正案中较少的计时问题。

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

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

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

要绕过不同的时间,请从传入的时间中获取新纪元时间。这是我的工作:

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

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

from datetime import datetime
import time

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

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

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

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

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

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

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

回答 2

请参阅有关tzinfo对象的日期时间文档。您必须实现自己想要支持的时区。这些是文档底部的示例。

这是一个简单的例子:

from datetime import datetime,tzinfo,timedelta

class Zone(tzinfo):
    def __init__(self,offset,isdst,name):
        self.offset = offset
        self.isdst = isdst
        self.name = name
    def utcoffset(self, dt):
        return timedelta(hours=self.offset) + self.dst(dt)
    def dst(self, dt):
            return timedelta(hours=1) if self.isdst else timedelta(0)
    def tzname(self,dt):
         return self.name

GMT = Zone(0,False,'GMT')
EST = Zone(-5,False,'EST')

print datetime.utcnow().strftime('%m/%d/%Y %H:%M:%S %Z')
print datetime.now(GMT).strftime('%m/%d/%Y %H:%M:%S %Z')
print datetime.now(EST).strftime('%m/%d/%Y %H:%M:%S %Z')

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

输出量

01/22/2011 21:52:09 
01/22/2011 21:52:09 GMT
01/22/2011 16:52:09 EST
2011-01-21 02:37:21+00:00
2011-01-20 21:37:21-05:00a

See the datetime documentation on tzinfo objects. You have to implement the timezones you want to support yourself. The are examples at the bottom of the documentation.

Here’s a simple example:

from datetime import datetime,tzinfo,timedelta

class Zone(tzinfo):
    def __init__(self,offset,isdst,name):
        self.offset = offset
        self.isdst = isdst
        self.name = name
    def utcoffset(self, dt):
        return timedelta(hours=self.offset) + self.dst(dt)
    def dst(self, dt):
            return timedelta(hours=1) if self.isdst else timedelta(0)
    def tzname(self,dt):
         return self.name

GMT = Zone(0,False,'GMT')
EST = Zone(-5,False,'EST')

print datetime.utcnow().strftime('%m/%d/%Y %H:%M:%S %Z')
print datetime.now(GMT).strftime('%m/%d/%Y %H:%M:%S %Z')
print datetime.now(EST).strftime('%m/%d/%Y %H:%M:%S %Z')

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

Output

01/22/2011 21:52:09 
01/22/2011 21:52:09 GMT
01/22/2011 16:52:09 EST
2011-01-21 02:37:21+00:00
2011-01-20 21:37:21-05:00a

回答 3

如果即使在与不确定的本地时间相对应的时间(例如,在DST转换期间)也要获得正确的结果,并且/或者本地utc偏移在您本地时区的不同时间不同,那么请使用pytz时区:

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

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

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

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

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

回答 4

如果您不想使用以外的任何其他模块,此答案应该会有所帮助datetime

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

如果不是实例化开始日期的人,但仍可以datetime在UTC时间创建一个天真的对象,则可能需要尝试使用以下Python 3.x代码对其进行转换:

import datetime

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

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

获取感知datetime对象的另一种简便方法(也是在Python 3.x中)是使用指定的时区开始创建对象。这是使用UTC的示例:

import datetime, sys

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

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

print(dt_obj_local.strftime(directive))

如果您使用Python 2.x,则可能必须继承datetime.tzinfo并使用它来帮助您创建感知datetime对象,因为datetime.timezonePython 2.x中不存在该对象。

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

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

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

import datetime

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

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

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

import datetime, sys

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

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

print(dt_obj_local.strftime(directive))

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


回答 5

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

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

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

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

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

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

回答 6

您可以使用箭头

from datetime import datetime
import arrow

now = datetime.utcnow()

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

你可以喂arrow.get()任何东西。时间戳,iso字符串等

You can use arrow

from datetime import datetime
import arrow

now = datetime.utcnow()

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

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


回答 7

我通常将其推迟到前端-从后端以时间戳或UTC中的其他日期时间格式发送时间,然后让客户端找出时区偏移量,并在适当的时区中呈现此数据。

对于Web应用程序,这在javascript中非常容易实现-您可以使用内置方法很容易地弄清浏览器的时区偏移量,然后从后端正确渲染数据。

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

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


回答 8

您可以calendar.timegm将Unix时代以来的时间转换为秒,然后time.localtime转换回:

import calendar
import time

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

print time.ctime(t)

赠送Fri Jan 21 05:37:21 2011(因为我处于UTC + 03:00时区)。

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

import calendar
import time

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

print time.ctime(t)

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


回答 9

import datetime

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

utc = '2018-10-17T00:00:00.111Z'
utc_fmt = '%Y-%m-%dT%H:%M:%S.%fZ'
local_fmt = '%Y-%m-%dT%H:%M:%S+08:00'
local_string = utc_str_to_local_str(utc, utc_fmt, local_fmt)
print(local_string)   # 2018-10-17T08:00:00+08:00

例如,我的时区为“ +08:00 ”。输入utc = 2018-10-17T00:00:00.111Z,那么我将得到输出= 2018-10-17T08:00:00 + 08:00

import datetime

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

utc = '2018-10-17T00:00:00.111Z'
utc_fmt = '%Y-%m-%dT%H:%M:%S.%fZ'
local_fmt = '%Y-%m-%dT%H:%M:%S+08:00'
local_string = utc_str_to_local_str(utc, utc_fmt, local_fmt)
print(local_string)   # 2018-10-17T08:00:00+08:00

for example, my timezone is ‘+08:00‘. input utc = 2018-10-17T00:00:00.111Z, then I will get output = 2018-10-17T08:00:00+08:00


回答 10

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

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

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

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

回答 11

这是一个快速而肮脏的版本,它使用本地系统设置来计算时差。注意:如果您需要转换为当前系统未在其中运行的时区,则此方法将不起作用。

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

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

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

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

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

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

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

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

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

回答 12

弗兰克桑德斯的答案合并为一种方便的方法。

import calendar
import datetime

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

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

Consolidating the answer from franksands into a convenient method.

import calendar
import datetime

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

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

使用pandas.to_datetime时仅保留日期部分

问题:使用pandas.to_datetime时仅保留日期部分

pandas.to_datetime用来解析数据中的日期。默认情况下,熊猫代表日期,datetime64[ns]即使所有日期都是每天也是如此。我想知道是否存在一种优雅/巧妙的方法来将日期转换为datetime.date或,datetime64[D]以便当我将数据写入CSV时,日期不附加00:00:00。我知道我可以手动逐个元素地转换类型:

[dt.to_datetime().date() for dt in df.dates]

但这确实很慢,因为我有很多行,这有点违反了使用目的pandas.to_datetime。有没有一种方法可以一次转换dtype整个列?或者,是否pandas.to_datetime支持精度规范,以便在处理日常数据时可以省去时间部分?

I use pandas.to_datetime to parse the dates in my data. Pandas by default represents the dates with datetime64[ns] even though the dates are all daily only. I wonder whether there is an elegant/clever way to convert the dates to datetime.date or datetime64[D] so that, when I write the data to CSV, the dates are not appended with 00:00:00. I know I can convert the type manually element-by-element:

[dt.to_datetime().date() for dt in df.dates]

But this is really slow since I have many rows and it sort of defeats the purpose of using pandas.to_datetime. Is there a way to convert the dtype of the entire column at once? Or alternatively, does pandas.to_datetime support a precision specification so that I can get rid of the time part while working with daily data?


回答 0

从版本开始,0.15.0现在可以轻松地通过.dt仅访问日期组件来完成此操作:

df['just_date'] = df['dates'].dt.date

上面的方法返回一个datetime.datedtype,如果您想要一个a,datetime64则可以normalize将时间分量设置为午夜,以便将所有值设置为00:00:00

df['normalised_date'] = df['dates'].dt.normalize()

这会使dtype保持不变,datetime64但显示屏仅显示该date值。

Since version 0.15.0 this can now be easily done using .dt to access just the date component:

df['just_date'] = df['dates'].dt.date

The above returns a datetime.date dtype, if you want to have a datetime64 then you can just normalize the time component to midnight so it sets all the values to 00:00:00:

df['normalised_date'] = df['dates'].dt.normalize()

This keeps the dtype as datetime64, but the display shows just the date value.


回答 1

简单的解决方案:

df['date_only'] = df['date_time_column'].dt.date

Simple Solution:

df['date_only'] = df['date_time_column'].dt.date

回答 2

虽然我赞成EdChum的答案,这是对OP提出的问题的最直接答案,但它并不能真正解决性能问题(它仍然依赖于python datetime对象,因此对它们的任何操作都不会被矢量化-即,它会很慢)。

性能更好的替代方法是使用df['dates'].dt.floor('d')。严格来说,它不会“仅保留日期部分”,因为它只是将时间设置为00:00:00。但是它确实可以按OP的要求运行,例如:

  • 打印到屏幕
  • 保存到csv
  • 使用列来 groupby

…并且效率更高,因为该操作已矢量化。

编辑:其实,在OP的宁愿答案很可能是“最近的版本pandas没有时间写为csv如果是00:00:00对所有的意见”。

While I upvoted EdChum’s answer, which is the most direct answer to the question the OP posed, it does not really solve the performance problem (it still relies on python datetime objects, and hence any operation on them will be not vectorized – that is, it will be slow).

A better performing alternative is to use df['dates'].dt.floor('d'). Strictly speaking, it does not “keep only date part”, since it just sets the time to 00:00:00. But it does work as desired by the OP when, for instance:

  • printing to screen
  • saving to csv
  • using the column to groupby

… and it is much more efficient, since the operation is vectorized.

EDIT: in fact, the answer the OP’s would have preferred is probably “recent versions of pandas do not write the time to csv if it is 00:00:00 for all observations”.


回答 3

熊猫DatetimeIndexSeries有一种方法normalize可以完全满足您的需求。

您可以在此答案中了解更多信息。

可以用作 ser.dt.normalize()

Pandas DatetimeIndex and Series have a method called normalize that does exactly what you want.

You can read more about it in this answer.

It can be used as ser.dt.normalize()


回答 4

熊猫v0.13 +:to_csvdate_format参数一起使用

尽可能避免将您的datetime64[ns]系列转换为objectdtype系列的datetime.date对象。后者通常使用构造pd.Series.dt.date,存储为指针数组,相对于基于NumPy的纯序列而言效率低下。

由于在写入CSV时您关注的是格式,因此只需使用date_format参数to_csv。例如:

df.to_csv(filename, date_format='%Y-%m-%d')

有关格式设置约定,请参见Python的strftime指令

Pandas v0.13+: Use to_csv with date_format parameter

Avoid, where possible, converting your datetime64[ns] series to an object dtype series of datetime.date objects. The latter, often constructed using pd.Series.dt.date, is stored as an array of pointers and is inefficient relative to a pure NumPy-based series.

Since your concern is format when writing to CSV, just use the date_format parameter of to_csv. For example:

df.to_csv(filename, date_format='%Y-%m-%d')

See Python’s strftime directives for formatting conventions.


回答 5

这是提取日期的简单方法:

import pandas as pd

d='2015-01-08 22:44:09' 
date=pd.to_datetime(d).date()
print(date)

This is a simple way to extract the date:

import pandas as pd

d='2015-01-08 22:44:09' 
date=pd.to_datetime(d).date()
print(date)

回答 6

转换为datetime64[D]

df.dates.values.astype('M8[D]')

尽管将其重新分配给DataFrame col将其恢复为[ns]。

如果您想要实际的datetime.date

dt = pd.DatetimeIndex(df.dates)
dates = np.array([datetime.date(*date_tuple) for date_tuple in zip(dt.year, dt.month, dt.day)])

Converting to datetime64[D]:

df.dates.values.astype('M8[D]')

Though re-assigning that to a DataFrame col will revert it back to [ns].

If you wanted actual datetime.date:

dt = pd.DatetimeIndex(df.dates)
dates = np.array([datetime.date(*date_tuple) for date_tuple in zip(dt.year, dt.month, dt.day)])

回答 7

如果有人看到此旧帖子,请给出一个最新的答案。

转换为日期时间时添加“ utc = False”将删除时区部分,仅将日期保留为datetime64 [ns]数据类型。

pd.to_datetime(df['Date'], utc=False)

您将能够将其保存在excel中,而不会出现错误“ ValueError:Excel不支持带时区的日期时间。在写入Excel之前,请确保日期时间不知道时区。”

Just giving a more up to date answer in case someone sees this old post.

Adding “utc=False” when converting to datetime will remove the timezone component and keep only the date in a datetime64[ns] data type.

pd.to_datetime(df['Date'], utc=False)

You will be able to save it in excel without getting the error “ValueError: Excel does not support datetimes with timezones. Please ensure that datetimes are timezone unaware before writing to Excel.”


回答 8

我希望能够更改数据框中一组列的类型,然后删除保持一天的时间。round(),floor(),ceil()全部工作

df[date_columns] = df[date_columns].apply(pd.to_datetime)
df[date_columns] = df[date_columns].apply(lambda t: t.dt.floor('d'))

I wanted to be able to change the type for a set of columns in a data frame and then remove the time keeping the day. round(), floor(), ceil() all work

df[date_columns] = df[date_columns].apply(pd.to_datetime)
df[date_columns] = df[date_columns].apply(lambda t: t.dt.floor('d'))