Format Dates in iOS: Mastering `NSDateFormatter` Class

Date Formatting in iOS: Understanding the NSDateFormatter Class

Introduction

In this article, we will delve into the world of date formatting in iOS. Specifically, we will explore how to format dates using the NSDateFormatter class and address a common question regarding the formatting of days with ordinal suffixes (e.g., “st”, “nd”, “rd”).

Understanding the Basics of NSDateFormatter

The NSDateFormatter class is used to convert an NSDate object into a string representation. It provides various options for controlling the format of the output date string, including the style, calendar, and locale.

Creating an NSDateFormatter Object

To begin with, we need to create an instance of the NSDateFormatter class. We can do this by initializing it with a default style:

NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];

However, this will result in a very basic format, which may not meet our requirements. To customize the format, we need to set the style using one of several predefined formats.

Setting the Format Style

iOS provides several built-in styles for formatting dates:

  • @"YYYY": The year in four digits (e.g., “2023”)
  • @"MM": The month as a zero-padded two-digit value (e.g., “12”)
  • @"dd": The day of the month as a zero-padded two-digit value (e.g., “18”)
  • @"EEEE": The full weekday name (e.g., “Friday”)

To set these styles, we use the setDateFormat: method:

[dateFormat setDateFormat:@"EEEE, MMMM d"];

This sets the format style to display the full weekday name followed by a comma and then the month and day.

Handling Ordinal Sufffixes for Days

The question at hand is how to handle ordinal suffixes for days (e.g., “st”, “nd”, “rd”). Unfortunately, iOS’s built-in NSDateFormatter class does not support these by default. However, we can achieve this using a combination of the components: method of the NSCalendar class and some clever string manipulation.

Breaking Down the Day Component

To handle ordinal suffixes for days, we first need to break down the day component into its constituent parts:

NSDateComponents *dtComp = [cal components:NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit fromDate:today];

This returns a NSDateComponents object containing the year, month, and day components.

Determining the Ordinal Suffix

We then need to determine which ordinal suffix to apply based on the value of the day component. We can do this using a simple switch statement:

switch ([dtComp day]) {
    case 1:
        // First day
        break;
    case 2:
        // Second day
        break;
    case 3:
        // Third day
        break;
    default:
        // Fourth day and above
        break;
}

However, this approach is not very scalable. A better approach would be to use a single function that takes the day component as an input:

- (NSString *)ordinalSuffixForDay:(NSInteger)day {
    switch (day % 10) {
        case 1:
            return @"st";
        case 2:
            return @"nd";
        case 3:
            return @"rd";
        default:
            return @"th";
    }
}

This function returns the ordinal suffix for a given day component.

Applying the Ordinal Suffix

We can now use this function to apply the correct ordinal suffix to our date string:

NSString *dateString = [dateFormat stringFromDate:today];
NSString *ordinalSuffix = [self ordinalSuffixForDay:[dtComp day]];
dateString = [dateString stringByReplacingOccurrencesOfString:[NSString stringWithFormat:@"%i",[dtComp day]] withString:[NSString stringWithFormat:@"%@%i",ordinalSuffix,[dtComp day]]];

Putting It All Together

Now that we have all the pieces in place, let’s put it together to see how our final date string would look:

NSDate *today = [NSDate date];
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:@"EEEE, MMMM d"];

NSString *dateString = [dateFormat stringFromDate:today];

NSCalendar *cal = [NSCalendar currentCalendar];
unsigned unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit |  NSDayCalendarUnit;
NSDateComponents *dtComp = [cal components:unitFlags fromDate:today];

switch ([dtComp day]) {
    case 1:
        dateString = [dateString stringByReplacingOccurrencesOfString:@"1" withString:@"st"];
        break;
    case 2:
        dateString = [dateString stringByReplacingOccurrencesOfString:@"2" withString:@"nd"];
        break;
    case 3:
        dateString = [dateString stringByReplacingOccurrencesOfString:@"3" withString:@"rd"];
        break;
    default:
        dateString = [dateString stringByReplacingOccurrencesOfString:@"4" withString:@"th"];
        break;
}

[dateFormat release];

This final code block shows how to handle ordinal suffixes for days using a combination of the components: method and some clever string manipulation.

Conclusion

In this article, we explored how to format dates in iOS using the NSDateFormatter class. We also delved into the world of ordinal suffixes for days and showed how to handle them using a single function and some clever string manipulation. With these techniques under your belt, you should be able to create sophisticated date formatting schemes that meet your specific requirements.


Last modified on 2024-10-05