xtn-tools-pro 1.0.0.0.4__py3-none-any.whl → 1.0.0.0.6__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,123 @@
1
+ #!/usr/bin/env python
2
+ # -*- coding: utf-8 -*-
3
+
4
+ # 说明:
5
+ # 杂七杂八
6
+ # History:
7
+ # Date Author Version Modification
8
+ # --------------------------------------------------------------------------------------------------
9
+ # 2024/5/13 xiatn V00.01.000 新建
10
+ # --------------------------------------------------------------------------------------------------
11
+ import re
12
+ import uuid
13
+ import math
14
+ import json
15
+ from uuid import UUID
16
+ from pprint import pformat
17
+ from urllib.parse import urlencode
18
+
19
+
20
+ def get_uuid(version=4, namespace: UUID = uuid.NAMESPACE_DNS, name=""):
21
+ """
22
+ 生成uuid
23
+ :param version:版本号
24
+ 1:基于当前时间和 MAC 地址生成版本 1 的 UUID,具有唯一性,但可能存在一定的安全风险。
25
+ 3:基于名称和命名空间的方式生成。它通过将名称和命名空间的标识符组合起来进行哈希计算,生成一个唯一的标识符。UUID 版本 3 使用的哈希算法是 MD5。
26
+ 4:使用随机数生成版本 4 的 UUID,具有足够的随机性和唯一性。
27
+ 5:使用基于命名空间和名称生成版本 5 的 UUID,可以使用自定义的命名空间和名称。
28
+ :param namespace:命名空间 uuid.NAMESPACE_DNS、uuid.NAMESPACE_URL、uuid.NAMESPACE_OID、uuid.NAMESPACE_X500
29
+ :param name:名称 自定义
30
+ :return:
31
+ """
32
+ if version == 1:
33
+ result = uuid.uuid1()
34
+ elif version == 3:
35
+ result = uuid.uuid3(namespace, name)
36
+ elif version == 5:
37
+ result = uuid.uuid5(namespace, name)
38
+ else:
39
+ result = uuid.uuid4()
40
+
41
+ uuid_str = str(result)
42
+ # uuid_hex = uuid_obj.hex
43
+ # uuid_int = uuid_obj.int
44
+ # uuid_bytes = uuid_obj.bytes
45
+ return uuid_str
46
+
47
+
48
+ def get_str_to_json(str_json):
49
+ """
50
+ 字符串类型的json格式 转 json
51
+ :param str_json: 字符串json
52
+ :return:
53
+ """
54
+ try:
55
+ new_str_json = str_json.replace("'", '"'). \
56
+ replace("None", "null").replace("True", "true"). \
57
+ replace("False", "false")
58
+ return json.loads(new_str_json)
59
+ except Exception as e:
60
+ return {}
61
+
62
+
63
+ def list_to_strtuple(datas):
64
+ """
65
+ 列表转字符串元组
66
+ :param datas: datas: [1, 2]
67
+ :return: (1, 2) 字符串类型
68
+ """
69
+ data_str = str(tuple(datas))
70
+ data_str = re.sub(",\)$", ")", data_str)
71
+ return data_str
72
+
73
+
74
+ def dumps_json(data, indent=4, sort_keys=False):
75
+ """
76
+ 将JSON数据格式化为可打印的字符串
77
+ :param data:
78
+ :param indent: 每一级嵌套都使用4个空格进行缩进
79
+ :param sort_keys: 是否排序
80
+ :return:
81
+ """
82
+ try:
83
+ if isinstance(data, str):
84
+ data = get_str_to_json(data)
85
+
86
+ data = json.dumps(
87
+ data,
88
+ ensure_ascii=False,
89
+ indent=indent,
90
+ skipkeys=True,
91
+ sort_keys=sort_keys,
92
+ default=str,
93
+ )
94
+
95
+ except Exception as e:
96
+ data = pformat(data)
97
+
98
+ return data
99
+
100
+
101
+ def get_calculate_total_page(total, limit):
102
+ """
103
+ 根据total和limit计算出一共有多少页
104
+ :param total:
105
+ :param limit:
106
+ :return:
107
+ """
108
+ if limit <= 0:
109
+ return 0
110
+ # 根据总条数和limit计算总页数
111
+ total_pages = math.ceil(total / limit)
112
+ return total_pages
113
+
114
+ def get_build_url_with_params(url, params):
115
+ """
116
+ 传入url和params拼接完整的url ->效果 https://wwww.xxxx.com/?xxx1=1&xxx2=2
117
+ :param url:
118
+ :param params:
119
+ :return:
120
+ """
121
+ encoded_params = urlencode(params)
122
+ full_url = url + "?" + encoded_params
123
+ return full_url
@@ -0,0 +1,192 @@
1
+ #!/usr/bin/env python
2
+ # -*- coding: utf-8 -*-
3
+
4
+ # 说明:
5
+ # 日志
6
+ # History:
7
+ # Date Author Version Modification
8
+ # --------------------------------------------------------------------------------------------------
9
+ # 2024/5/12 xiatn V00.01.000 新建
10
+ # --------------------------------------------------------------------------------------------------
11
+ import os
12
+ import sys
13
+ import inspect
14
+ import logging
15
+ from logging.handlers import BaseRotatingHandler
16
+ from xtn_tools_pro.utils.time_utils import get_time_timestamp_to_datestr
17
+
18
+
19
+ class RotatingFileHandler(BaseRotatingHandler):
20
+ def __init__(
21
+ self, filename, mode="a", max_bytes=0, backup_count=0, encoding=None, delay=0
22
+ ):
23
+ BaseRotatingHandler.__init__(self, filename, mode, encoding, delay)
24
+ self.max_bytes = max_bytes
25
+ self.backup_count = backup_count
26
+ self.placeholder = str(len(str(backup_count)))
27
+
28
+ def doRollover(self):
29
+ if self.stream:
30
+ self.stream.close()
31
+ self.stream = None
32
+ if self.backup_count > 0:
33
+ for i in range(self.backup_count - 1, 0, -1):
34
+ sfn = ("%0" + self.placeholder + "d.") % i # '%2d.'%i -> 02
35
+ sfn = sfn.join(self.baseFilename.split("."))
36
+ # sfn = "%d_%s" % (i, self.baseFilename)
37
+ # dfn = "%d_%s" % (i + 1, self.baseFilename)
38
+ dfn = ("%0" + self.placeholder + "d.") % (i + 1)
39
+ dfn = dfn.join(self.baseFilename.split("."))
40
+ if os.path.exists(sfn):
41
+ # print "%s -> %s" % (sfn, dfn)
42
+ if os.path.exists(dfn):
43
+ os.remove(dfn)
44
+ os.rename(sfn, dfn)
45
+ dfn = (("%0" + self.placeholder + "d.") % 1).join(
46
+ self.baseFilename.split(".")
47
+ )
48
+ if os.path.exists(dfn):
49
+ os.remove(dfn)
50
+ # Issue 18940: A file may not have been created if delay is True.
51
+ if os.path.exists(self.baseFilename):
52
+ os.rename(self.baseFilename, dfn)
53
+ if not self.delay:
54
+ self.stream = self._open()
55
+
56
+ def shouldRollover(self, record):
57
+
58
+ if self.stream is None: # delay was set...
59
+ self.stream = self._open()
60
+ if self.max_bytes > 0: # are we rolling over?
61
+ msg = "%s\n" % self.format(record)
62
+ self.stream.seek(0, 2) # due to non-posix-compliant Windows feature
63
+ if self.stream.tell() + len(msg) >= self.max_bytes:
64
+ return 1
65
+ return 0
66
+
67
+
68
+ class BoldFormatter(logging.Formatter):
69
+ def format(self, record):
70
+ result = super().format(record)
71
+ return "\033[1m" + result + "\033[0m"
72
+
73
+
74
+ class Log:
75
+ def __init__(self, name, path=None, log_level='DEBUG',
76
+ is_write_to_console=True,
77
+ is_write_to_file=False,
78
+ color=True,
79
+ mode='a',
80
+ max_bytes=0, backup_count=0, encoding=None):
81
+ """
82
+ :param name: log名
83
+ :param path: log文件存储路径 如 D://xxx.log
84
+ :param log_level: log等级 CRITICAL/ERROR/WARNING/INFO/DEBUG
85
+ :param is_write_to_console: 是否输出到控制台
86
+ :param is_write_to_file: 是否写入到文件 默认否
87
+ :param color: 是否有颜色
88
+ :param mode: 写文件模式
89
+ :param max_bytes: 每个日志文件的最大字节数
90
+ :param backup_count: 日志文件保留数量
91
+ :param encoding: 日志文件编码
92
+
93
+ """
94
+ # 创建logger对象
95
+ self.logger = logging.getLogger(name)
96
+ # 设置日志等级
97
+ self.logger.setLevel(log_level.upper())
98
+
99
+ # 创建日志格式化器
100
+ # formatter = logging.Formatter('[%(now_datestr)s] [%(levelname)s] [%(func_name)s] - %(message)s') # 原
101
+ # formatter = logging.Formatter('\033[1m%(now_datestr)s] [%(levelname)s] [%(func_name)s] - %(message)s\033[0m') #加粗
102
+ formatter = logging.Formatter(
103
+ '\033[1m[%(now_datestr)s] | %(levelname)-8s | [%(func_name)s] - %(message)s\033[0m') # 加粗对齐
104
+
105
+ # formatter = BoldFormatter('[%(now_datestr)s] [%(levelname)s] [%(func_name)s] - %(message)s') # 加粗
106
+
107
+ # 判断是否要输出到控制台
108
+ if is_write_to_console:
109
+ # 创建控制台处理器
110
+ console_handler = logging.StreamHandler(sys.stdout)
111
+ # 设置控制台处理器的格式化器
112
+ console_handler.setFormatter(formatter)
113
+ # 将控制台处理器添加到logger中
114
+ self.logger.addHandler(console_handler)
115
+
116
+ # 判断是否要写入文件
117
+ if is_write_to_file:
118
+ # 创建文件处理器
119
+ file_handler = RotatingFileHandler(path, mode=mode, max_bytes=max_bytes,
120
+ backup_count=backup_count, encoding=encoding)
121
+ # 设置文件处理器的格式化器
122
+ file_handler.setFormatter(formatter)
123
+ # 将文件处理器添加到logger中
124
+ self.logger.addHandler(file_handler)
125
+
126
+ # 判断是否要带颜色
127
+ if color:
128
+ try:
129
+ from colorlog import ColoredFormatter
130
+ # 创建带颜色的日志格式化器
131
+ # color_formatter = ColoredFormatter('%(log_color)s[%(now_datestr)s] [%(levelname)s] [%(func_name)s] - %(message)s') # 原
132
+ # color_formatter = ColoredFormatter('\033[1m%(log_color)s[%(now_datestr)s] [%(levelname)s] [%(func_name)s] - %(message)s\033[0m') # 加粗
133
+ # 创建颜色映射
134
+ log_colors = {
135
+ 'DEBUG': 'bold_blue',
136
+ 'INFO': 'bold_cyan',
137
+ 'WARNING': 'bold_yellow',
138
+ 'ERROR': 'bold_red',
139
+ 'CRITICAL': 'bold_red',
140
+ }
141
+ color_formatter = ColoredFormatter(
142
+ '\033[1m%(log_color)s[%(now_datestr)s] | %(levelname)-8s | [%(func_name)s] - %(message)s\033[0m',
143
+ log_colors=log_colors) # 加粗对齐
144
+ # 设置控制台处理器的格式化器为带颜色的格式化器
145
+ console_handler.setFormatter(color_formatter)
146
+ except ImportError:
147
+ pass
148
+
149
+ def debug(self, message):
150
+ # 记录DEBUG级别的日志
151
+ self.logger.debug(message, extra=self._get_caller_name_extra())
152
+
153
+ def info(self, message):
154
+ # 记录INFO级别的日志
155
+ self.logger.info(message, extra=self._get_caller_name_extra())
156
+
157
+ def warning(self, message):
158
+ # 记录WARNING级别的日志
159
+ self.logger.warning(message, extra=self._get_caller_name_extra())
160
+
161
+ def error(self, message):
162
+ # 记录ERROR级别的日志
163
+ self.logger.error(message, extra=self._get_caller_name_extra())
164
+
165
+ def critical(self, message):
166
+ # 记录CRITICAL级别的日志
167
+ self.logger.critical(message, extra=self._get_caller_name_extra())
168
+
169
+ def _get_caller_name_extra(self):
170
+ """
171
+ 获取调用日志函数的函数名称
172
+ """
173
+ # 获取当前栈帧
174
+ frame = inspect.currentframe()
175
+ # 获取调用者的栈帧
176
+ caller_frame = frame.f_back.f_back
177
+ # 从栈帧中获取代码对象
178
+ code_obj = caller_frame.f_code
179
+ # 获取调用者的名字
180
+ caller_name = code_obj.co_name
181
+ return {"func_name": caller_name,
182
+ "now_datestr": get_time_timestamp_to_datestr()}
183
+
184
+
185
+ if __name__ == '__main__':
186
+ pass
187
+ logger = Log('mylogger', './xxx.log', log_level='DEBUG', is_write_to_console=True, is_write_to_file=True,
188
+ color=True, mode='a', max_bytes=1024, backup_count=3)
189
+ logger.debug("debug message")
190
+ logger.info("info level message")
191
+ logger.warning("warning level message")
192
+ logger.critical("critical level message")
@@ -0,0 +1,57 @@
1
+ #!/usr/bin/env python
2
+ # -*- coding: utf-8 -*-
3
+
4
+ # 说明:
5
+ # 重试
6
+ # History:
7
+ # Date Author Version Modification
8
+ # --------------------------------------------------------------------------------------------------
9
+ # 2024/5/12 xiatn V00.01.000 新建
10
+ # --------------------------------------------------------------------------------------------------
11
+ import time
12
+ from xtn_tools_pro.utils.log import Log
13
+
14
+ log = Log(name="retry", color=True)
15
+
16
+
17
+ def retry(max_attempts=3, delay=0, exception_callfunc=None, *args_callfunc, **kwargs_callfunc):
18
+ """
19
+ 重试
20
+ :param max_attempts: 最多重试次数
21
+ :param delay: 每次重试间隔时间
22
+ :param exception_callfunc: 失败的回调函数
23
+ :return:
24
+ """
25
+
26
+ def decorator(func):
27
+ def wrapper(*args, **kwargs):
28
+ attempts = 0
29
+ while attempts < max_attempts:
30
+ try:
31
+ return func(*args, **kwargs)
32
+ except Exception as e:
33
+ log.debug(f"重试第 {attempts + 1} 次,failed: {e}")
34
+ if exception_callfunc:
35
+ exception_callfunc(*args_callfunc, **kwargs_callfunc)
36
+ attempts += 1
37
+ time.sleep(delay)
38
+
39
+ return wrapper
40
+
41
+ return decorator
42
+
43
+
44
+ if __name__ == '__main__':
45
+
46
+ def test1(*args, **kwargs):
47
+ print("test1", args, kwargs)
48
+
49
+
50
+ @retry(3, 5)
51
+ def test(a, b):
52
+ import random
53
+ if random.random() < 0.5:
54
+ raise ValueError("Random value too small")
55
+ print("Success!")
56
+
57
+ test(1, 1)
@@ -0,0 +1,159 @@
1
+ #!/usr/bin/env python
2
+ # -*- coding: utf-8 -*-
3
+
4
+ # 说明:
5
+ # sql相关
6
+ # History:
7
+ # Date Author Version Modification
8
+ # --------------------------------------------------------------------------------------------------
9
+ # 2024/5/12 xiatn V00.01.000 新建
10
+ # --------------------------------------------------------------------------------------------------
11
+ import datetime
12
+ from xtn_tools_pro.utils.helpers import list_to_strtuple, dumps_json
13
+
14
+
15
+ def format_sql_value(value):
16
+ if isinstance(value, str):
17
+ value = value.strip()
18
+
19
+ elif isinstance(value, (list, dict)):
20
+ value = dumps_json(value, indent=None)
21
+
22
+ elif isinstance(value, (datetime.date, datetime.time)):
23
+ value = str(value)
24
+
25
+ elif isinstance(value, bool):
26
+ value = int(value)
27
+
28
+ return value
29
+
30
+
31
+ def get_insert_sql(table, data, auto_update=False, update_columns=(), insert_ignore=False):
32
+ """
33
+ 生成 insert sql
34
+ :param table: 表
35
+ :param data: 表数据 json格式
36
+ :param auto_update: 使用的是replace into, 为完全覆盖已存在的数据
37
+ :param update_columns: 需要更新的列 默认全部,当指定值时,auto_update设置无效,当duplicate key冲突时更新指定的列
38
+ :param insert_ignore: 数据存在忽略,True则会忽略该插入操作,不会产生冲突错误
39
+ :return:
40
+ """
41
+ keys = ["`{}`".format(key) for key in data.keys()]
42
+ keys = list_to_strtuple(keys).replace("'", "")
43
+ values = [format_sql_value(value) for value in data.values()]
44
+ values = list_to_strtuple(values)
45
+ if update_columns:
46
+ if not isinstance(update_columns, (tuple, list)):
47
+ update_columns = [update_columns]
48
+ update_columns_ = ", ".join(
49
+ ["{key}=values({key})".format(key=key) for key in update_columns]
50
+ )
51
+ sql = (
52
+ "insert%s into `{table}` {keys} values {values} on duplicate key update %s"
53
+ % (" ignore" if insert_ignore else "", update_columns_)
54
+ )
55
+
56
+ elif auto_update:
57
+ sql = "replace into `{table}` {keys} values {values}"
58
+ else:
59
+ sql = "insert%s into `{table}` {keys} values {values}" % (
60
+ " ignore" if insert_ignore else ""
61
+ )
62
+
63
+ sql = sql.format(table=table, keys=keys, values=values).replace("None", "null")
64
+ return sql
65
+
66
+ def get_insert_batch_sql(table, datas, auto_update=False, update_columns=(), update_columns_value=()):
67
+ """
68
+ 生成 批量 insert sql
69
+ :param table: 表
70
+ :param datas: 表数据 [{...}]
71
+ :param auto_update: 使用的是replace into, 为完全覆盖已存在的数据
72
+ :param update_columns: 需要更新的列 默认全部,当指定值时,auto_update设置无效,当duplicate key冲突时更新指定的列
73
+ :param update_columns_value: 需要更新的列的值 默认为datas里边对应的值, 注意 如果值为字符串类型 需要主动加单引号, 如 update_columns_value=("'test'",)
74
+ :return:
75
+ """
76
+ if not datas:
77
+ return
78
+ keys = list(set([key for data in datas for key in data]))
79
+ values_placeholder = ["%s"] * len(keys)
80
+
81
+ values = []
82
+ for data in datas:
83
+ value = []
84
+ for key in keys:
85
+ current_data = data.get(key)
86
+ current_data = format_sql_value(current_data)
87
+
88
+ value.append(current_data)
89
+
90
+ values.append(value)
91
+
92
+ keys = ["`{}`".format(key) for key in keys]
93
+ keys = list_to_strtuple(keys).replace("'", "")
94
+
95
+ values_placeholder = list_to_strtuple(values_placeholder).replace("'", "")
96
+
97
+ if update_columns:
98
+ if not isinstance(update_columns, (tuple, list)):
99
+ update_columns = [update_columns]
100
+ if update_columns_value:
101
+ update_columns_ = ", ".join(
102
+ [
103
+ "`{key}`={value}".format(key=key, value=value)
104
+ for key, value in zip(update_columns, update_columns_value)
105
+ ]
106
+ )
107
+ else:
108
+ update_columns_ = ", ".join(
109
+ ["`{key}`=values(`{key}`)".format(key=key) for key in update_columns]
110
+ )
111
+ sql = "insert into `{table}` {keys} values {values_placeholder} on duplicate key update {update_columns}".format(
112
+ table=table,
113
+ keys=keys,
114
+ values_placeholder=values_placeholder,
115
+ update_columns=update_columns_,
116
+ )
117
+ elif auto_update:
118
+ sql = "replace into `{table}` {keys} values {values_placeholder}".format(
119
+ table=table, keys=keys, values_placeholder=values_placeholder
120
+ )
121
+ else:
122
+ sql = "insert ignore into `{table}` {keys} values {values_placeholder}".format(
123
+ table=table, keys=keys, values_placeholder=values_placeholder
124
+ )
125
+
126
+ return sql, values
127
+
128
+ def get_update_sql(table, data, condition):
129
+ """
130
+ 生成更新sql
131
+ :param table: 表
132
+ :param data: 表数据 json格式
133
+ :param condition: where 条件
134
+ :return:
135
+ """
136
+ key_values = []
137
+
138
+ for key, value in data.items():
139
+ value = format_sql_value(value)
140
+ if isinstance(value, str):
141
+ key_values.append("`{}`={}".format(key, repr(value)))
142
+ elif value is None:
143
+ key_values.append("`{}`={}".format(key, "null"))
144
+ else:
145
+ key_values.append("`{}`={}".format(key, value))
146
+
147
+ key_values = ", ".join(key_values)
148
+
149
+ sql = "update `{table}` set {key_values} where {condition}"
150
+ sql = sql.format(table=table, key_values=key_values, condition=condition)
151
+ return sql
152
+
153
+ if __name__ == '__main__':
154
+ print(get_insert_sql("user_copy1", {"id": 5, "nickname": "1212", "email": "121212", "auth": 2},insert_ignore=True))
155
+ print(get_insert_batch_sql("user_copy1", [{"id": 5, "nickname": "555", "email": "555", "auth": 1},
156
+ {"id": 6, "nickname": "666", "email": "666", "auth": 2},
157
+ {"id": 7, "nickname": "777", "email": "777", "auth": 1}],
158
+ ))
159
+ print(get_update_sql("user_copy1",{"email":"123","status":4},"id=2"))
@@ -0,0 +1,143 @@
1
+ #!/usr/bin/env python
2
+ # -*- coding: utf-8 -*-
3
+
4
+ # 说明:
5
+ # 时间
6
+ # History:
7
+ # Date Author Version Modification
8
+ # --------------------------------------------------------------------------------------------------
9
+ # 2024/5/13 xiatn V00.01.000 新建
10
+ # --------------------------------------------------------------------------------------------------
11
+ import time
12
+ import datetime
13
+
14
+
15
+ def get_time_now_timestamp(is_time_10=False, is_time_13=False):
16
+ """
17
+ 获取当前时间戳
18
+ :param is_time_10: 是否需要处理为10位的时间戳,默认不处理
19
+ :param is_time_13: 是否需要处理为13位的时间戳,默认不处理
20
+ :return:
21
+ """
22
+
23
+ if is_time_10:
24
+ val = int(time.time())
25
+ elif is_time_13:
26
+ val = int(time.time() * 1000)
27
+ else:
28
+ val = time.time()
29
+ return val
30
+
31
+
32
+ def get_time_now_day0_timestamp(is_time_13=False):
33
+ """
34
+ 获取当天0点时间戳
35
+ :param is_time_13: 是否需要处理为13位的时间戳,默认不处理并且返回10位时间戳
36
+ :return:
37
+ """
38
+ val = time.mktime(datetime.date.today().timetuple())
39
+ if is_time_13:
40
+ return int(val * 1000)
41
+ else:
42
+ return int(val)
43
+
44
+
45
+ def get_time_now_day59_timestamp(is_time_13=False):
46
+ """
47
+ 获取当天23:59:59点时间戳
48
+ :param is_time_13: 是否需要处理为13位的时间戳,默认不处理并且返回10位时间戳
49
+ :return:
50
+ """
51
+ # 获取当前日期时间
52
+ now = datetime.datetime.now()
53
+ # 设置小时、分钟、秒为 23:59:59
54
+ last_second = now.replace(hour=23, minute=59, second=59)
55
+ # 转换为时间戳
56
+ timestamp = time.mktime(last_second.timetuple())
57
+ # 转换为整数类型
58
+ if is_time_13:
59
+ return get_time_10_to_13_timestamp(timestamp)
60
+ else:
61
+ return int(timestamp)
62
+
63
+
64
+ def get_time_x_day_timestamp(x, is_time_13=False):
65
+ """
66
+ 获取x天的0点的时间戳
67
+ :param x: 0:当天; 1:1天后; -1:一天前
68
+ :param is_time_13: 是否需要处理为13位的时间戳,默认不处理并且返回10位时间戳
69
+ :return:
70
+ """
71
+ if x == 0:
72
+ date_string = datetime.datetime.now().strftime("%Y-%m-%d") # 当天日期
73
+ elif x > 0:
74
+ future_date = datetime.datetime.now() + datetime.timedelta(days=x)
75
+ date_string = future_date.strftime("%Y-%m-%d") # x天后的日期
76
+ else:
77
+ past_date = datetime.datetime.now() - datetime.timedelta(days=abs(x))
78
+ date_string = past_date.strftime("%Y-%m-%d") # x天前的日期
79
+
80
+ timestamp = get_time_datestr_to_timestamp(date_string=date_string, is_time_13=is_time_13)
81
+ return timestamp
82
+
83
+
84
+ def get_time_datestr_to_timestamp(date_string, date_format="%Y-%m-%d", is_time_13=False):
85
+ """
86
+ 根据日期格式转换为时间戳,date_string和date_format需要配合,自行传参修改,这里是以%Y-%m-%d为格式也就是2024-04-18
87
+ :param date_string: 字符串类型的日期格式 例如:2024-04-18
88
+ :param date_format: 时间格式
89
+ :param is_time_13: 是否需要处理为13位的时间戳,默认不处理并且返回10位时间戳
90
+ :return:
91
+ """
92
+ date_obj = datetime.datetime.strptime(date_string, date_format)
93
+ timestamp = date_obj.timestamp()
94
+ if is_time_13:
95
+ return get_time_10_to_13_timestamp(timestamp)
96
+ else:
97
+ return int(timestamp)
98
+
99
+
100
+ def get_time_10_to_13_timestamp(timestamp):
101
+ """
102
+ 10位时间戳转13位时间戳
103
+ :param timestamp:
104
+ :return:
105
+ """
106
+ val = int(timestamp)
107
+ if len(str(val)) == 10:
108
+ return int(val * 1000)
109
+ return val
110
+
111
+
112
+ def get_time_13_to_10_timestamp(timestamp):
113
+ """
114
+ 13位时间戳转10位时间戳
115
+ :param timestamp:
116
+ :return:
117
+ """
118
+ val = int(timestamp)
119
+ if len(str(val)) == 13:
120
+ return int(val // 1000)
121
+ return val
122
+
123
+
124
+ def get_time_timestamp_to_datestr(format='%Y-%m-%d %H:%M:%S', now_time=0):
125
+ """
126
+ 根据时间戳转换为日期格式,兼容10位时间戳和13位时间戳
127
+ :param format: 日期格式,常用:%Y-%m-%d %H:%M:%S、%Y-%m-%d、%Y/%m/%d、%H:%M:%S ...
128
+ :param now_time: 时间戳,默认0表示当前时间戳
129
+ :return:
130
+ """
131
+ # 根据格式获取当前转换好的时间
132
+ if not now_time:
133
+ now_time = get_time_now_timestamp()
134
+ now_time = get_time_13_to_10_timestamp(now_time)
135
+ val = time.strftime(format, time.localtime(now_time))
136
+ return val
137
+
138
+
139
+ if __name__ == '__main__':
140
+ pass
141
+ print(get_time_timestamp_to_datestr())
142
+ print(get_time_timestamp_to_datestr(format="%H:%M:%S", now_time=get_time_now_timestamp(is_time_10=True)))
143
+ print(get_time_timestamp_to_datestr(now_time=get_time_now_timestamp(is_time_13=True)))
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: xtn-tools-pro
3
- Version: 1.0.0.0.4
3
+ Version: 1.0.0.0.6
4
4
  Summary: xtn 开发工具
5
5
  Author: xtn
6
6
  Author-email: czw011122@163.com
@@ -10,6 +10,9 @@ Description-Content-Type: text/markdown
10
10
  License-File: LICENSE
11
11
  Requires-Dist: pymongo
12
12
  Requires-Dist: redis
13
+ Requires-Dist: pymysql
14
+ Requires-Dist: dbutils
15
+ Requires-Dist: colorlog
13
16
  Requires-Dist: requests
14
17
 
15
18
  xtnkk-tools