【Python】【专题】(datetime)不完全详解 datetime 库及 datetime 应用实例



1. 详解 - 0% - 未完成



2. 高效利用 datetime 库计算时间


2.1 求两个时间差的 年,月,日,时,分,秒

刚好今天我要对爬虫爬取设定一个最小周期。

所以重写 一份计算两个 datetime 相差时间的程序,
暂时是我想到最简单的方法了。
对于求差能够用时间的 60 进制移位。

N/A

N/A

源码 👇

class EasyDeltaDatetime():
    from datetime import datetime

    def __init__(self, dstDatetime, srcDatetime):
        self.dstDatetime = dstDatetime
        self.srcDatetime = srcDatetime
        self.computer_zero_datetime = datetime(1970, 1, 1, 0, 0, 0)
        self.calculate()

    def calculate(self):
        self.difference = self.dstDatetime - self.srcDatetime
        self.meta_datetime = self.computer_zero_datetime + self.difference

    def __getattr__(self, attrname):
        if attrname in ["year", "month", "day", "hour", "minute", "second"]:
            return int(getattr(self.meta_datetime, attrname) - getattr(self.computer_zero_datetime, attrname))

注意:datetime.now()datetime(...) 不能相减的错误

datetime.now() 没有指定 timezone,和通过 datetime(..., tzinfo=...) 实例化的对象相减会出现:

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

如果需要使用 datetime.now(),则需要指定其 timezone

datetime.now().replace(tzinfo=pytz.timezone("UTC"))

即,将 datetime.now() 替换成上面 👆 这行即可。


2.2 To datetime

2.2.1 转换时间戳(time.time)为 datetime

time 库 和 datetime 库互换

>>> import time                                                                                                
>>> time.time()                                                                                                
1559545564.3678553
>>> int(time.time())                                                                                           
1559545575
>>> import datetime                                                                                            
>>> datetime.datetime.fromtimestamp(int(time.time()))                                                          
datetime.datetime(2019, 6, 3, 15, 8, 15)
>>> 

Reference: python学习笔记:time()和datetime()时间模块的基本使用和示例

2.2.2 转换字符串为 datetime
>>> import datetime as dt
>>> dt_ = dt.datetime(2019, 8, 20, 9, 7, 54)
>>> print(repr(dt_))
datetime.datetime(2019, 8, 20, 9, 7, 54)
>>> dt_s = dt_.strftime(format="%Y-%m-%d %H:%M:%S")
>>> print(dt_s)  # 字符串
2019-08-20 09:07:54
>>> #### 通过 time 库转换  ####
>>> import time
>>> tdt = time.strptime(dt_s, "%Y-%m-%d %H:%M:%S")
>>> print(repr(tdt))
time.struct_time(tm_year=2019, tm_mon=8, tm_mday=20, tm_hour=9, tm_min=7, tm_sec=54, tm_wday=1, tm_yday=232, tm_isdst=-1)
>>> dt.datetime(*tdt[:-3])
datetime.datetime(2019, 8, 20, 9, 7, 54)
>>> # sort code: dt.datetime(*time.strptime(dt_s, "%Y-%m-%d %H:%M:%S")[:-3])
>>> #### 直接通过 datetime 库提供的接口转换 ####
>>> dt.datetime.strptime(dt_s, '%Y-%m-%d %H:%M:%S')
datetime.datetime(2019, 8, 20, 9, 7, 54)
>>> 


3. 使用 “2018-12-27” 格式获取(django-数据库中)最接近的日期的一条数据

核心代码:

try:
    visualdatas = UserID.objects.get(
        user_id=self.kwargs["user_id"]
    ).visualdata_set.all()
    filter_date = datetime.datetime.strptime(
        self.kwargs['date'], "%Y-%m-%d").date()
    qs = visualdatas.filter(crawlerDate__year=filter_date.year,
                            crawlerDate__month=filter_date.month, )
    d = {_.crawlerDate.day: _ for _ in qs}
    return d[min(d.keys(), key=lambda _: abs(_ - filter_date.day))]
except Exception as e:
    print(e, file=sys.stderr)
    raise Http404("{}".format(e))  # -[o] update to DRF response type later

Reference:
Python date string to date object: https://stackoverflow.com/questions/2803852/python-date-string-to-date-object

👆 对应 line 5, 6

How can I filter a date of a DateTimeField in Django?: https://stackoverflow.com/questions/1317714/how-can-i-filter-a-date-of-a-datetimefield-in-django

👆 对应 line 7, 8

Python 字典推导 - n/a ⇒ 对应 line 9

python build-in function min: https://docs.python.org/3/library/functions.html?highlight=min#min

👆 对应 line 10

Python lambda 表达式 - n/a ⇒ 对应 line 10

该段代码为我的一个项目中 DRF 部分的部分代码。
核心代码 的所有有关代码:

useridvisualdatamodels.py 部分:

class BaseUserIDInfo(models.Model):
    user_id = models.CharField(max_length=128)
    name = models.CharField(max_length=512, default='')

    class Meta:
        abstract = True


class UserID(BaseUserIDInfo, BaseUserInfo):
    regitster_date = models.DateTimeField(
        'User Regitster Date',
        default=datetime(1970, 1, 1, 0, 0, 0, tzinfo=pytz.timezone("UTC")), )
    signature = [...the other codes not important...]

class VisualData(models.Model):
    user_id = ForeignKey(UserID, on_delete=models.CASCADE)
    crawlerDate = DateTimeField('data crowler date', auto_now=True)

    originality = IntegerField(default=-1)  # 原创文章数量
    reprint = IntegerField(default=-1)  # 转发数量
    [...the other codes not important...]

urls.py 部分:

[...]
urlpatterns = [
    [...]

    # visualdatas/[{}/]
    path("userids/<str:user_id>/visualdatas/",
         VisualDataList.as_view(), name="visualdatas_list"),
    path("userids/<str:user_id>/visualdatas/<str:date>/", 
          VisualDataDetail.as_view(), name="visualdatas_detail"),

views.py 部分的该部分完整代码:

class VisualDataViewCommonMixin(object):
    serializer_class = VisualDataSerialzier

    def get_queryset(self):
        _ = get_object_or_404(UserID, user_id=self.kwargs["user_id"])
        return _.visualdata_set.all()


class VisualDataList(VisualDataViewCommonMixin, generics.ListCreateAPIView):

class VisualDataDetail(VisualDataViewCommonMixin, generics.RetrieveDestroyAPIView):
    def get_object(self):
        try:
            visualdatas = super().get_queryset()
            filter_date = datetime.datetime.strptime(
                self.kwargs['date'], "%Y-%m-%d").date()
            qs = visualdatas.filter(crawlerDate__year=filter_date.year,
                                    crawlerDate__month=filter_date.month, )
            d = {_.crawlerDate.day: _ for _ in qs}
            return d[min(d.keys(), key=lambda _: abs(_ - filter_date.day))]
        except Exception as e:
            print(e, file=sys.stderr)
            raise Http404("{}".format(e))  # -[o] update to DRF response type later
            

考虑 urls.pyviews.py 实现的功能,以下是运行效果截图:
如果存在当天的数据即显示当天的数据 👇
如果存在当天的数据即显示当天的数据
最接近的日期示例 👇
最接近的日期示例



4. django 中的 datetime


4.1 django model 模型的 DateTimeField 的一些使用细节

🔗 👉 https://blog.csdn.net/qq_29757283/article/details/83188766

4.1.1 为 DateTimeField 设置 default 为计算机元年

🔗 👇
https://blog.csdn.net/qq_29757283/article/details/83188766#_DateTimeField__default__10

4.1.2 使用 标准库 datetime.datetime() 为该 Field 赋值 - timezone 问题

🔗 👇

https://blog.csdn.net/qq_29757283/article/details/83188766#__datetimedatetime__Field__34

4.1.3 在 manage.py shell 中 timezone 显示不一致问题

🔗 👇

https://blog.csdn.net/qq_29757283/article/details/83188766#_managepy_shell__timezone__84

4.1.4 使用 django模型实例渲染模板的 date 显示问题

🔗 👉 https://blog.csdn.net/qq_29757283/article/details/83449253 - 正确的时区时间和显示格式



5. 一些应用

5.1 获取昨天日期

Reference: Python 获取昨天日期

ex. 1:

# 引入 datetime 模块
import datetime
def getYesterday(): 
    today=datetime.date.today() 
    oneday=datetime.timedelta(days=1) 
    yesterday=today-oneday  
    return yesterday
 
# 输出
print(getYesterday())

ex. 2:

# 引入 datetime 模块
import datetime

def get_yesterday(): 
    yesterday = datetime.date.today() + datetime.timedelta(-1)
    return yesterday
# 输出
print(get_yesterday())


Reference

n/a



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值