Swift:使用 strftime 和 localtime 格式化 NSDate

Posted

技术标签:

【中文标题】Swift:使用 strftime 和 localtime 格式化 NSDate【英文标题】:Swift: NSDate formatting with strftime & localtime 【发布时间】:2014-08-06 22:43:30 【问题描述】:

如何将以下 Objective-C 代码转换为 Swift 代码?

#define MAX_SIZE 11
char buffer[MAX_SIZE];
time_t time = [[NSDate date] timeIntervalSince1970];
strftime(buffer, MAX_SIZE, "%-l:%M\u2008%p", localtime(&time));
NSString *dateString = [NSString stringWithUTF8String:buffer];
NSLog(@"dateString: %@", dateString); // dateString: 11:56 PM

我正在格式化date

【问题讨论】:

使用NSDateFormatter 我只会使用NSDateFormatter 而不是strftime(3) 一步一步告诉人们做一些不能回答问题的事情。不使用 NSDateFormatter 有多种正当理由,而且您不回答 OP 对他或其他任何寻找完全相同的东西的人都没有帮助。当我尝试查找 strftime 时,厌倦了查找“使用 NSDateFormatter”。叹息。 【参考方案1】:

正如评论员@BryanChen 和@JasonCoco 所说,使用NSDateFormatter。

let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd 'at' h:mm a" // superset of OP's format
let str = dateFormatter.stringFromDate(NSDate())

"Data Formatting Guide" 中提供了格式字符串的完整说明。

【讨论】:

日期格式符号:ICU Formatting Dates and Times 对不起,这是如何使用 strformat 的? OP 显然要求这个,而不是这个解决方案。 阅读下面@zaph 的 cmets,在本问答时。 strformat 本质上是不安全的,并且此代码影响与使用安全 Swift 构造请求的 OP 相同的输出。 @Grimxn @Unome 这不是正确答案。 NSDateFormatter 在解析许多日期时可能会极大地降低性能,这可能是原始代码不使用它的原因。这不是问题的答案。 @Jordan,对人们的回答发表负面评论以推广您自己的是 BM。这段代码对于不需要解析很多日期的场景非常简单有用。对于需要解析大量日期的场景,我同意您的较低级别的解决方案以可读性和复杂性为代价更好。两个答案都不是写的或错误的。并且选择的 OP 没有选择任何一个作为正确答案。我将删除我的“接受这个答案”评论,因为这篇文章中有多个答案很有用。【参考方案2】:

这是另一个使用NSDateFormatterStyle的例子:

private func FormatDate(date:NSDate) -> String 
  let dateFormatter = NSDateFormatter()
  dateFormatter.dateStyle = NSDateFormatterStyle.LongStyle
  return dateFormatter.stringFromDate(date)

输出格式为“1990 年 1 月 1 日”。

如果您想了解有关格式化程序和不同可用样式的更多信息,请查看 NSDateFormatter 部分下的NSFormatter。

【讨论】:

【参考方案3】:

我使用的函数。

extension NSDate 
    public func toString (format: String) -> String 
        let formatter = NSDateFormatter ()
        formatter.locale = NSLocale.currentLocale()
        formatter.dateFormat = format

        return formatter.stringFromDate(self)
    

date.toString("yyyy-MM-dd")

【讨论】:

【参考方案4】:
    let maxSize: UInt = 11
    var buffer: CChar[] = CChar[](count: Int(maxSize), repeatedValue: 0)
    var time: time_t = Int(NSDate().timeIntervalSince1970)
    var length = strftime(&buffer, maxSize, "%-l:%M\u2008%p", localtime(&time))
    var dateString = NSString(bytes: buffer, length: Int(length), encoding: NSUTF8StringEncoding)
    NSLog("dateString: %@", dateString) // dateString: 11:56 PM

【讨论】:

不要这样做! Swift 的一个要点是摆脱“C”和指向更安全语言的显式指针。在这里,我们不仅有“C”语法,而且有可能在未来的代码更改中过度运行buffer。从安全角度来看,这甚至不是可接受的“C”代码。 @joan @zaph 老实说,经过一些修改,这将是一种可行的方法,也是性能更关键的场景的有效替代方案。 NSDateFormatter 是出了名的慢,当性能至关重要时,我们需要管理缓存的格式化程序 - 或者我们可能会对这种方法感到满意。 我不明白为什么其他事情被赞成而这被反对,这是对 OP 问题的唯一真正答案,当然也是他自己的答案。但是如果你想使用 strformat 字符串,你需要使用类似这样的东西,NSformatter 不支持它。

以上是关于Swift:使用 strftime 和 localtime 格式化 NSDate的主要内容,如果未能解决你的问题,请参考以下文章

swift Locale

swift Locale

swift Locale

time.strftime:格式化字符串中含中文报错处理

utc时间和local 时间互转

Swift iOS - 如何从另一个用户的 formatter.locale 设置一个用户的 formatter.locale