個人開發:TimeTracker 時間追蹤工具
這份筆記記錄了 TimeTracker
工具的設計與實現過程,該工具用於追蹤專案和功能的開發時間,並將數據保存為 JSON 格式,以便後續分析與展示。
一、專案目標
- 記錄專案開始與結束時間
- 紀錄每個功能(feature)的開發時間
- 自動計算持續時間
- 將數據存儲為 JSON,方便持久化與後續處理
- 提供命令列介面與 Makefile 支援,簡化操作流程
二、使用技術
datetime
:記錄時間戳並計算時間差json
:將追蹤數據序列化為 JSONos
:檢查檔案存在性,確保初始化與讀寫流程穩定sys
:處理命令列參數,實現靈活的命令操作- Makefile:簡化常用命令的執行
三、程式架構
my_project/
├── time_tracking/
│ ├── main.py # 命令列介面入口
│ ├── time_tracker.py # 核心邏輯,負責時間記錄與計算
├── Makefile # 提供簡化操作的命令
3.1 類別與方法概覽
time_tracker.py
- 物件導向設計:
TimeTracker
類封裝了所有時間追蹤的邏輯。 - 方法:
_load_data()
:讀取或初始化 JSON 檔案數據_save_data()
:將當前數據寫入 JSON 檔案_current_time()
:取得當前時間字串 ('%Y-%m-%d %H:%M:%S'
)_calc_duration(start, end)
:計算並返回時間差字串start_project()
/end_project()
:記錄專案整體時間start_feature(name)
/end_feature(name)
:記錄單一功能的時間
main.py
- 提供命令列介面,支援以下命令:
start_project
:開始專案end_project
:結束專案start_feature <feature_name>
:開始功能end_feature <feature_name>
:結束功能
Makefile
- 提供簡化操作的命令:
make start_project
:開始專案make end_project
:結束專案make start_feature feature=<feature_name>
:開始功能make end_feature feature=<feature_name>
:結束功能
四、核心實現
4.1 time_tracker.py
的物件導向設計
初始化與數據管理
class TimeTracker:
def __init__(self, filename='time_log.json'):
self.filename = filename
self.data = self._load_data()
def _load_data(self):
if os.path.exists(self.filename):
with open(self.filename, 'r') as f:
return json.load(f)
return {"project": {}, "features": {}}
def _save_data(self):
with open(self.filename, 'w') as f:
json.dump(self.data, f, indent=4)
__init__
:初始化TimeTracker
物件,並讀取或初始化數據。_load_data()
:若檔案存在,載入 JSON;否則回傳預設空結構。_save_data()
:將當前內存中的self.data
寫回檔案,保持持久化。
時間處理
def _current_time(self):
return datetime.now().strftime('%Y-%m-%d %H:%M:%S')
def _calc_duration(self, start, end):
start_dt = datetime.strptime(start, '%Y-%m-%d %H:%M:%S')
end_dt = datetime.strptime(end, '%Y-%m-%d %H:%M:%S')
return str(end_dt - start_dt)
_current_time()
:取得格式化的當前時間。_calc_duration()
:計算起訖時間差,並轉為字串。
專案與功能時間追蹤
def start_project(self):
self.data['project']['start_time'] = self._current_time()
self._save_data()
print("Project started.")
def end_project(self):
self.data['project']['end_time'] = self._current_time()
self.data['project']['duration'] = self._calc_duration(
self.data['project']['start_time'],
self.data['project']['end_time']
)
self._save_data()
print("Project ended.")
def start_feature(self, name):
if name not in self.data['features']:
self.data['features'][name] = {}
self.data['features'][name]['start_time'] = self._current_time()
self._save_data()
print(f"Feature '{name}' started.")
def end_feature(self, name):
feat = self.data['features'].get(name)
if feat and 'start_time' in feat:
feat['end_time'] = self._current_time()
feat['duration'] = self._calc_duration(
feat['start_time'], feat['end_time']
)
self._save_data()
print(f"Feature '{name}' ended.")
else:
print(f"Feature '{name}' has not been started.")
start_project()
/end_project()
:記錄專案的開始與結束時間,並計算總持續時間。start_feature(name)
/end_feature(name)
:記錄功能的開始與結束時間,並計算功能持續時間。
4.2 main.py
的命令列介面
import sys
from time_tracking.time_tracker import TimeTracker
tracker = TimeTracker()
def main():
if len(sys.argv) < 2:
print("Usage: python main.py [command] [feature_name (optional)]")
sys.exit(1)
command = sys.argv[1]
feature = sys.argv[2] if len(sys.argv) >= 3 else None
if command == "start_project":
tracker.start_project()
elif command == "end_project":
tracker.end_project()
elif command == "start_feature" and feature:
tracker.start_feature(feature)
elif command == "end_feature" and feature:
tracker.end_feature(feature)
else:
print("Invalid command or missing feature name.")
if __name__ == "__main__":
main()
- 命令列支援:
start_project
:開始專案。end_project
:結束專案。start_feature <feature_name>
:開始功能。end_feature <feature_name>
:結束功能。
4.3 Makefile 的簡化操作 (用 uv 建置環境)
start_project:
uv run python -m time_tracking.main start_project
end_project:
uv run python -m time_tracking.main end_project
start_feature:
uv run python -m time_tracking.main start_feature $(feature)
end_feature:
uv run python -m time_tracking.main end_feature $(feature)
make start_project
:執行start_project
命令。make end_project
:執行end_project
命令。make start_feature feature=<feature_name>
:開始功能。make end_feature feature=<feature_name>
:結束功能。
五、改進建議
- 加入檔案讀寫錯誤處理,提升穩定性。
- 提供更詳細的狀態檢視功能(如顯示所有功能的持續時間)。
- 考慮輸出 CSV 或 HTML 報表,便於後續分析。
- 整合可視化模組(
matplotlib
,plotly
)展示時間分佈圖。 - 支援更多命令列參數(如自定義輸出檔案名稱)。
六、結語
TimeTracker
是一個輕量且實用的時間追蹤工具,適合個人或小團隊使用。透過物件導向設計與命令列支援,開發者可以輕鬆掌握開發進度並進行效率分析。同時,結合 Makefile 的支援,進一步簡化了操作流程。