To make a month-and-day publication label on a Mac, request those two fields with Swift’s Foundation formatter and let the locale arrange them. First decide whether your input is a calendar date or a timestamp: that determines whether a time zone should change the displayed day.
This guide walks through a small Terminal script for producing publication labels from synthetic dates. It uses Date.FormatStyle for the main operation and shows the template-based alternative for existing DateFormatter code. Apple documents both approaches for localized date output. Date.FormatStyle, DateFormatter
Request month and day as fields, not as a finished pattern
A pattern such as MMMM d fixes the month before the day. A localized field request specifies what to include while leaving arrangement to the formatter. In Swift, the relevant expression is Date.FormatStyle().month(.wide).day(). Apple explicitly states that the order of formatting modifiers does not affect the resulting string. Calling .day() first therefore does not force day-first output. Date.FormatStyle
For the synthetic publication date November 12, 2026, illustrative labels are November 12 with en_US and 12 November with en_GB. These are explicit preview locales; the working script also prints a label using the Mac’s current locale. Apple demonstrates the same month-and-day ordering difference with its localized template API. DateFormatter
Unicode describes the underlying distinction through date skeletons: they contain requested fields and field lengths, and software matches them to an appropriate localized pattern. For example, MMMd requests an abbreviated month and day. It does not prescribe a slash, a space, or the final display order. This is the useful principle to carry between APIs: select components, then let the formatter assemble the label. Unicode Technical Standard #35, Part 4: Dates
Decide what your publication date represents
Before formatting, choose the appropriate row below. This decision prevents a correct formatter from displaying an unintended calendar day.
| Input | Meaning | Formatting decision |
|---|---|---|
Year 2026, month 11, day 12 |
A civil date: one day in a specified calendar | Preserve those fields; use a consistent calendar and time zone when bridging through Date |
2026-11-12T00:30:00Z |
A timestamp identifying an instant | Parse the instant, then choose the time zone in which to display it |
+02:00 |
A numeric offset from UTC | Enough to relate a local timestamp to UTC; it does not identify a named zone |
Europe/London |
A named time zone identifier | Use its rules for the instant being displayed |
Apple defines Date as a point in time independent of any calendar or time zone. DateComponents holds fields such as year, month, and day that are evaluated using a calendar and time zone. Consequently, a date-only publication record needs an explicit conversion convention when passed to an API that formats Date. Date, DateComponents
For this task, the convention is straightforward: keep the source year, month, and day, construct a Gregorian date at noon in UTC, and format it using that same calendar and UTC zone. Noon is simply a chosen anchor for this example. Keeping construction and formatting consistent is what preserves the date. The anchor does not assert an actual publication time.
For a genuine timestamp, choose the intended display zone instead. A locale controls presentation; it does not supply the timestamp’s intended zone. A named zone can have different offsets at different instants, whereas a fixed numeric offset supplies no such rules. Apple exposes both zone identifiers and offset-at-date operations. RFC 3339 defines timestamp offsets, and RFC 9557 extends that representation to carry additional information including a time zone. TimeZone, RFC 3339, RFC 9557
Run a complete month-and-day formatter in Terminal
Use macOS 12 or later with a Swift toolchain and the macOS SDK available. Apple documents the Date.FormatStyle initializer used here as available from macOS 12. Swift’s official installation page provides Mac setup instructions, including Xcode for Apple-platform development. Format-style initializer, Install Swift — macOS
Save the following complete program as MonthDay.swift in a plain-text editor. It contains its own synthetic sample data, validates the calendar fields, and prints current-locale and explicit-locale previews. It also prints the equivalent template-based result so you can compare the two APIs.
import Foundation
enum LabelError: Error {
case unavailableUTC
case invalidPublicationDate
}
func main() throws {
guard let utc = TimeZone(secondsFromGMT: 0) else {
throw LabelError.unavailableUTC
}
var calendar = Calendar(identifier: .gregorian)
calendar.timeZone = utc
// Synthetic civil publication date, not an actual timestamp.
var fields = DateComponents()
fields.calendar = calendar
fields.timeZone = utc
fields.year = 2026
fields.month = 11
fields.day = 12
fields.hour = 12
guard fields.isValidDate(in: calendar),
let publicationDate = calendar.date(from: fields) else {
throw LabelError.invalidPublicationDate
}
let previews: [(String, Locale)] = [
("Current locale", .current),
("en_US", Locale(identifier: "en_US")),
("en_GB", Locale(identifier: "en_GB"))
]
for (name, locale) in previews {
let style = Date.FormatStyle(
locale: locale,
calendar: calendar,
timeZone: utc
)
.month(.wide)
.day()
print("\(name): \(publicationDate.formatted(style))")
let formatter = DateFormatter()
formatter.locale = locale
formatter.calendar = calendar
formatter.timeZone = utc
formatter.setLocalizedDateFormatFromTemplate("MMMMd")
print("\(name), template: \(formatter.string(from: publicationDate))")
}
}
try main()
Open Terminal, change to the folder containing the file, and run swift MonthDay.swift. If the Swift toolchain is unavailable, complete the official Mac installation steps before continuing. This example was inspected against the documentation but was not executed in this research environment because Swift was unavailable.
The two explicit previews should demonstrate month-first and day-first labels for the same November 12 date. The current-locale line follows your Mac’s current locale setting. Both formatter paths request a full month name and day without adding a year or time. Treat the output as localized display text; avoid making downstream processing depend on a particular space or punctuation character. Unicode’s pattern-matching model permits locale-specific arrangements. Unicode Technical Standard #35, Part 4: Dates
The Gregorian calendar in this program is intentional: the synthetic source fields are defined in that calendar. It remains fixed while the locale changes the presentation. If your source dates use a different calendar, interpret their fields using that calendar before deciding how to display them. Apple’s initializer exposes locale, calendar, and time zone separately for this purpose. Format-style initializer
Use a localized template in existing DateFormatter code
The second path in the program uses setLocalizedDateFormatFromTemplate("MMMMd"). Here, MMMM requests a full month and d requests a day of the month. The string is a template passed to a localization method; it is not assigned directly as the final dateFormat. Apple’s own example uses this exact template to produce different month-and-day orders. DateFormatter
Set locale before calling the template method. Apple explicitly requires that sequence because the method derives the format using the formatter’s locale at that point. If you later select another locale, call the template method again. The example creates a fresh formatter for each preview, making that dependency visible. setLocalizedDateFormatFromTemplate(_:)
For this label task, choose whichever path fits your existing code: field modifiers in the modern Swift API, or the localized template method in a DateFormatter workflow. Avoid assembling separately formatted month and day strings with your own separator, because doing so takes responsibility for the arrangement away from the date formatter.
Handle timestamps without accidentally changing the task
Suppose the source instead supplies the synthetic timestamp 2026-11-12T00:30:00Z. That identifies an instant. Displaying it at offset +00:00 yields November 12; displaying the same instant at offset -02:00 yields November 11 at 22:30. This is an illustrative offset calculation, not an observed publication event. RFC 3339 defines numeric offsets as local time minus UTC. RFC 3339, section 4.2
Parse such input with an ISO 8601 API configured for its actual representation, then format the resulting instant with the selected display zone. Apple documents ISO8601DateFormatter and its .withInternetDateTime option for RFC 3339 date-and-time strings. That option is a parsing configuration, separate from the localized month-and-day output request. ISO8601DateFormatter formatOptions
Do not apply this timestamp workflow to a source that supplies only a civil date unless you have deliberately defined the conversion convention. Likewise, do not assume the Z suffix identifies the publication’s named time zone. RFC 9557 treats named-zone information as additional information beyond the base timestamp representation. RFC 9557
Diagnose an unexpected label in the right order
Use this sequence to identify which decision needs changing:
- The day is wrong: check whether the input is a civil date or an instant. For the civil-date program, keep construction and formatting in UTC. For an instant, verify the intended display zone.
- The month and day appear in the wrong order: inspect the locale passed to the formatter and check for a directly assigned
dateFormator manually joined strings. - Changing modifier order has no effect: that is documented behavior. Select the appropriate locale instead of rearranging
.month()and.day(). - The template output retains an earlier arrangement: set the new locale, then regenerate the format with
setLocalizedDateFormatFromTemplate. - The source fields are invalid: report or correct the input. The complete program checks validity before conversion rather than substituting another publication date.
These checks follow the documented separation between an instant, its calendar interpretation, and its localized presentation. Apple documents modifier-order independence, template setup order, and date-component validation in the corresponding APIs. Date.FormatStyle, setLocalizedDateFormatFromTemplate(_:), DateComponents
Keep the full source date or timestamp after producing the label. A month-and-day string intentionally omits the year, and a formatted timestamp label also omits its time and zone; that display text cannot preserve the complete input. For a dependable publication label, retain the original value, choose the calendar and zone deliberately, and let the locale arrange the requested month and day.
Sources
- Date.FormatStyle — Apple
- DateFormatter — Apple
- Unicode Technical Standard #35: Unicode Common Locale Data & Rules, Part 4: Dates — Unicode Consortium
- Date — Apple
- DateComponents — Apple
- TimeZone — Apple
- init(date:time:locale:calendar:timeZone:capitalizationContext:) — Apple
- setLocalizedDateFormatFromTemplate(_:) — Apple
- Install Swift — macOS — Swift.org
- ISO8601DateFormatter formatOptions — Apple
- RFC 3339: Date and Time on the Internet: Timestamps — RFC Editor
- RFC 9557: Date and Time on the Internet: Timestamps with Additional Information — RFC Editor