swift NSDate()或Date()显示错误的时间

ni65a41a  于 2023-10-15  发布在  Swift
关注(0)|答案(4)|浏览(120)

当我尝试记录当前日期时:

print(NSDate())

print(Date())

(in Swift 3)
或任何日期对象,它显示了错误的时间。例如,现在大约是16:12,但上面显示的

2016-10-08 20:11:40 +0000

我的约会对象是不是在错误的时区?如何确定我的日期以获得正确的时区?
为什么会这样,又该如何解决?如何在打印语句或调试器中轻松显示本地时区中的任意日期?
(Note这个问题是一个“铃声”,这样我就可以提供一个简单的Swift 3/Swift 2 Date/NSDate扩展,让你可以轻松地显示本地时区的任何日期对象。

798qvoo8

798qvoo81#

NSDate(或Swift中的Date ≥ V3)没有时区。它记录了世界各地的瞬间。
在内部,date对象记录自“epoch date”或2001年1月1日午夜(Greenwich Mean Time,也称为UTC)以来的秒数。
我们通常认为日期在我们当地的时区。
如果您使用

print(NSDate())

系统显示当前日期,但以UTC/格林威治标准时间表示。所以只有在那个时区时间才会看起来正确。
如果发出debugger命令,

e NSDate()

这是一个痛苦。我个人希望iOS/Mac OS能使用用户当前时区显示日期,但他们没有。

编辑#2:

对我以前使用的本地化字符串进行了改进,使其更容易使用,这是创建Date类的扩展:

extension Date {
    func localString(dateStyle: DateFormatter.Style = .medium, timeStyle: DateFormatter.Style = .medium) -> String {
        return DateFormatter.localizedString(from: self, dateStyle: dateStyle, timeStyle: timeStyle)
    }
}

这样你就可以使用像Date().localString()这样的表达式,或者如果你只想打印时间,你可以使用Date().localString(dateStyle:.none)

编辑:

我刚刚发现NSDateFormatter(Swift 3中的DateFormatter)有一个类方法localizedString。这和我下面的扩展做的一样,但是更简单和干净。以下是声明:

class func localizedString(from date: Date, dateStyle dstyle: DateFormatter.Style, timeStyle tstyle: DateFormatter.Style) -> String

所以你只要用

let now = Date()
print (DateFormatter.localizedString(
  from: now, 
  dateStyle: .short, 
  timeStyle: .short))

你几乎可以忽略下面的一切。
我已经创建了NSDate类的一个类别(Swift 3中的Date),它有一个方法localDateString,可以显示用户本地时区的日期。
以下是Swift 3中的category:(文件名Date_DisplayString.swift)

extension Date {
  @nonobjc static var localFormatter: DateFormatter = {
    let dateStringFormatter = DateFormatter()
    dateStringFormatter.dateStyle = .medium
    dateStringFormatter.timeStyle = .medium
    return dateStringFormatter
  }()
  
  func localDateString() -> String
  {
    return Date.localFormatter.string(from: self)
  }
}

在Swift 2中:

extension NSDate {
   @nonobjc static var localFormatter: NSDateFormatter = {
    let dateStringFormatter = NSDateFormatter()
    dateStringFormatter.dateStyle = .MediumStyle
    dateStringFormatter.timeStyle = .MediumStyle
    return dateStringFormatter
  }()
  
public func localDateString() -> String
  {
    return NSDate.localFormatter.stringFromDate(self)
  }
}

(If如果你喜欢不同的日期格式,那么修改日期格式化程序使用的格式是很容易的。它也可以直接显示您需要的任何时区的日期和时间。
我建议在你所有的项目中使用合适的Swift 2/Swift 3版本。
然后可以使用
雨燕2:

print(NSDate().localDateString())

Swift 3:

print(Date().localDateString())
kgsdhlau

kgsdhlau2#

一个简单的方法来纠正日期为您的时区将使用TimeZone.current.secondsFromGMT()
对于本地时间戳值,例如:
let currentLocalTimestamp = (Int(Date().timeIntervalSince1970) + TimeZone.current.secondsFromGMT())

kd3sttzy

kd3sttzy3#

仅用于记录或打印当前时区的日期,请使用description(with:)

print(Date().description(with: .current)

此API可用于iOS 8+和macOS 10.10+

1aaf6o9v

1aaf6o9v4#

2023年的一个更简单的答案

// for the standard Apple look
let nowish = DateFormatter.localizedString(
                    from: Date(), dateStyle: .short, timeStyle: .short)
print(nowish)

结果10/28/23

// for a custom format. you need all four lines of code, in this order:
let ft = DateFormatter()
ft.locale = Locale.current
ft.setLocalizedDateFormatFromTemplate("MM/dd/yyyy")
let nowish = ft.string(from: Date())
print(nowish)

结果10/28/2023

注意一个公式有“localizedString”,另一个公式有“string”。
你经常想要“从现在开始的十天,去年,等等”的方法。在这种情况下,只需使用Calendar.current即可。

let nextYr = Calendar.current.date(byAdding: .year, value: 2, to: Date())!

然后简单地使用nextYr代替上面公式中的Date()

相关问题