日期轉換工具-處理各種日期格式
日期轉換工具-處理各種日期格式
1. 簡介
提供了一個 DateConverter 類別,用於處理各種日期格式的轉換,包括:
- 民國年與西元年(公元年)的轉換
- 日期字串轉換為整數年、月、日
- 農曆年與天干地支年的轉換
- 國曆(西曆)與農曆日期的轉換
這個工具類別可以應用於需要處理不同日期格式的應用程式中,例如:歷史資料分析、多國語言日曆系統等。
2. 程式碼結構
DateConverter 類別包含多個靜態方法,每個方法負責一種日期轉換。
import datetime
from lunardate import LunarDate
class DateConverter:
"""
日期轉換工具類別,提供多種日期格式的轉換方法。
"""
# 民國年轉換為西元年
@staticmethod
def roc_to_ad(year):
"""將民國年轉換為西元年"""
if year <= 0:
raise ValueError("無效的民國年份: 年份必須大於0")
return year + 1911
# 西元年轉換為民國年
@staticmethod
def year_to_roc(year):
"""將西元年轉換為民國年"""
if year < 1912:
raise ValueError("年份不在有效範圍內: 民國年從1912年起始")
roc_year = year - 1911
return f"{roc_year}年"
# 支援的日期格式
_DATE_FORMATS = ['%Y-%m-%d', '%Y/%m/%d', '%Y年%m月%d日'] # 可擴展支持更多格式
# 日期字符串轉換為整數型別的年、月、日
@staticmethod
def convert_to_int_date(date_str):
"""將日期字符串轉換為整數型別的年、月、日"""
date = None
for date_format in DateConverter._DATE_FORMATS:
try:
date = datetime.datetime.strptime(date_str, date_format)
break
except ValueError:
pass
if date is None:
raise ValueError(f"無法解析日期:{date_str},請檢查日期格式是否正確。")
return date.year, date.month, date.day
# 農曆年轉天干地支年
@staticmethod
def lunar_year_to_gan_zhi(year):
"""將農曆年轉換為天干地支年"""
tian_gan = "甲乙丙丁戊己庚辛壬癸"
di_zhi = "子丑寅卯辰巳午未申酉戌亥"
gan_idx = (year - 4) % 10 # 天干循環
zhi_idx = (year - 4) % 12 # 地支循環
return tian_gan[gan_idx] + di_zhi[zhi_idx]
# 天干地支年轉換為多個西元年份
@staticmethod
def gan_zhi_to_lunar_years(gan_zhi_year):
"""將天干地支年轉換為多個西元年份"""
tian_gan = "甲乙丙丁戊己庚辛壬癸"
di_zhi = "子丑寅卯辰巳午未申酉戌亥"
gan = gan_zhi_year[0]
zhi = gan_zhi_year[1]
gan_idx = tian_gan.index(gan)
zhi_idx = di_zhi.index(zhi)
current_year = datetime.datetime.now().year
year_list = []
for i in range(current_year, current_year - 241, -1): # 遍歷過去240年
gan_idx_shift = (i - 4) % 10 # 根據天干的周期,向前位移4年
zhi_idx_shift = (i - 4) % 12 # 根據地支的周期,向前位移4年
if gan_idx_shift == gan_idx and zhi_idx_shift == zhi_idx:
year_list.append(i)
return year_list
# 國曆日期轉換為農曆日期
@staticmethod
def convert_to_lunar_date(year, month, day):
"""將國曆日期轉換為農曆日期"""
lunar_date = LunarDate.fromSolarDate(year, month, day)
return lunar_date
# 農曆日期轉換為國曆日期
@staticmethod
def convert_to_solar_date(year, month, day):
"""將農曆日期轉換為國曆日期"""
lunar_date = LunarDate(year, month, day)
return lunar_date.toSolarDate()
datetime
模組:用於處理日期和時間相關的操作。lunardate
模組:用於處理農曆日期。
3. 各種日期轉換方法
3.1. 民國年與西元年轉換
roc_to_ad(year)
:將民國年轉換為西元年。- 如果輸入的民國年小於等於 0,則引發 ValueError。
- 西元年 = 民國年 + 1911
year_to_roc(year)
:將西元年轉換為民國年。- 如果輸入的西元年小於 1912,則引發 ValueError。
- 民國年 = 西元年 - 1911
@staticmethod
def roc_to_ad(year):
"""將民國年轉換為西元年"""
if year <= 0:
raise ValueError("無效的民國年份: 年份必須大於0")
return year + 1911
@staticmethod
def year_to_roc(year):
"""將西元年轉換為民國年"""
if year < 1912:
raise ValueError("年份不在有效範圍內: 民國年從1912年起始")
roc_year = year - 1911
return f"{roc_year}年"
3.2. 日期字串轉換為整數年、月、日
convert_to_int_date(date_str)
:將日期字串轉換為整數型別的年、月、日。- 使用
_DATE_FORMATS
列表中定義的日期格式嘗試解析日期字串。 - 如果所有格式都無法解析,則引發 ValueError。
- 使用
_DATE_FORMATS = ['%Y-%m-%d', '%Y/%m/%d', '%Y年%m月%d日'] # 可擴展支持更多格式
@staticmethod
def convert_to_int_date(date_str):
"""將日期字符串轉換為整數型別的年、月、日"""
date = None
for date_format in DateConverter._DATE_FORMATS:
try:
date = datetime.datetime.strptime(date_str, date_format)
break
except ValueError:
pass
if date is None:
raise ValueError(f"無法解析日期:{date_str},請檢查日期格式是否正確。")
return date.year, date.month, date.day
3.3. 農曆年與天干地支年的轉換
lunar_year_to_gan_zhi(year)
:將農曆年轉換為天干地支年。- 使用天干和地支的循環列表計算對應的天干和地支。
gan_zhi_to_lunar_years(gan_zhi_year)
:將天干地支年轉換為可能的西元年份列表。- 遍歷過去 240 年,找出符合給定天干地支的年份。
@staticmethod
def lunar_year_to_gan_zhi(year):
"""將農曆年轉換為天干地支年"""
tian_gan = "甲乙丙丁戊己庚辛壬癸"
di_zhi = "子丑寅卯辰巳午未申酉戌亥"
gan_idx = (year - 4) % 10 # 天干循環
zhi_idx = (year - 4) % 12 # 地支循環
return tian_gan[gan_idx] + di_zhi[zhi_idx]
@staticmethod
def gan_zhi_to_lunar_years(gan_zhi_year):
"""將天干地支年轉換為多個西元年份"""
tian_gan = "甲乙丙丁戊己庚辛壬癸"
di_zhi = "子丑寅卯辰巳午未申酉戌亥"
gan = gan_zhi_year[0]
zhi = gan_zhi_year[1]
gan_idx = tian_gan.index(gan)
zhi_idx = di_zhi.index(zhi)
current_year = datetime.datetime.now().year
year_list = []
for i in range(current_year, current_year - 241, -1): # 遍歷過去240年
gan_idx_shift = (i - 4) % 10 # 根據天干的周期,向前位移4年
zhi_idx_shift = (i - 4) % 12 # 根據地支的周期,向前位移4年
if gan_idx_shift == gan_idx and zhi_idx_shift == zhi_idx:
year_list.append(i)
return year_list
3.4. 國曆(西曆)與農曆日期的轉換
convert_to_lunar_date(year, month, day)
:將國曆日期轉換為農曆日期。- 使用
LunarDate.fromSolarDate()
方法將國曆日期轉換為LunarDate
物件。
- 使用
convert_to_solar_date(year, month, day)
:將農曆日期轉換為國曆日期。- 使用
LunarDate()
建立LunarDate
物件,然後使用toSolarDate()
方法轉換為國曆日期。
- 使用
@staticmethod
def convert_to_lunar_date(year, month, day):
"""將國曆日期轉換為農曆日期"""
lunar_date = LunarDate.fromSolarDate(year, month, day)
return lunar_date
@staticmethod
def convert_to_solar_date(year, month, day):
"""將農曆日期轉換為國曆日期"""
lunar_date = LunarDate(year, month, day)
return lunar_date.toSolarDate()
4. 使用範例
以下是如何使用 DateConverter
類別中的方法的範例:
from date_converter import DateConverter
# 民國年轉換為西元年
roc_year = 112
ad_year = DateConverter.roc_to_ad(roc_year)
print(ad_year) # 輸出: 2023
# 西元年轉換為民國年
year = 2023
roc_year = DateConverter.year_to_roc(year)
print(roc_year) # 輸出: "112年"
# 轉換天干地支年為西元年
gan_zhi_year = "丙辰"
years = DateConverter.gan_zhi_to_lunar_years(gan_zhi_year)
print(years) # 輸出: [1976, 1916, 1856, 1796]
# 日期字符串轉換為整數型別的年、月、日
date_str = "1976-10-10"
year, month, day = DateConverter.convert_to_int_date(date_str)
print(year, month, day) # 輸出: 1976 10 10
# 農曆日期轉換為國曆日期
lunar_date = DateConverter.convert_to_lunar_date(2023, 1, 1)
print(lunar_date) # 輸出: 2023年1月1日的農曆日期
# 國曆日期轉換為農曆日期
solar_date = DateConverter.convert_to_solar_date(2023, 1, 1)
print(solar_date) # 輸出: 2023年1月1日的國曆日期
5. 程式碼邏輯優化
- 錯誤處理: 在
roc_to_ad
和year_to_roc
方法中,對輸入的年份進行驗證,如果無效則引發ValueError
。 - 日期格式管理: 使用
_DATE_FORMATS
列表集中管理支援的日期格式,方便擴展和維護。 - 程式碼重用: 將天干地支的計算邏輯封裝在
lunar_year_to_gan_zhi
方法中,避免在gan_zhi_to_lunar_years
方法中重複計算。
6. 總結
DateConverter
類別提供了一組方便的日期轉換工具,可以處理多種日期格式。程式碼結構清晰,易於理解和維護。同時,程式碼中包含錯誤處理、日期格式管理和程式碼重用等優化措施,提高了程式碼的可靠性和可擴展性。