如何在 Swift 中将公历日期转换为中文(不是天干地支)

How to convert Gregorian dates to Chinese (not Sexagenary Cycle) in Swift

我正在尝试将农历新年转换为公历。但是我 运行 遇到了 iOS 的麻烦,因为 SDK 返回的年份介于 1 到 60(天干地支)之间,而不是绝对比例。这是来自 Xcode 游乐场的代码...

let inputGregorianYear = 2020

let chineseCalendar = Calendar(identifier: .chinese)
let gregorianCalendar = Calendar(identifier: .gregorian)

var formatter = DateFormatter()
formatter.dateFormat = "MM/dd/yyyy"

var gregorianComponents = DateComponents()

gregorianComponents.month = 1
gregorianComponents.day = 25
gregorianComponents.year = inputGregorianYear

let chineseNewYear = gregorianCalendar.date(from: gregorianComponents)

formatter.calendar = chineseCalendar
let chineseDateStr = formatter.string(from: chineseNewYear!)
print("Chinese date: \(chineseDateStr)")     //  Chinese date: 01/01/0037 Should be 01/01/4718?

formatter.calendar = gregorianCalendar
let gregorianDateStr = formatter.string(from: chineseNewYear!)
print("Gregorian date: \(gregorianDateStr)") // Gregorian date: 01/25/2020

好像我缺少一些从天干地支切换到正常年份的设置,但我在任何地方都找不到它。

更多细节...这是我问题的关键...

//  Here is the problem...
let chineseCalendar = Calendar(identifier: .chinese)
let gregorianCalendar = Calendar(identifier: .gregorian)

var components = DateComponents()
components.day = 1
components.month = 1
components.year = 4658

let chineseNewYear = chineseCalendar.date(from: components)

var formatter = DateFormatter()
formatter.dateFormat = "MM/dd/YYYY"

formatter.calendar = chineseCalendar
let chineseDateStr = formatter.string(from: chineseNewYear!)
print("Chinese date: \(chineseDateStr)")     //  "Chinese date:  01/01/9278" Should be 1/1/4658?

formatter.calendar = gregorianCalendar
let gregorianDateStr = formatter.string(from: chineseNewYear!)
print("Gregorian date: \(gregorianDateStr)") // "Gregorian date: 01/30/6641" Should be 02/12/2021

为什么这行不通?格式化程序修复不解决 components.year。唯一有效的是 components.year 在 1..60 范围内的天干地支。

你的代码也很好。只需将格式更改为:

formatter.dateFormat = "MM/dd/YYYY"

这就是我转换日期的方式。

let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "dd/MM/YYYY"
dateFormatter.calendar = Calendar(identifier: .gregorian)
let date = Date()
let dateInGregorian = dateFormatter.string(from: date)

print(dateInGregorian)

dateFormatter.calendar = Calendar(identifier: .chinese)
dateFormatter.dateFormat = "dd/MM/YYYY"
print("Converted date to Chinese = \(dateFormatter.string(from: date))")

要转换为公历:

dateFormatter.calendar = Calendar(identifier: .gregorian)
dateFormatter.dateFormat = "dd/MM/YYYY"
print("Converted date to Gregorian = \(dateFormatter.string(from: date))")

我们在处理中国日期时有不同的格式,请使用"dd MMM YYYY"。将中文转换为公历

func convertDateFrom(dateString: String, dateFormat: String) -> Date? {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = dateFormat
dateFormatter.locale = Locale(identifier: "en_us")
guard let date = dateFormatter.date(from: dateString) else {return nil}
return date
}

let dateGregorian = convertDateFrom(dateString: "09/03/4657", dateFormat: "dd MMM YYYY") ?? Date()

print("Converted date to Gregorian = \(dateGregorian)")

终于追根究底了。我原来的问题可以更优雅地表述为... "What is the Month and Day of Chinese New Year for a Gregorian year?"。在我的旅程中,我了解到中国历法遵循六十年纪元的天干地支循环。纪元是一个重要的概念,因为您需要使用它来获得正确的公历年份。不指定中国历法中的纪元将 return 是从 1984 年开始的当前纪元中的月和日。

以下是我如何解决获取任何公历年份的农历新年月份和日期的问题:

enter var chineseCalendar = Calendar(identifier: .chinese)

let g_year = 2020
let g_adj_year = g_year + 2697

let c_era = Int(g_adj_year/60)
let c_year = g_adj_year - c_era * 60

var components = DateComponents()
components.era = c_era
components.year = c_year
components.month = 1
components.day = 1

let c_ny = chineseCalendar.date(from: components)!

var gregorianCalendar = Calendar(identifier: .gregorian)
gregorianCalendar.timeZone = TimeZone(secondsFromGMT: 0)!

let formatter = DateFormatter()
formatter.dateFormat = "MM/dd/yyyy"
formatter.calendar = gregorianCalendar

print("\(formatter.string(from: c_ny))")  // 01/25/2020

公历年的 2697 偏移对于获得正确的中国纪元至关重要。