datetime_utils.py 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. import time
  2. from datetime import date, timedelta, datetime
  3. from dateutil import parser
  4. def add_days(dt: str, number: int, original_fmt: str = '%Y%m%d', dst_fmt: str = '%Y%m%d'):
  5. return (parse_datetime(dt, original_fmt) + timedelta(days=number)).strftime(dst_fmt)
  6. def date_to_timestamp(date_str: str, time_unit: int = 1) -> float:
  7. """
  8. 字符串日期转时间戳
  9. Args:
  10. date_str: 字符串的日期
  11. time_unit: 时间戳单位,1为秒(默认),2为毫秒,3为微秒
  12. Returns: 时间戳
  13. """
  14. return datetime_to_timestamp(parse_datetime(date_str), time_unit)
  15. def datetime_to_timestamp(date_time: datetime, time_unit: int = 1) -> float:
  16. """
  17. datetime 转时间戳
  18. Args:
  19. date_time: datetime
  20. time_unit: 时间戳单位,1为秒(默认),2为毫秒,3为微秒
  21. Returns: 时间戳
  22. """
  23. timestamp = date_time.timestamp() * 1000000
  24. timestamp = float(str(timestamp) + str("%06d" % date_time.microsecond))
  25. if time_unit == 3:
  26. return timestamp
  27. elif time_unit == 2:
  28. return timestamp / 1000
  29. else:
  30. return timestamp / 1000000
  31. def formatted_now(fmt: str = '%Y-%m-%d %H:%M:%S') -> str:
  32. return time.strftime(fmt, time.localtime())
  33. def get_date_by_priority(cli_dt: str, config_dt: str) -> str:
  34. # 计算实际日期,优先级: 命令行 > 配置文件 > 默认
  35. if cli_dt:
  36. dt = cli_dt
  37. elif config_dt:
  38. dt = config_dt
  39. else:
  40. dt = get_yesterday()
  41. return dt
  42. def get_date_range(some_date: str) -> [str]:
  43. """
  44. 获取日期范围
  45. Args:
  46. some_date: 日期参数,有四种表示法 —— 20210801、 20210801-、20210801-20210810、20210801,20210803,20210805
  47. Returns: 日期范围
  48. """
  49. if not some_date:
  50. return [get_yesterday()]
  51. date_range = []
  52. if len(some_date) == 8:
  53. date_range.append(some_date)
  54. elif (len(some_date) == 9 or len(some_date) == 17) and some_date[8] == '-':
  55. date_cursor = some_date[:8]
  56. if len(some_date) == 9:
  57. # 20210801-格式
  58. end_date = get_yesterday()
  59. else:
  60. # 20210801-20210810格式
  61. end_date = some_date[9:]
  62. while date_cursor <= end_date:
  63. date_range.append(date_cursor)
  64. date_cursor = (datetime.strptime(date_cursor, '%Y%m%d') + timedelta(days=1)).strftime('%Y%m%d')
  65. elif set([len(e) for e in some_date.split(',')]).pop() == 8:
  66. date_range = some_date.split(',')
  67. else:
  68. raise Exception('无效的日期表达形式 %s' % some_date)
  69. return date_range
  70. def parse_datetime(date_time: str, original_format: str = None) -> datetime:
  71. """解析日期字符串为 datetime:传 original_format 按它解析,否则用 dateutil 自动识别。
  72. Args:
  73. date_time: 日期
  74. original_format: 原日期格式
  75. Returns:
  76. 转换后的日期
  77. """
  78. if not date_time:
  79. return None
  80. # raise ValueError('date_time is null')
  81. try:
  82. if original_format:
  83. parsed_date = datetime.strptime(date_time, original_format)
  84. else:
  85. parsed_date = parser.parse(date_time, fuzzy=True)
  86. except Exception as e:
  87. raise e
  88. return parsed_date
  89. def get_today(fmt: str = '%Y%m%d') -> str:
  90. return date.today().strftime(fmt)
  91. def get_yesterday(fmt: str = '%Y%m%d') -> str:
  92. return (date.today() - timedelta(days=1)).strftime(fmt)
  93. def local_2_utc(some_date: str) -> datetime:
  94. # 本地时间转 UTC 时间( -8:00 )
  95. # + ' 00:00:00'
  96. utc_date = datetime.utcfromtimestamp(date_to_timestamp(some_date))
  97. return utc_date
  98. if __name__ == '__main__':
  99. print(parse_datetime('2024年03月10日'.replace('年', '-').replace('月', '-').replace('日', '')))