将UTC日期格式转换为本地NSDate

63

我从服务器获取的是UTC时区的日期字符串,需要将其转换为本地时区。

我的代码:

let utcTime = "2015-04-01T11:42:00.269Z"    
let dateFormatter = NSDateFormatter()
dateFormatter.timeZone = NSTimeZone(name: "UTC")
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"
let date = dateFormatter.dateFromString(utcTime)
println("utc: \(utcTime), date: \(date)")

这将打印 -

UTC时间:2015年04月01日11:42:00.269Z,日期:可选(2015年04月01日11:42:00 +0000)

如果我删除

dateFormatter.timeZone = NSTimeZone(name: "UTC") 

它打印

UTC:2015-04-01T11:42:00.269Z,日期:可选(2015-04-01 08:42:00 +0000)

我的本地时区是UTC +3,第一种选项中我获取UTC,在第二个选项中我获取UTC -3

我应该得到

UTC:2015-04-01T11:42:00.269Z,日期:可选(2015-04-01 14:42:00 +0000)

那么我如何将UTC日期格式转换为本地时间?


你尝试过 formatter.timeZone = NSTimeZone.localTimeZone() 吗? - boidkan
是的,我得到了UTC-3... UTC: 2015-04-01T11:42:00.269Z,日期:可选(2015-04-01 08:42:00 +0000) - ilan
1
https://dev59.com/1n_aa4cB1Zd3GeqP4Yd2 - boidkan
@ilan 我在Swift中也遇到了同样的问题。你能帮我解决一下吗? - Rakesh
@Rakesh,请查看下面的答案,它们对我有用。 - ilan
7个回答

78
以下内容在Objective-C中对我有所帮助:

```

// create dateFormatter with UTC time format
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss"]; 
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"UTC"]];
NSDate *date = [dateFormatter dateFromString:@"2015-04-01T11:42:00"]; // create date from string

// change to a readable time format and change to local time zone
[dateFormatter setDateFormat:@"EEE, MMM d, yyyy - h:mm a"];
[dateFormatter setTimeZone:[NSTimeZone localTimeZone]];
NSString *timestamp = [dateFormatter stringFromDate:date];

我会提供这两个网站,帮助您转换不同的时间格式: http://www.w3.org/TR/NOTE-datetime http://benscheirman.com/2010/06/dealing-with-dates-time-zones-in-objective-c/ 在Swift中,代码如下:
// create dateFormatter with UTC time format
  let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss"
        dateFormatter.timeZone = NSTimeZone(name: "UTC") as TimeZone?
        let date = dateFormatter.date(from: "2015-04-01T11:42:00")// create   date from string

        // change to a readable time format and change to local time zone
        dateFormatter.dateFormat = "EEE, MMM d, yyyy - h:mm a"
        dateFormatter.timeZone = NSTimeZone.local
        let timeStamp = dateFormatter.string(from: date!)

11
在Swift 3中,它的等效代码将是:dateFormatter.timezone = TimeZone.current - Achintya Ashok
让日期等于dateFormatter.dateFromString("2015-04-01T11:42:00")。当我在设备设置中设置12小时时间格式时,这会将nil分配给日期。 - Altaf Rehman
当您将其转换回日期时,它会再次以UTC格式呈现。 - Mansuu....

70

尝试使用这个Swift扩展

Swift 4: UTC/GMT ⟺ 本地时间(当前/系统)

extension Date {

    // Convert local time to UTC (or GMT)
    func toGlobalTime() -> Date {
        let timezone = TimeZone.current
        let seconds = -TimeInterval(timezone.secondsFromGMT(for: self))
        return Date(timeInterval: seconds, since: self)
    }

    // Convert UTC (or GMT) to local time
    func toLocalTime() -> Date {
        let timezone = TimeZone.current
        let seconds = TimeInterval(timezone.secondsFromGMT(for: self))
        return Date(timeInterval: seconds, since: self)
    }

}


// Try it
let utcDate = Date().toGlobalTime()
let localDate = utcDate.toLocalTime()

print("utcDate - \(utcDate)")        //Print UTC Date
print("localDate - \(localDate)")     //Print Local Date

@Krunal,我喜欢这个的简洁性,但是当我运行它时:public func runDatesExample() { let now = Date() let utcDate = now.toGlobalTime() let localDate = now.toLocalTime() print(now) //prints: 2020-04-08 00:31:17 +0000. //actual GMT/UTC right now print("utcDate - \(utcDate)") //prints: utcDate - 2020-04-08 06:31:17 +0000 print("localDate - \(localDate)") //prints: localDate - 2020-04-07 18:31:17 +0000 }我期望utcDate的输出与now相同。 我有什么遗漏吗? - Herbal7ea
这个函数不会返回本地时区的时间。它返回一个代表某一时刻的日期对象,该对象与当前时间有一定的偏移量。然后将其作为UTC时间打印出来。 要获取表示本地时区时间的字符串,请使用DateFormatter。 - fishinear
@fishinear - 欢迎您编辑并提高此答案的质量。 - Krunal
@Krunal,没有必要这样做,已经有多个正确的答案回答了这个问题。您可以删除该答案。 - fishinear

27

c_rath的答案的Swift版本:

// create dateFormatter with UTC time format
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss"
dateFormatter.timeZone = NSTimeZone(name: "UTC")
let date = dateFormatter.dateFromString("2015-04-01T11:42:00")

// change to a readable time format and change to local time zone
dateFormatter.dateFormat = "EEE, MMM d, yyyy - h:mm a"
dateFormatter.timeZone = NSTimeZone.localTimeZone() 
let timeStamp = dateFormatter.stringFromDate(date!)

1
第5行应该是:dateFormatter.dateFormat = "EEE,MMM d,yyyy - h:mm a",第6行应该是:dateFormatter.timeZone = NSTimeZone.localTimeZone()。 - dotToString

9

我不得不从c_rath的解决方案中删除z和毫秒。在Swift 4中有效。

extension String {
    func fromUTCToLocalDateTime() -> String {
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss"
        dateFormatter.timeZone = TimeZone(abbreviation: "UTC")
        var formattedString = self.replacingOccurrences(of: "Z", with: "")
        if let lowerBound = formattedString.range(of: ".")?.lowerBound {
            formattedString = "\(formattedString[..<lowerBound])"
        }

        guard let date = dateFormatter.date(from: formattedString) else {
            return self
        }

        dateFormatter.dateFormat = "EEE, MMM d, yyyy - h:mm a"
        dateFormatter.timeZone = TimeZone.current
        return dateFormatter.string(from: date)
    }
}

6
在Swift 3中,这个很好运行:
// create dateFormatter with UTC time format
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss"
dateFormatter.timeZone = TimeZone(abbreviation: "UTC")
let date = dateFormatter.date(from: "2015-04-01T11:42:00")// create date from string

// change to a readable time format and change to local time zone
dateFormatter.dateFormat = "EEE, MMM d, yyyy - h:mm a"
dateFormatter.timeZone = TimeZone.current
let timeStamp = dateFormatter.string(from: date!)

5

继其他人提到的内容后,这是一个方便的NSDate扩展程序,使用Swift语言

import Foundation

extension NSDate {
    func ToLocalStringWithFormat(dateFormat: String) -> String {
        // change to a readable time format and change to local time zone
        let dateFormatter = NSDateFormatter()
        dateFormatter.dateFormat = dateFormat
        dateFormatter.timeZone = NSTimeZone.localTimeZone()
        let timeStamp = dateFormatter.stringFromDate(self)

        return timeStamp
    }
}

3

也许你可以尝试类似这样的方法:

extension NSDate {
    convenience init(utcDate:String, dateFormat:String="yyyy-MM-dd HH:mm:ss.SSS+00:00") {
        // 2016-06-06 00:24:21.164493+00:00
        let dateFormatter = NSDateFormatter()
        dateFormatter.dateFormat = dateFormat
        dateFormatter.timeZone = NSTimeZone(name: "UTC")

        let date = dateFormatter.dateFromString(utcDate)!
        let s = NSTimeZone.localTimeZone().secondsFromGMTForDate(date)
        let timeInterval = NSTimeInterval(s)

        self.init(timeInterval: timeInterval, sinceDate:date)
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接