utils_datetime.py 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. # -*- coding: utf-8 -*-
  2. # !/usr/bin/env python
  3. import time
  4. import datetime
  5. from typing import Union, Tuple
  6. from dateutil.relativedelta import relativedelta
  7. from apilib.utils_string import basestring_type
  8. from typing import Optional
  9. """
  10. 由于Python的_strptime会在多线程时出现bug,需要首先引入 import _strptime
  11. [0] https://stackoverflow.com/questions/2427240/thread-safe-equivalent-to-pythons-time-strptime
  12. """
  13. def get_zero_time(the_datetime):
  14. zero_time = None
  15. if isinstance(the_datetime, datetime.date):
  16. str_time = the_datetime.strftime("%Y-%m-%d") + " 00:00:00"
  17. zero_time = datetime.datetime.strptime(str_time, "%Y-%m-%d %H:%M:%S")
  18. return zero_time
  19. def get_tomorrow_zero_time(the_datetime):
  20. # type: (datetime)->datetime
  21. zero_time = None
  22. str_time = the_datetime.strftime("%Y-%m-%d") + " 00:00:00"
  23. zero_time = datetime.datetime.strptime(str_time, "%Y-%m-%d %H:%M:%S")
  24. return zero_time + datetime.timedelta(days = 1)
  25. # 根据当前时间获取时间戳,返回整数
  26. def generate_timestamp():
  27. return long(time.time())
  28. def generate_timestamp_ex():
  29. return long(time.time() * 1000)
  30. def date_to_datetime(date, start_or_end):
  31. # type: (Union[basestring_type, datetime.date], str)->datetime.datetime
  32. if isinstance(date, basestring_type):
  33. date = datetime.datetime.strptime(date, '%Y-%m-%d')
  34. else:
  35. date = date
  36. if start_or_end == 'start':
  37. time_ = datetime.time.min
  38. elif start_or_end == 'end':
  39. time_ = datetime.time.max
  40. else:
  41. raise Exception('only `start` or `end` are allowed for argument `start_or_end` given %s' % (start_or_end,))
  42. return datetime.datetime.combine(date, time_)
  43. def defaultTodayDate(x): return datetime.datetime.now().strftime('%Y-%m-%d') if x is None else x
  44. def date_to_datetime_floor(date = None):
  45. if date is None:
  46. return datetime.datetime.now()
  47. else:
  48. return date_to_datetime(date = date, start_or_end = 'start')
  49. def date_to_datetime_ceiling(date = None):
  50. if date is None:
  51. return datetime.datetime.now()
  52. else:
  53. return date_to_datetime(date = date, start_or_end = 'end')
  54. def datetime_range(dt):
  55. # type:(datetime.datetime)->Tuple[datetime.datetime, datetime.datetime]
  56. assert isinstance(dt, datetime.datetime)
  57. combine = datetime.datetime.combine
  58. date = dt.date()
  59. return combine(date, datetime.time.min), combine(date, datetime.time.max)
  60. def today_datetime_range(): return datetime_range(datetime.datetime.now())
  61. def dt_to_timestamp(dt): return time.mktime(dt.timetuple())
  62. def local2utc(local_time):
  63. time_struct = time.mktime(local_time.timetuple())
  64. utc_st = datetime.datetime.utcfromtimestamp(time_struct)
  65. return utc_st
  66. timestamp_to_dt = datetime.datetime.fromtimestamp
  67. datetime_to_timestamp = dt_to_timestamp
  68. def today_format_str(): return datetime.datetime.now().strftime("%Y-%m-%d")
  69. def yesterday_format_str(): return (datetime.datetime.now() - datetime.timedelta(days = 1)).strftime('%Y-%m-%d')
  70. def the_day_before_yesterday_format_str(): return (datetime.datetime.now() - datetime.timedelta(days = 2)).strftime(
  71. '%Y-%m-%d')
  72. def this_month_format_str(): return datetime.datetime.now().strftime('%Y-%m')
  73. def last_month_format_str(): return (datetime.datetime.today() - relativedelta(months = 1)).strftime('%Y-%m')
  74. def timestamp_timeformat(timeStamp): return time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(timeStamp))
  75. def first_day_datetime_of_month(date = None, time_format = '%Y-%m-%d %H:%M:%S'):
  76. # type: (Optional[datetime], Optional[str])->datetime
  77. if not date:
  78. date = datetime.datetime.now()
  79. return datetime.datetime.strptime('%s-%s-01 00:00:00' % (date.year, date.month), time_format)
  80. def to_datetime(ts_or_str, time_format = "%Y-%m-%d %H:%M:%S"):
  81. if isinstance(ts_or_str, basestring):
  82. return datetime.datetime.strptime(ts_or_str, time_format)
  83. elif isinstance(ts_or_str, int) or isinstance(ts_or_str, long) or isinstance(ts_or_str, float):
  84. return datetime.datetime.fromtimestamp(ts_or_str)
  85. elif isinstance(ts_or_str, datetime.datetime):
  86. return ts_or_str
  87. else:
  88. assert False, u'参数错误'
  89. def to_timestamp(ts_or_str, time_format = "%Y-%m-%d %H:%M:%S"):
  90. if isinstance(ts_or_str, basestring):
  91. return dt_to_timestamp(to_datetime(ts_or_str, time_format))
  92. elif isinstance(ts_or_str, int) or isinstance(ts_or_str, long) or isinstance(ts_or_str, float):
  93. return ts_or_str
  94. elif isinstance(ts_or_str, datetime.datetime):
  95. return dt_to_timestamp(ts_or_str)
  96. else:
  97. assert False, '参数错误'
  98. def datetime_between_months(months = 6):
  99. begin = datetime.datetime.now() - relativedelta(months = months)
  100. begin = datetime.datetime(begin.year, begin.month, 1)
  101. end = datetime.datetime.now() + datetime.timedelta(hours = 1)
  102. return begin, end
  103. def last_day_datetime_of_this_month(inputTime = None):
  104. if not inputTime:
  105. inputTime = datetime.datetime.now()
  106. nextMonthDay = inputTime + relativedelta(months = 1)
  107. return first_day_datetime_of_month(nextMonthDay) - datetime.timedelta(days=1)
  108. def get_month_days(year, month):
  109. """
  110. 获取一个月的所有天的列表
  111. :param year: 年份
  112. :param month: 月份
  113. :return: 该月所有天的列表
  114. """
  115. # 获取该月的第一天
  116. first_day = datetime.date(year, month, 1)
  117. # 获取该月的下一个月的第一天
  118. next_month = datetime.date(year, month + 1, 1) if month != 12 else datetime.date(year + 1, 1, 1)
  119. # 生成该月所有天的列表
  120. days = [(first_day + datetime.timedelta(days=i)).day for i in range((next_month - first_day).days)]
  121. return days