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

Sign up to get free protection for your applications and to get access to all the features.
@@ -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