You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CNContact生日显示时区偏差问题求助

联系人生日时区显示问题求助

我使用ContactsCN Framework从系统“通讯录”应用中获取联系人的生日信息。该联系人在通讯录中的生日为1980年6月22日,但在我的应用中实际显示为1980年6月21日,期望显示结果与通讯录一致。偏差原因是时区差-4小时,我尝试调整时区和格式化器的多种配置均未解决问题。日期的.description属性显示正确信息:1980-06-22 00:00:00 +0000。

我尝试了以下几种方案:

  • 无格式化(但最终需要格式化日期)
  • 不设置时区的格式化
  • 使用TimeZone.current
  • 使用TimeZone.gmt
  • 使用TimeZone.init(secondsFromGMT: 14000)
  • 使用TimeZone.init(secondsFromGMT: -14000)

注:14000是EST与GMT的时差

同时我用当前日期做了对比测试,以下是测试代码:

import SwiftUI
import ContactsUI

struct TestWithCNContactView: View {
    
    let contactStore = CNContactStore()
    @State private var searchName:String = "apple"
    @State private var contacts = [CNContact]()
    
    var body: some View {
        Text("locale : \(Locale.preferredLanguages[0]), timezone : \(TimeZone.current)").padding()
        TextField("Enter the name to find in Contacts", text: $searchName, onCommit: fetchContacts).padding()
        Divider()
        
        if contacts.count > 0 {
            ScrollView {
                VStack (alignment: .leading) {
                    ForEach(contacts, id: \.self) { contact in
                        if let date1 = contact.birthday?.date {
                            HStack {Text(contact.givenName)
                                Text(contact.familyName)}.font(.title).padding(.top)
                            testDisplayDate(title: "contact bday",date: date1)
                        }
                    }
                    Divider()
                    testDisplayDate(title: "Date()",date: Date())
                }.padding()
            }
        }
    }
    func fetchContacts()  {
        let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey, CNContactBirthdayKey] as [CNKeyDescriptor]
        let predicate = CNContact.predicateForContacts(matchingName: searchName)
        contacts = try! contactStore.unifiedContacts(matching: predicate, keysToFetch: keysToFetch )
    }
}

struct testDisplayDate: View {
    var title: String
    var date: Date?
    
    var body: some View {
        Text(title).font(.title2).padding(.top)
        if let date = date {
            Text("date (no formatting) : \(date)")
            Text(".description : \(date.description)")
            Text("dateFormatter : \(date, formatter: dateFormatter)")
            Text("dateFormatterGMT : \(date, formatter: dateFormatterGTM)")
            Text("dateFormatterFull : \(date, formatter: dateFormatterFull)")
            Text("dateFormatterFullGMT : \(date, formatter: dateFormatterFullGMT)")
        } else {
            Text("no date")
        }
    }
    var dateFormatter: DateFormatter {
        let formatter = DateFormatter()
        formatter.dateFormat = "d MMMM"
        formatter.timeZone = TimeZone.current
        return formatter
    }
    var dateFormatterGTM: DateFormatter {
        let formatter = DateFormatter()
        formatter.dateFormat = "d MMMM"
        formatter.timeZone = TimeZone.gmt
        return formatter
    }
    var dateFormatterFull: DateFormatter {
        let formatter = DateFormatter()
        formatter.dateFormat = "yyyy/MM/dd HH:mm"
        formatter.timeZone = TimeZone.current
        return formatter
    }
    var dateFormatterFullGMT: DateFormatter {
        let formatter = DateFormatter()
        formatter.dateFormat = "yyyy/MM/dd HH:mm"
        formatter.timeZone = TimeZone.gmt
        return formatter
    }
    
}

我还附上了通讯录中该联系人信息和测试结果的截图,希望能得到解决该问题的方法,谢谢。


内容的提问来源于stack exchange,提问作者Pat N.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 11:13:29