build
This commit is contained in:
parent
d9d3033ac3
commit
e1cd3be739
|
@ -2,5 +2,8 @@
|
||||||
"repo_url": "http://192.168.0.200:3000/Faxing/Lawnchair.git",
|
"repo_url": "http://192.168.0.200:3000/Faxing/Lawnchair.git",
|
||||||
"repo_branch": "touka-dev",
|
"repo_branch": "touka-dev",
|
||||||
"repo_commit": "",
|
"repo_commit": "",
|
||||||
"package_name": "com.shape.shift.run.launcher.free.game.xjrtg"
|
"package_name": "com.punch.prankster.puzzle.fwaes.free.launcher.fgsaw",
|
||||||
|
"game_type": "unity_native",
|
||||||
|
"version_display_name": "1.1.9",
|
||||||
|
"version_code": 19
|
||||||
}
|
}
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -9,6 +9,8 @@ class Context:
|
||||||
repo_commit: str = ""
|
repo_commit: str = ""
|
||||||
package_name: str = ""
|
package_name: str = ""
|
||||||
|
|
||||||
|
game_type: str = ""
|
||||||
|
|
||||||
project_original_path: str = "project/original"
|
project_original_path: str = "project/original"
|
||||||
|
|
||||||
temp_project_path: str = ""
|
temp_project_path: str = ""
|
||||||
|
@ -16,7 +18,25 @@ class Context:
|
||||||
local_repo_branch: str = ""
|
local_repo_branch: str = ""
|
||||||
local_repo_commit: str = ""
|
local_repo_commit: str = ""
|
||||||
|
|
||||||
|
admob_app_id: str = ""
|
||||||
|
game_services_project_id: str = ""
|
||||||
|
facebook_app_id: str = ""
|
||||||
|
facebook_client_token: str = ""
|
||||||
|
|
||||||
|
version_display_name: str = "1"
|
||||||
|
version_code: int = 1
|
||||||
|
|
||||||
|
config: any = None
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_json(cls, json_str: str):
|
def from_json(cls, json_str: str):
|
||||||
data = json.loads(json_str)
|
data = json.loads(json_str)
|
||||||
return cls(**data)
|
return cls(**data)
|
||||||
|
|
||||||
|
def get_config(self, key: str, default_value: str = '') -> str:
|
||||||
|
if self.config is None:
|
||||||
|
return default_value
|
||||||
|
return self.config.get(key, default_value).replace(" ", " ")
|
||||||
|
|
||||||
|
def get_app_name(self):
|
||||||
|
return self.get_config("app_name")
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
from scripts.task import Task
|
from scripts.task import Task
|
||||||
from utils import FileUtils
|
from utils import FileUtils, TimeUtils
|
||||||
from utils.logger_utils import app_logger
|
from utils.logger_utils import app_logger
|
||||||
|
|
||||||
|
|
||||||
|
@ -14,6 +14,8 @@ class ProjectCopy(Task):
|
||||||
def init(self):
|
def init(self):
|
||||||
self.context.temp_project_path = self.context.project_original_path.replace("original",
|
self.context.temp_project_path = self.context.project_original_path.replace("original",
|
||||||
self.context.package_name.replace(
|
self.context.package_name.replace(
|
||||||
".", "_"))
|
".", "_") +
|
||||||
|
"_" + self.context.local_repo_commit +
|
||||||
|
"_" + TimeUtils.get_current_time_str())
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -1,6 +1,291 @@
|
||||||
|
import os.path
|
||||||
|
from pathlib import Path
|
||||||
|
import re
|
||||||
|
|
||||||
|
import javaproperties
|
||||||
|
|
||||||
|
from scripts.context import Context
|
||||||
from scripts.task import Task
|
from scripts.task import Task
|
||||||
|
from utils import FileUtils
|
||||||
|
from utils.logger_utils import app_logger
|
||||||
|
|
||||||
|
|
||||||
|
def uncomment_line(content, line_pattern):
|
||||||
|
"""
|
||||||
|
取消指定行的注释
|
||||||
|
|
||||||
|
:param content: 文件内容
|
||||||
|
:param line_pattern: 要取消注释的行内容(不含前导//和空格)
|
||||||
|
:return: 更新后的内容
|
||||||
|
"""
|
||||||
|
# 匹配以//开头,后跟任意空格,然后是目标行内容
|
||||||
|
pattern = rf'^(\s*)//\s*({re.escape(line_pattern)}\s*)$'
|
||||||
|
|
||||||
|
# 替换为去注释版本(保留原有缩进)
|
||||||
|
replacement = rf'\1\2'
|
||||||
|
|
||||||
|
updated_content = re.sub(pattern, replacement, content, flags=re.MULTILINE)
|
||||||
|
return updated_content
|
||||||
|
|
||||||
|
|
||||||
|
def update_gradle_variable(content, variable_name, new_value):
|
||||||
|
"""
|
||||||
|
更新 Gradle 文件中的 final def 变量值
|
||||||
|
|
||||||
|
:param content: Gradle 文件内容
|
||||||
|
:param variable_name: 变量名 (如 "releaseName")
|
||||||
|
:param new_value: 新值 (字符串或数字)
|
||||||
|
:return: 更新后的内容
|
||||||
|
"""
|
||||||
|
# 处理字符串值(带引号)
|
||||||
|
if isinstance(new_value, str):
|
||||||
|
# 匹配带引号的字符串赋值
|
||||||
|
pattern = rf'(final\s+def\s+{re.escape(variable_name)}\s*=\s*["\'])(.*?)(["\'])'
|
||||||
|
replacement = rf'\g<1>{new_value}\g<3>'
|
||||||
|
else:
|
||||||
|
# 匹配数字值(不带引号)
|
||||||
|
pattern = rf'(final\s+def\s+{re.escape(variable_name)}\s*=\s*)(\d+)'
|
||||||
|
replacement = rf'\g<1>{new_value}'
|
||||||
|
|
||||||
|
updated_content = re.sub(pattern, replacement, content)
|
||||||
|
return updated_content
|
||||||
|
|
||||||
|
|
||||||
|
def update_gradle_property(content, key, new_value):
|
||||||
|
# 匹配两种格式:
|
||||||
|
# 1. resValue "string", "key", "value"
|
||||||
|
# 2. resValue("string", "key", "value")
|
||||||
|
pattern = rf'(resValue\s*\(?\s*["\']string["\']\s*,\s*["\']{re.escape(key)}["\']\s*,\s*["\'])(.*?)(["\']\s*\)?)'
|
||||||
|
|
||||||
|
# 替换为新值
|
||||||
|
updated_content = re.sub(pattern, rf'\g<1>{new_value}\g<3>', content)
|
||||||
|
|
||||||
|
return updated_content
|
||||||
|
|
||||||
|
|
||||||
|
GAME_ACTIVITY_PATH = f"LauncherCode/src/com/launchercode/GameActivity.kt".replace("/", os.sep)
|
||||||
|
ANDROID_MANIFEST_PATH = f"lawnchair/AndroidManifest.xml".replace("/", os.sep)
|
||||||
|
|
||||||
|
|
||||||
class ProjectUpdate(Task):
|
class ProjectUpdate(Task):
|
||||||
def execute(self):
|
|
||||||
|
def __init__(self, context: Context):
|
||||||
|
super().__init__(context)
|
||||||
|
self.build_gradle_path = None
|
||||||
|
|
||||||
|
def update_package_name(self):
|
||||||
|
"""
|
||||||
|
更新包名
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
|
||||||
|
build_gradle_path = os.path.join(self.context.temp_project_path, "build.gradle")
|
||||||
|
text = open(build_gradle_path, "r", encoding="utf-8").read()
|
||||||
|
|
||||||
|
text = text.replace("com.fingerheart.launcher.game.free.sdjws", self.context.package_name)
|
||||||
|
open(build_gradle_path, "w", encoding="utf-8").write(text)
|
||||||
|
|
||||||
|
xml_path = os.path.join(self.context.temp_project_path, "lawnchair/res/xml")
|
||||||
|
|
||||||
|
# com.launchercode.SplashActivity
|
||||||
|
# TODO 这里还需要改启动项
|
||||||
|
for root, dirs, files in os.walk(xml_path):
|
||||||
|
for file in files:
|
||||||
|
temp_xml_path = os.path.join(root, file)
|
||||||
|
text = open(temp_xml_path, "r", encoding="utf-8").read()
|
||||||
|
text = text.replace("com.fingerheart.launcher.game.free.sdjws", self.context.package_name)
|
||||||
|
open(temp_xml_path, "w", encoding="utf-8").write(text)
|
||||||
|
pass
|
||||||
|
pass
|
||||||
|
|
||||||
|
def update_keystore(self):
|
||||||
|
root_dir = os.path.join("game_config", self.context.package_name)
|
||||||
|
for file in os.listdir(root_dir):
|
||||||
|
if file.endswith(".keystore"):
|
||||||
|
name = file.replace(".keystore", "")
|
||||||
|
FileUtils.copy(os.path.join(root_dir, file), os.path.join(self.context.temp_project_path, file))
|
||||||
|
|
||||||
|
open(os.path.join(self.context.temp_project_path, "keystore.properties"), "w", encoding="utf-8").write(
|
||||||
|
f"""
|
||||||
|
keyAlias={name}
|
||||||
|
keyPassword=123456
|
||||||
|
storeFile=./{name}.keystore
|
||||||
|
storePassword=123456
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
raise Exception("keystore not found")
|
||||||
|
|
||||||
|
def update_config(self):
|
||||||
|
"""
|
||||||
|
更新配置文件
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
root_dir = os.path.join("game_config", self.context.package_name)
|
||||||
|
config_path = list(
|
||||||
|
filter(lambda f: f.endswith(".zip") and f.startswith(self.context.package_name), os.listdir(root_dir)))
|
||||||
|
if len(config_path) <= 0:
|
||||||
|
raise Exception("config not found")
|
||||||
|
|
||||||
|
target_path = os.path.join(root_dir, config_path[0])
|
||||||
|
|
||||||
|
dst = os.path.join(self.context.temp_project_path, config_path[0].replace(".zip", ""))
|
||||||
|
|
||||||
|
result = FileUtils.decompress(target_path, dst)
|
||||||
|
app_logger().debug(f"{target_path} -> {dst} , 解压结果: {result}")
|
||||||
|
|
||||||
|
mainly_path = os.path.join(dst, "mainly")
|
||||||
|
|
||||||
|
google_services_json_path = os.path.join(dst, "google-services.json")
|
||||||
|
|
||||||
|
FileUtils.copy(google_services_json_path,
|
||||||
|
os.path.join(self.context.temp_project_path, "google-services.json"),
|
||||||
|
True)
|
||||||
|
|
||||||
|
dst_path = os.path.join(self.context.temp_project_path, f"lawnchair{os.sep}assets")
|
||||||
|
|
||||||
|
for file in list(filter(lambda f: f != "google_fonts.json", os.listdir(dst_path))):
|
||||||
|
FileUtils.delete(os.path.join(dst_path, file), True)
|
||||||
|
pass
|
||||||
|
|
||||||
|
for file in list(filter(lambda f: f.find(".") <= 0, os.listdir(mainly_path))):
|
||||||
|
FileUtils.copy(os.path.join(mainly_path, file), os.path.join(dst_path, file))
|
||||||
|
|
||||||
|
with open(os.path.join(mainly_path, "tkg_config_mainly.properties"), 'rb') as f:
|
||||||
|
self.context.config = javaproperties.load(f)
|
||||||
|
|
||||||
|
if self.context.admob_app_id is None or self.context.admob_app_id == "":
|
||||||
|
self.context.admob_app_id = self.context.get_config("admob_id")
|
||||||
|
pass
|
||||||
|
|
||||||
|
def update_icon(self):
|
||||||
|
"""
|
||||||
|
更新游戏Icon
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
|
||||||
|
target_icon_path = os.path.join("game_config", self.context.package_name, "icon.zip")
|
||||||
|
tag = "res_icon_resources"
|
||||||
|
dst = os.path.join(self.context.temp_project_path, tag)
|
||||||
|
FileUtils.decompress(target_icon_path, dst)
|
||||||
|
|
||||||
|
for root, dirs, files in os.walk(dst):
|
||||||
|
for file in files:
|
||||||
|
temp_tart_path = os.path.join(root, file)
|
||||||
|
if temp_tart_path.find("__MACOSX") > 0:
|
||||||
|
continue
|
||||||
|
temp_dst = temp_tart_path.replace(tag, "res")
|
||||||
|
app_logger().debug(f"copy icon = {temp_tart_path} -> {temp_dst}")
|
||||||
|
FileUtils.copy(temp_tart_path, temp_dst, True)
|
||||||
|
pass
|
||||||
|
|
||||||
|
def update_game_result(self):
|
||||||
|
"""
|
||||||
|
更新游戏资源
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
root_dir = os.path.join("game_config", self.context.package_name)
|
||||||
|
|
||||||
|
if self.context.game_type == "unity_native":
|
||||||
|
res_path = os.path.join(root_dir, "unityLibrary.zip")
|
||||||
|
if not os.path.exists(res_path):
|
||||||
|
raise Exception("unity library not found")
|
||||||
|
dst = os.path.join(self.context.temp_project_path, "unityLibrary")
|
||||||
|
temp_dst = dst + "_res"
|
||||||
|
if os.path.exists(dst):
|
||||||
|
FileUtils.delete(dst, True)
|
||||||
|
FileUtils.decompress(res_path, temp_dst)
|
||||||
|
|
||||||
|
if os.listdir(temp_dst).index("unityLibrary") >= 0:
|
||||||
|
FileUtils.copy(os.path.join(temp_dst, "unityLibrary"), dst)
|
||||||
|
else:
|
||||||
|
FileUtils.copy(temp_dst, dst)
|
||||||
|
|
||||||
|
text = open(os.path.join(dst, "build.gradle"), "r", encoding="utf-8").read()
|
||||||
|
text = text.replace("implementation", "api")
|
||||||
|
open(os.path.join(dst, "build.gradle"), "w", encoding="utf-8").write(text)
|
||||||
|
|
||||||
|
# 引用Unity项目
|
||||||
|
text = open(self.build_gradle_path, "r", encoding="utf-8").read()
|
||||||
|
text = uncomment_line(text, "implementation projects.unityLibrary")
|
||||||
|
open(self.build_gradle_path, "w", encoding="utf-8").write(text)
|
||||||
|
|
||||||
|
# launcher 引用 unityActivity
|
||||||
|
|
||||||
|
text = open(os.path.join(self.context.temp_project_path, GAME_ACTIVITY_PATH), "r", encoding="utf-8").read()
|
||||||
|
text = text.replace("WebActivity", "com.unity3d.player.UnityPlayerActivity")
|
||||||
|
open(os.path.join(self.context.temp_project_path, GAME_ACTIVITY_PATH), "w", encoding="utf-8").write(text)
|
||||||
|
|
||||||
|
text = open(os.path.join(self.context.temp_project_path, ANDROID_MANIFEST_PATH), "r", encoding="utf-8").read()
|
||||||
|
# text = text.replace("WebActivity", "com.unity3d.player.UnityPlayerActivity")
|
||||||
|
open(os.path.join(self.context.temp_project_path, ANDROID_MANIFEST_PATH), "w", encoding="utf-8").write(text)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
else:
|
||||||
|
raise Exception(f"不支持的游戏类型 : {self.context.game_type}")
|
||||||
|
pass
|
||||||
|
|
||||||
|
def update_image(self):
|
||||||
|
"""
|
||||||
|
更新游戏的资源
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
root_dir = os.path.join("game_config", self.context.package_name)
|
||||||
|
drawable_path = os.path.join(root_dir, "drawable-xxhdpi.zip")
|
||||||
|
if not os.path.exists(drawable_path):
|
||||||
|
raise Exception("drawable not found")
|
||||||
|
dst = os.path.join(self.context.temp_project_path, "drawable_res")
|
||||||
|
FileUtils.decompress(drawable_path, dst)
|
||||||
|
|
||||||
|
if os.path.join(dst, "drawable-xxhdpi"):
|
||||||
|
dst = os.path.join(dst, "drawable-xxhdpi")
|
||||||
|
|
||||||
|
target_root_path = os.path.join(self.context.temp_project_path,
|
||||||
|
f"LauncherCode{os.sep}res{os.sep}drawable-xxhdpi")
|
||||||
|
|
||||||
|
image_list = list(map(lambda f: Path(f).stem, os.listdir(target_root_path)))
|
||||||
|
|
||||||
|
for file in os.listdir(dst):
|
||||||
|
temp_tar = os.path.join(dst, file)
|
||||||
|
temp_dst = os.path.join(target_root_path, file)
|
||||||
|
file_name = Path(file).stem
|
||||||
|
if file_name in image_list:
|
||||||
|
FileUtils.delete(os.path.join(target_root_path, file_name + ".png"))
|
||||||
|
FileUtils.delete(os.path.join(target_root_path, file_name + ".jpg"))
|
||||||
|
pass
|
||||||
|
FileUtils.copy(temp_tar, temp_dst, True)
|
||||||
|
pass
|
||||||
|
|
||||||
|
def update_gradle_config(self):
|
||||||
|
"""
|
||||||
|
更新gradle里面的版本号
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
|
||||||
|
build_gradle_path = os.path.join(self.context.temp_project_path, "build.gradle")
|
||||||
|
|
||||||
|
text = open(build_gradle_path, "r", encoding="UTF-8").read()
|
||||||
|
|
||||||
|
text = update_gradle_property(text, "admob_app_id", self.context.admob_app_id)
|
||||||
|
text = update_gradle_property(text, "game_services_project_id", self.context.game_services_project_id)
|
||||||
|
text = update_gradle_property(text, "facebook_app_id", self.context.facebook_app_id)
|
||||||
|
text = update_gradle_property(text, "facebook_client_token", self.context.facebook_client_token)
|
||||||
|
text = update_gradle_property(text, "derived_app_name", self.context.get_app_name())
|
||||||
|
text = update_gradle_variable(text, "versionDisplayName", self.context.version_display_name)
|
||||||
|
text = update_gradle_variable(text, "version_code", self.context.version_code)
|
||||||
|
# text = text.
|
||||||
|
open(build_gradle_path, "w", encoding="UTF-8").write(text)
|
||||||
|
pass
|
||||||
|
|
||||||
|
def execute(self):
|
||||||
|
self.build_gradle_path = os.path.join(self.context.temp_project_path, "build.gradle")
|
||||||
|
self.update_package_name()
|
||||||
|
self.update_keystore()
|
||||||
|
self.update_config()
|
||||||
|
self.update_icon()
|
||||||
|
self.update_image()
|
||||||
|
self.update_game_result()
|
||||||
|
self.update_gradle_config()
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
from .system_utils import SystemUtils
|
from .system_utils import SystemUtils
|
||||||
from .command_utils import CommandUtils
|
from .command_utils import CommandUtils
|
||||||
from .file_utils import FileUtils
|
from .file_utils import FileUtils
|
||||||
|
from .time_utils import TimeUtils
|
||||||
|
|
||||||
__all__ = ['SystemUtils', 'CommandUtils', "FileUtils"]
|
__all__ = ['SystemUtils', 'CommandUtils', "FileUtils", "TimeUtils"]
|
||||||
|
|
|
@ -0,0 +1,113 @@
|
||||||
|
import time
|
||||||
|
import datetime
|
||||||
|
from enum import Enum
|
||||||
|
|
||||||
|
|
||||||
|
class TimeUtils:
|
||||||
|
"""
|
||||||
|
时间工具类
|
||||||
|
功能:
|
||||||
|
1. 获取当前时间的各种格式化输出
|
||||||
|
2. 时间转换
|
||||||
|
3. 时间计算
|
||||||
|
"""
|
||||||
|
|
||||||
|
class Weekday(Enum):
|
||||||
|
MONDAY = "星期一"
|
||||||
|
TUESDAY = "星期二"
|
||||||
|
WEDNESDAY = "星期三"
|
||||||
|
THURSDAY = "星期四"
|
||||||
|
FRIDAY = "星期五"
|
||||||
|
SATURDAY = "星期六"
|
||||||
|
SUNDAY = "星期日"
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_current_time():
|
||||||
|
"""
|
||||||
|
获取当前时间,格式:年-月-日-时-分
|
||||||
|
返回:str,例如:2023-11-15-14-30
|
||||||
|
"""
|
||||||
|
now = datetime.datetime.now()
|
||||||
|
return now.strftime("%Y-%m-%d-%H-%M")
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_current_time_str():
|
||||||
|
"""
|
||||||
|
获取当前时间,格式:年-月-日-时-分
|
||||||
|
返回:str,例如:2023-11-15-14-30
|
||||||
|
"""
|
||||||
|
now = datetime.datetime.now()
|
||||||
|
return now.strftime("%Y%m%d%H%M")
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_current_time_with_weekday():
|
||||||
|
"""
|
||||||
|
获取当前时间和星期几
|
||||||
|
返回:str,例如:2023-11-15-14-30 星期三
|
||||||
|
"""
|
||||||
|
now = datetime.datetime.now()
|
||||||
|
weekday = TimeUtils.Weekday((now.weekday() + 1) % 7 + 1).value
|
||||||
|
return f"{now.strftime('%Y-%m-%d-%H-%M')} {weekday}"
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_timestamp():
|
||||||
|
"""
|
||||||
|
获取当前时间戳
|
||||||
|
返回:int,例如:1636969800
|
||||||
|
"""
|
||||||
|
return int(time.time())
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_formatted_time(timestamp=None, format_str="%Y-%m-%d %H:%M:%S"):
|
||||||
|
"""
|
||||||
|
格式化时间
|
||||||
|
:param timestamp: 时间戳,默认为当前时间
|
||||||
|
:param format_str: 格式字符串
|
||||||
|
返回:str,例如:2023-11-15 14:30:00
|
||||||
|
"""
|
||||||
|
if timestamp is None:
|
||||||
|
timestamp = time.time()
|
||||||
|
return time.strftime(format_str, time.localtime(timestamp))
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def time_str_to_timestamp(time_str, format_str="%Y-%m-%d %H:%M:%S"):
|
||||||
|
"""
|
||||||
|
时间字符串转时间戳
|
||||||
|
:param time_str: 时间字符串
|
||||||
|
:param format_str: 格式字符串
|
||||||
|
返回:int,例如:1636969800
|
||||||
|
"""
|
||||||
|
time_array = time.strptime(time_str, format_str)
|
||||||
|
return int(time.mktime(time_array))
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_time_difference(start_time, end_time=None, format_str="%Y-%m-%d %H:%M:%S"):
|
||||||
|
"""
|
||||||
|
计算两个时间的差值(秒)
|
||||||
|
:param start_time: 开始时间(字符串或datetime对象)
|
||||||
|
:param end_time: 结束时间(字符串或datetime对象),默认为当前时间
|
||||||
|
:param format_str: 当参数为字符串时的格式
|
||||||
|
返回:timedelta对象
|
||||||
|
"""
|
||||||
|
if isinstance(start_time, str):
|
||||||
|
start_time = datetime.datetime.strptime(start_time, format_str)
|
||||||
|
if end_time is None:
|
||||||
|
end_time = datetime.datetime.now()
|
||||||
|
elif isinstance(end_time, str):
|
||||||
|
end_time = datetime.datetime.strptime(end_time, format_str)
|
||||||
|
|
||||||
|
return end_time - start_time
|
||||||
|
|
||||||
|
|
||||||
|
# 使用示例
|
||||||
|
if __name__ == "__main__":
|
||||||
|
print("当前时间(年-月-日-时-分):", TimeUtils.get_current_time())
|
||||||
|
print("当前时间和星期:", TimeUtils.get_current_time_with_weekday())
|
||||||
|
print("当前时间戳:", TimeUtils.get_timestamp())
|
||||||
|
print("格式化当前时间:", TimeUtils.get_formatted_time())
|
||||||
|
|
||||||
|
time_str = "2023-11-15 14:30:00"
|
||||||
|
print(f"'{time_str}' 转时间戳:", TimeUtils.time_str_to_timestamp(time_str))
|
||||||
|
|
||||||
|
start_time = "2023-11-15 14:30:00"
|
||||||
|
print(f"从 '{start_time}' 到现在的时间差:", TimeUtils.get_time_difference(start_time))
|
Loading…
Reference in New Issue