Skip to content

Commit 348ca5b

Browse files
2025-04-15
1 parent e8780aa commit 348ca5b

1 file changed

Lines changed: 18 additions & 25 deletions

File tree

Sources/ZodiacKit/Services/ZodiacService.swift

Lines changed: 18 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -93,40 +93,33 @@ extension ZodiacService {
9393
/// - Returns: The ChineseZodiacSign corresponding to the given date.
9494
/// - Throws: ZodiacError if the zodiac sign cannot be determined or if data is invalid.
9595
public func getChineseZodiac(from date: Date) throws -> ChineseZodiacSign {
96-
let chineseDate = convertToChineseDate(from: date)
97-
let extractedBranch = try extractBranchFrom(chineseDate: chineseDate)
98-
guard let zodiac = branchNameToZodiac(extractedBranch) else {
96+
guard let branch = getChineseZodiacBranch(from: date),
97+
let zodiac = branchNameToZodiac(branch) else {
9998
throw ZodiacError.invalidData
10099
}
101100
return zodiac
102101
}
103102

104-
/// Converts a Gregorian date to a Chinese calendar date string.
103+
/// Determines the Earthly Branch associated with the Chinese Zodiac year for a given date.
105104
///
106-
/// - Parameter date: The date to convert.
107-
/// - Returns: A string representing the date in the Chinese calendar.
108-
private func convertToChineseDate(from date: Date) -> String {
105+
/// This method calculates the cyclical year in the Chinese calendar and maps it to
106+
/// one of the twelve Earthly Branches used in the Chinese Zodiac system. The branch
107+
/// is returned as a lowercase Pinyin string (e.g., "zi" for Rat, "chou" for Ox).
108+
///
109+
/// - Parameter date: The Gregorian date for which to determine the Chinese Zodiac branch.
110+
/// - Returns: A Pinyin string representing the Earthly Branch (e.g., "zi", "chou", "yin"),
111+
// or `nil` if the year could not be determined.
112+
private func getChineseZodiacBranch(from date: Date) -> String? {
109113
let chineseCalendar = Calendar(identifier: .chinese)
110-
let formatter = DateFormatter()
111-
formatter.calendar = chineseCalendar
112-
formatter.dateStyle = .full
113-
let chineseDate = formatter.string(from: date)
114-
return chineseDate
115-
}
114+
let components = chineseCalendar.dateComponents([.year], from: date)
116115

117-
/// Extracts the zodiac branch name from a Chinese calendar date string.
118-
///
119-
/// - Parameter chineseDate: A string representing a date in the Chinese calendar.
120-
/// - Returns: The extracted branch name.
121-
/// - Throws: ZodiacError.incorrectDateFormat if the date format is incorrect.
122-
private func extractBranchFrom(chineseDate: String) throws -> String {
123-
guard let hyphen = chineseDate.firstIndex(of: "-") else {
124-
throw ZodiacError.incorrectDateFormat
116+
guard let cyclicalYear = components.year else {
117+
return nil
125118
}
126-
let startIndex = chineseDate.index(after: hyphen)
127-
let endIndex = chineseDate.index(chineseDate.endIndex, offsetBy: -2)
128-
let branchExtracted = chineseDate[startIndex ... endIndex]
129-
return String(branchExtracted)
119+
120+
let branchIndex = (cyclicalYear - 1) % 12
121+
let branches = ["zi", "chou", "yin", "mao", "chen", "si", "wu", "wei", "shen", "you", "xu", "hai"]
122+
return branches[branchIndex]
130123
}
131124

132125
/// Maps a Chinese Zodiac branch name to its corresponding zodiac sign.

0 commit comments

Comments
 (0)