I am trying to convert Chinese New Years to the Gregorian calendar. But I am running into trouble with iOS because the SDK is returning the year between 1 and 60 (the Sexagenary Cycle) not on an absolute scale. Here is the code from an Xcode playground...
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
Seems like I am missing some setting to switch from Sexagenary to normal years but I can't find it anywhere.
More detail... this is the crux of my problem...
// 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
Why doesn't this work? The formatter fix does not address the components.year. The only thing that works is components.year in the range of 1..60 for the sexagenary cycle.
Your code is also fine. Just change format to this:
formatter.dateFormat = "MM/dd/YYYY"
This is how I convert dates.
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))")
To convert to Gregorian:
dateFormatter.calendar = Calendar(identifier: .gregorian)
dateFormatter.dateFormat = "dd/MM/YYYY"
print("Converted date to Gregorian = \(dateFormatter.string(from: date))")
We have different format when working with chinese date, use "dd MMM YYYY". To convert Chinese to Gregorian
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)")