iOS
Swift
DateFormatting
MonthConversion
ProgrammingTips

iOS How to get a proper Month name from a number?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Turning a month number such as 1 or 10 into a proper month name on iOS is mostly a formatting problem, not a hard-coded lookup problem. The right solution is usually DateFormatter or Calendar with an explicit locale, because that gives you localized month names and avoids maintaining your own month array by hand.

Use DateFormatter with a Real Date

The safest pattern is to build a valid date that contains the month number, then ask DateFormatter for the month name.

swift
1import Foundation
2
3func monthName(from month: Int, locale: Locale = .current) -> String? {
4    guard (1...12).contains(month) else { return nil }
5
6    var components = DateComponents()
7    components.year = 2024
8    components.month = month
9    components.day = 1
10
11    let calendar = Calendar(identifier: .gregorian)
12    guard let date = calendar.date(from: components) else { return nil }
13
14    let formatter = DateFormatter()
15    formatter.locale = locale
16    formatter.dateFormat = "MMMM"
17    return formatter.string(from: date)
18}
19
20print(monthName(from: 3) ?? "invalid")

Using a real date matters because DateFormatter formats dates, not raw integers.

Full Name Versus Short Name

The format string controls the kind of month name you get.

  • 'MMMM gives the full month name such as March'
  • 'MMM gives the abbreviated name such as Mar'
swift
let formatter = DateFormatter()
formatter.locale = Locale(identifier: "en_US")
formatter.dateFormat = "MMM"

This is much better than slicing strings manually, because the abbreviation rules depend on locale.

Localization Comes for Free

One reason to use DateFormatter instead of a hard-coded array is localization.

swift
print(monthName(from: 3, locale: Locale(identifier: "en_US")) ?? "invalid")
print(monthName(from: 3, locale: Locale(identifier: "fr_FR")) ?? "invalid")
print(monthName(from: 3, locale: Locale(identifier: "de_DE")) ?? "invalid")

The same month number can render as different text depending on the user's locale, which is usually the right behavior in a shipping app.

A Simple Array Is Fine for Fixed English Output

If you explicitly want hard-coded English month names and do not care about localization, an array is acceptable.

swift
1let months = [
2    "January", "February", "March", "April", "May", "June",
3    "July", "August", "September", "October", "November", "December"
4]
5
6func englishMonthName(from month: Int) -> String? {
7    guard (1...12).contains(month) else { return nil }
8    return months[month - 1]
9}

This is fast and simple, but it is a product decision. It hard-codes one language and one naming convention.

Reuse Formatters When Performance Matters

DateFormatter is relatively expensive to create repeatedly. If you need month names often, reuse a formatter instead of allocating a new one every time.

swift
1final class MonthFormatter {
2    static let shared: DateFormatter = {
3        let formatter = DateFormatter()
4        formatter.locale = .current
5        formatter.dateFormat = "MMMM"
6        return formatter
7    }()
8}

This matters in scrolling UIs or repeated formatting work.

Common Pitfalls

The biggest mistake is indexing into a month array without validating the range first. Month numbers in this context should be 1 through 12, not 0 through 11.

Another issue is using DateFormatter without setting or understanding the locale. If the result looks different on another device, that may be correct localization, not a bug.

People also sometimes build invalid dates accidentally by leaving out required date components. If you use DateComponents, provide a valid year, month, and day when turning it into a Date.

Finally, do not use a hard-coded English array if the app is supposed to be localized. That creates inconsistent date behavior compared with the rest of the system.

Summary

  • The best iOS solution is usually DateFormatter applied to a real Date.
  • Use MMMM for full month names and MMM for abbreviations.
  • 'DateFormatter automatically handles localization when you set the locale.'
  • A hard-coded array is acceptable only if fixed-language output is intentional.
  • Validate the month range before formatting or indexing.

Course illustration
Course illustration

All Rights Reserved.