Как конвертировать григорианские даты в китайский (не Sexagenary Cycle) в Swift - PullRequest
0 голосов
/ 30 марта 2020

Я пытаюсь перевести китайский Новый год в григорианский календарь. Но я столкнулся с проблемой с iOS, потому что SDK возвращает год между 1 и 60 (Sexagenary Cycle) не в абсолютном масштабе. Вот код с игровой площадки 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

Похоже, мне не хватает какой-то настройки, чтобы переключиться с Sexagenary на обычные годы, но я нигде не могу его найти.

Подробнее подробно ... в этом суть моей проблемы ...

//  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

Почему это не работает? Исправление форматера не затрагивает компоненты. Год. Единственное, что работает, это компоненты. Год в диапазоне 1.60 для шестигранного цикла.

Ответы [ 2 ]

0 голосов
/ 04 апреля 2020

Наконец дошли до сути вопроса. Мой первоначальный вопрос можно было бы выразить более элегантно: «Каков месяц и день китайского нового года для григорианского года?». В моем путешествии я узнал, что китайский календарь следует шестнадцатилетнему циклу. Эра является важной концепцией, потому что вы должны использовать ее, чтобы получить правильный григорианский год. Если не указать «Эра» в китайском календаре, будут возвращены месяц и день в текущей эре, которая началась в 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 по Григорианскому году имеет решающее значение для получения правильной китайской эры.

0 голосов
/ 30 марта 2020

Ваш код тоже в порядке. Просто измените формат на этот:

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)")
...