10

How do I convert the following Objective-C code into Swift code?

#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

I'm formatting a date.

ma11hew28
  • 121,420
  • 116
  • 450
  • 651
  • 4
    use `NSDateFormatter` – Bryan Chen Jun 17 '14 at 02:52
  • 1
    I would just use an `NSDateFormatter` instead of `strftime(3)` – Jason Coco Jun 17 '14 at 02:52
  • 3
    Step telling people to do something that doesn't answer the question. There are multiple valid reasons to not use NSDateFormatter, and you not answering the OP doesn't help either him or anyone else looking for this exact same thing. So tired of finding "use NSDateFormatter" when I try to find strftime. Sigh. – Gargoyle Dec 24 '15 at 00:25

4 Answers4

45

As the commentators @BryanChen and @JasonCoco said, use NSDateFormatter.

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

A full description of the format strings is available in "Data Formatting Guide".

Grimxn
  • 22,115
  • 10
  • 72
  • 85
  • 2
    Date formatting symbols: [ICU Formatting Dates and Times](http://userguide.icu-project.org/formatparse/datetime) – zaph Jun 17 '14 at 11:47
  • 2
    I'm sorry but how is this using strformat? The OP Clearly asks for this, not for this solution. – Mathijs Segers Jun 19 '15 at 07:14
  • 1
    Read @zaph's comments below, at the time of this question & answer. strformat is inherently unsafe, and this code effects the same output as the OP requested using safe Swift constructs. – Grimxn Jun 19 '15 at 07:41
  • 1
    @Grimxn @Unome this is **not** the correct answer. `NSDateFormatter` can be extremely performance degrading when parsing many dates, and is likely why the original code does not use it. This is not the answer to the question. – Jordan Smith Jul 06 '16 at 01:57
  • 1
    @Jordan, commenting negatively on peoples answers to promote your own is BM. This code is very simple and useful FOR scenarios that you don't need to parse many dates. FOR scenarios that require parsing lots of dates, I agree that your lower level solution is better AT the cost of readability and complexity. Neither answer is write or wrong. And the OP selected hasn't selected either as the correct answer. I will remove my "Accept this answer" comment since multiple answers are useful in this post. – Unome Aug 03 '16 at 19:07
  • 1
    @Unome not trying to promote my own answer sorry, I don't care how many up votes my answer gets. The comment was meant to align with the above comment by Mathjis Segers: the question asked how to convert code, not how to do something a different way. It's like asking how to say something in Spanish, and getting told that most people speak English anyway - no Spanish answer given. – Jordan Smith Aug 03 '16 at 21:15
1

Here is another example that uses NSDateFormatterStyle:

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

The output is formatted as, "January 1, 1990".

If you want to read more about the formatter and the different available styles, checkout, NSFormatter under NSDateFormatter section.

Zorayr
  • 23,770
  • 8
  • 136
  • 129
0

My function i use.

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")
YanSte
  • 10,661
  • 3
  • 57
  • 53
-1
    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
ma11hew28
  • 121,420
  • 116
  • 450
  • 651
  • 3
    DO NOT DO THIS! One point of Swift is to get away from "C" and explicit pointers toward a more safe language. Here we not only have "C" syntax but the possibility to over-run `buffer` with a future code change. This is not even acceptable "C" code from a safety perspective. – zaph Jun 17 '14 at 11:42
  • 6
    @joan @zaph To be honest, with some modifications this would be a viable approach and a valid alternative for a more performance critical scenario. `NSDateFormatter` is notoriously slow and when performance is critical we need to manage a cached formatter - or we may be happy with this approach. – CouchDeveloper Jan 01 '15 at 17:33
  • 1
    I don't get why other things are upvoted and this is downvoted, this is the only real answer to OP's question, also his own answer of course. But if you want to use a strformat string, you need to use something like this the NSformatter won't support it. – Mathijs Segers Jun 19 '15 at 07:16