DateUtils.py 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351
  1. import time
  2. from datetime import date, datetime, timedelta
  3. import calendar
  4. from dateutil.relativedelta import relativedelta
  5. class DateUtils:
  6. """
  7. 时间相关函数封装
  8. """
  9. def __init__(self):
  10. self.today = datetime.strptime(datetime.today().strftime("%Y-%m-%d"), "%Y-%m-%d")
  11. self.daydelta = timedelta(days=1)
  12. self.now = datetime.now()
  13. def add_days(self,str, interval):
  14. return (datetime.strptime(str,'%Y-%m-%d')+timedelta(days=interval)).strftime('%Y-%m-%d')
  15. def split_date(self,start, end, interval, func):
  16. """把时间拆分多次运行"""
  17. st = start
  18. et = self.add_days(st, interval - 1)
  19. while True:
  20. if et >= end:
  21. et = end
  22. print(f"{st}~{et}")
  23. func(st, et)
  24. break
  25. else:
  26. print(f"{st}~{et}")
  27. func(st, et)
  28. st = self.add_days(et, 1)
  29. et = self.add_days(st, interval - 1)
  30. def split_date2(self, start, end, interval):
  31. """:returns [(st1,et1),(st2,et2)..]"""
  32. li = []
  33. while True:
  34. next_date = self.add_days(start, interval-1)
  35. if next_date >= end:
  36. li.append((start, end))
  37. break
  38. else:
  39. li.append((start, next_date))
  40. start = self.add_days(next_date, 1)
  41. # print(li)
  42. return li
  43. def date_str_to_str(self,str,f1='%Y-%m-%d',f2='%Y%m%d'):
  44. return datetime.strptime(str,f1).strftime(f2)
  45. def getDateLists(self, begin, end):
  46. """
  47. 返回一个时间列表
  48. """
  49. interval = self.getInterval(begin, end)
  50. print(interval)
  51. return [self.getLastDays(begin, -x) for x in range(interval + 1)]
  52. def getTodayOrYestoday(self):
  53. """
  54. 如果当天零点 则返回昨天
  55. 否则返回今天
  56. :return:
  57. """
  58. if self.now.hour==0:
  59. return self.get_n_days(-1)
  60. else:
  61. return self.get_n_days(0)
  62. def getMonthLists(self, begin, end):
  63. begin_date = datetime.strptime(begin, "%Y-%m").date()
  64. end_date = datetime.strptime(end, '%Y-%m').date()
  65. temp = end_date
  66. month_list = []
  67. while temp >= begin_date:
  68. month_list.append(temp.strftime('%Y-%m'))
  69. temp = self.get_before_month(temp.year, temp.month, 1, 1)
  70. month_list.reverse()
  71. return month_list
  72. def getLastDays(self, begin, interval):
  73. """
  74. :param begin:
  75. :param interval: 正数是之前几天, 负数是之后几天
  76. :return:
  77. """
  78. start = datetime(int(begin[0:4]), int(begin[5:7]), int(begin[8:10]))
  79. delta = timedelta(days=1)
  80. if interval < 0:
  81. for _ in range(0, -interval):
  82. start = start + delta
  83. else:
  84. for _ in range(0, interval):
  85. start = start - delta
  86. return start.strftime("%Y-%m-%d")
  87. def get_n_month_ago_begin(self, begin, n):
  88. year = int(begin[:4])
  89. month = int(begin[5:7])
  90. if n > 0:
  91. for i in range(0, n):
  92. month -= 1
  93. if month == 0:
  94. month = 12
  95. year -= 1
  96. else:
  97. for i in range(0, -n):
  98. if month == 12:
  99. month = 0
  100. year += 1
  101. month += 1
  102. return date(year, month, 1).strftime('%Y-%m')
  103. def get_n_days(self, interval=0, flag=0):
  104. """
  105. 负数,过去的几天
  106. 正数,未来的几天
  107. :param interval:
  108. :param flag: 1 返回 timedelta
  109. :return:
  110. """
  111. start = self.today
  112. if interval < 0:
  113. for _ in range(0, -interval):
  114. start = start - self.daydelta
  115. else:
  116. for _ in range(0, interval):
  117. start = start + self.daydelta
  118. if flag == 1:
  119. return start
  120. else:
  121. return start.strftime("%Y-%m-%d")
  122. def getNow(self):
  123. """
  124. 获取当天时间
  125. :return: 当天时间的字符串
  126. """
  127. now = datetime.now()
  128. return now.strftime("%Y-%m-%d")
  129. def getWeek(self, begin):
  130. return datetime(int(begin[0:4]), int(begin[5:7]), int(begin[8:10])).strftime("%w")
  131. def get_today_before_month(self, n):
  132. """
  133. 获取之前n个月
  134. :param n:
  135. :return:
  136. """
  137. year = time.localtime()[0]
  138. month = time.localtime()[1]
  139. for i in range(0, n):
  140. month -= 1
  141. if month == 0:
  142. month = 12
  143. year -= 1
  144. return year, month
  145. def get_one_month_ago(self, flag=0):
  146. """
  147. 返回一个月前的时间, 默认返回格式化时间字符串
  148. flag 1 返回 datetime
  149. :param flag:
  150. :return:
  151. """
  152. x = self.today-relativedelta(months=1)
  153. if flag == 1:
  154. return x
  155. else:
  156. return x.strftime("%Y-%m-%d")
  157. def get_today_before_month_list(self, n=0):
  158. year = time.localtime()[0]
  159. month = time.localtime()[1]
  160. ret = []
  161. for i in range(0, n):
  162. month -= 1
  163. if month == 0:
  164. month = 12
  165. year -= 1
  166. if month >= 10:
  167. ret.append(str(year) + "-" + str(month) + "-" + "01")
  168. else:
  169. ret.append(str(year) + "-0" + str(month) + "-" + "01")
  170. return ret
  171. def get_before_month(self, year, month, day, n):
  172. for i in range(0, n):
  173. month -= 1
  174. if month == 0:
  175. month = 12
  176. year -= 1
  177. day = min(day, calendar.monthrange(year, month)[1])
  178. return date(year, month, day)
  179. def getInterval(self, begin, end):
  180. t1 = datetime(int(begin[0:4]), int(begin[5:7]), int(begin[8:10]))
  181. t2 = datetime(int(end[0:4]), int(end[5:7]), int(end[8:10]))
  182. return (t2 - t1).days
  183. def month_first_day(self, flag=False):
  184. """
  185. 返回当月第一天
  186. 若为1号,则返回上个月1号
  187. :param flag:
  188. :return:
  189. """
  190. if self.today.day == 1:
  191. # 如果当日是月初1号,则返回上月1号
  192. if self.today.month == 1:
  193. tmp = date(self.today.year - 1, 12, 1)
  194. else:
  195. tmp = date(self.today.year, self.today.month - 1, 1)
  196. else:
  197. tmp = date(self.today.year, self.today.month, 1)
  198. return tmp if flag else tmp.strftime("%Y-%m-%d")
  199. def get_today(self, flag=False):
  200. return self.today if flag else self.today.strftime("%Y-%m-%d")
  201. def get_n_pre_month_first_day(self, n, flag=False):
  202. """
  203. 获取 n 个月前第一天
  204. """
  205. r = self.get_before_month(self.today.year, self.today.month, 1, n)
  206. return r if flag else r.strftime("%Y-%m-%d")
  207. def get_n_month_ago(self, n, flag=0):
  208. d = self.get_before_month(self.today.year, self.today.month, self.today.day, n)
  209. return d.strftime("%Y-%m-%d") if flag == 0 else d
  210. def get_week_ago(self, flag=False):
  211. """
  212. :param: None
  213. :return: 7 days ago
  214. """
  215. tmp = (self.today - timedelta(days=7))
  216. return tmp if flag else tmp.strftime("%Y-%m-%d")
  217. def get_week_first_day(self, flag=False):
  218. """
  219. 返回当前天的一周开始
  220. :param flag:
  221. :return:
  222. """
  223. # print self.today.day
  224. if self.today.weekday() == 0:
  225. # 如果当天是周一,则返回上周一日期
  226. tmp = self.today - timedelta(days=7)
  227. else:
  228. tmp = self.today - timedelta(days=self.today.weekday())
  229. return tmp if flag else tmp.strftime("%Y-%m-%d")
  230. def get_one_day_ago(self, flag=False):
  231. """
  232. :param: None
  233. :return: 1 day ago
  234. """
  235. tmp = (self.today - timedelta(days=1))
  236. return tmp if flag else tmp.strftime("%Y-%m-%d")
  237. def get_start(self, s_start=date.today().strftime("%Y-%m-%d")):
  238. return datetime(int(s_start[0:4]), int(s_start[5:7]), int(s_start[8:10]))
  239. def get_n_hours_ago(self, n=1, flag = 0):
  240. """
  241. get n hous ago
  242. flag is True return datetime format
  243. default 1 hours ago
  244. if n > 0 :
  245. 过去时间
  246. else:
  247. 未来时间
  248. :param n:
  249. :return:
  250. """
  251. r = self.now - timedelta(hours=n)
  252. return r if flag else r.strftime("%Y-%m-%d %H:00:00")
  253. def get_n_minutes_ago(self, n=1):
  254. """
  255. get n minutes ago
  256. default 1 minutes ago
  257. if n > 0 :
  258. 过去时间
  259. else:
  260. 未来时间
  261. :param n:
  262. :return:
  263. """
  264. return (self.now - timedelta(minutes=n)).strftime("%Y-%m-%d %H:%M:%S")
  265. def get_n_pre_month_last_day(self, n=0, flag=False):
  266. """
  267. 获取 n 个月前的最后一天
  268. :param n:
  269. :param flag:
  270. :return:
  271. """
  272. r = self.get_before_month(self.today.year, self.today.month, 1, n)
  273. num = calendar.monthrange(r.year, r.month)[1]
  274. x = r.replace(day=num)
  275. return x if flag else x.strftime("%Y-%m-%d")
  276. @staticmethod
  277. def str_to_stamp(str, f='%Y-%m-%d'):
  278. return int(time.mktime(time.strptime(str,f)))
  279. @staticmethod
  280. def stamp_to_str(stamp, f="%Y-%m-%d %H:%M:%S"):
  281. """
  282. @:param stamp->int
  283. @:return ->str
  284. """
  285. if isinstance(stamp,str):
  286. stamp = int(stamp)
  287. if len(str(stamp))==13:
  288. stamp = round(stamp/1000)
  289. return time.strftime(f, time.localtime(stamp))
  290. @staticmethod
  291. def stamp_to_date_stamp(stamp):
  292. return DateUtils.str_to_stamp(DateUtils.stamp_to_str(stamp,'%Y-%m-%d'),'%Y-%m-%d')
  293. @staticmethod
  294. def str_to_date_str(str, f1='%Y-%m-%d',f2='%Y%m%d'):
  295. return datetime.strptime(str, f1).strftime(f2)
  296. if __name__ == "__main__":
  297. ut = DateUtils()
  298. # print(DateUtils.str_to_date_str('2012-02-01',f2="%Y-%m-%dT%H:%M:%S+08:00"))
  299. print(ut.today)