Swift: How many Friday the 13th
Video: Swift: How many Friday the 13th by Taught by Celeste AI - AI Coding Coach
Counting Friday the 13ths in Swift with Copilot
Iterate the 12 months, build a
Datefor the 13th, checkweekday == 6. A small calendar-arithmetic puzzle that demos how a one-line Copilot comment can produce a complete, correct function.
This episode is the odd one out — the playlist is "GitHub Copilot with Kotlin," but episode 1 happens to use Swift. The principle is identical: write a precise comment describing what you want, accept the Copilot suggestion, run it.
The task
Count how many Fridays fell on the 13th in a given year. For 2023, the answer is two (January and October).
The Copilot prompt
In an empty Swift file, type:
import Foundation
// Count how many Friday the 13ths there are in a given year
func countFridayThe13ths(in year: Int) -> Int {
Copilot offers the function body. Hit Tab to accept.
The signature line is the most important thing here. in year: Int tells Copilot the input parameter; -> Int tells it the return type. The triple-slash comment phrasing — "Count how many Friday the 13ths there are in a given year" — directly maps to the body Copilot generates.
The generated code
import Foundation
func countFridayThe13ths(in year: Int) -> Int {
let calendar = Calendar.current
var count = 0
for month in 1...12 {
var components = DateComponents()
components.year = year
components.month = month
components.day = 13
if let date = calendar.date(from: components) {
let weekday = calendar.component(.weekday, from: date)
if weekday == 6 { // 6 = Friday in Gregorian calendar
count += 1
}
}
}
return count
}
let year = 2023
let fridayThe13ths = countFridayThe13ths(in: year)
print("Number of Friday the 13ths in \(year): \(fridayThe13ths)")
Walkthrough
Five pieces.
1. The calendar. Calendar.current is the user's locale calendar — usually Gregorian, but could be Buddhist, Hebrew, Islamic, etc., depending on system settings. For Friday-the-13th calculations specifically, you might want Gregorian explicitly: Calendar(identifier: .gregorian).
2. The month loop. for month in 1...12 iterates January through December. Swift's 1...12 is a closed range — both endpoints inclusive.
3. Date construction. DateComponents is the building-block type for "I want the date with year=2023, month=1, day=13." Setting individual fields then calling calendar.date(from:) produces a real Date, or nil if the components describe an impossible date.
4. Weekday extraction. calendar.component(.weekday, from: date) returns an integer for the day of the week. The mapping is 1=Sunday, 2=Monday, ..., 6=Friday, 7=Saturday in the default locale — this is the Apple convention, not ISO 8601.
If you've come from Java/Kotlin where DayOfWeek.FRIDAY is 5 (ISO: Monday=1, Sunday=7), the off-by-one bites you. Swift's calendar API is one-based and Sunday-first by default.
5. The count accumulator. Increment whenever the weekday matches.
A more idiomatic version
The verbose loop body can collapse if you trust the API:
func countFridayThe13ths(in year: Int) -> Int {
let calendar = Calendar.current
return (1...12).filter { month in
var components = DateComponents()
components.year = year
components.month = month
components.day = 13
let date = calendar.date(from: components)!
return calendar.component(.weekday, from: date) == 6
}.count
}
(1...12).filter { ... }.count reads as "of the 12 months, how many satisfy the predicate." More functional, less imperative.
The ! force-unwrap is safe here — January 13th of any valid year is always a real date. For input years we trust, this is fine. For year=0 or huge negative years, paranoid code would handle the nil.
Refining the Copilot comment
Some prompts produce better code than others. Compare:
// count Friday the 13ths— Copilot might guess. Sometimes okay, sometimes wild.// Count how many Friday the 13ths there are in a given year using Calendar— explicit. Copilot is much more likely to useCalendarandDateComponents.// Return the number of Friday the 13ths in 'year' as an Int. Use Foundation's Calendar.— even better. Specifies imports and return type.
The pattern: be specific about the API surface you want. Copilot reads your comment as a spec, and a spec that names the framework gets a focused implementation.
Edge cases
- Year 1582 and earlier. The Gregorian calendar wasn't adopted until 1582.
Calendar(identifier: .gregorian)uses the proleptic version (extends Gregorian back in time), which gives the "wrong" answer for historical research. - Dates before year 1. Swift's
Calendarhandles year 0 and negatives but the semantics differ from common conventions. - Time zones.
DateComponentshere doesn't set.timeZone. The default is the calendar's time zone, which is the user's local zone. For a deterministic answer, pin the time zone:components.timeZone = TimeZone(identifier: "UTC").
In Kotlin
For symmetry, here's the same task in Kotlin:
import java.time.LocalDate
import java.time.DayOfWeek
fun countFridayThe13ths(year: Int): Int {
return (1..12).count { month ->
LocalDate.of(year, month, 13).dayOfWeek == DayOfWeek.FRIDAY
}
}
fun main() {
println(countFridayThe13ths(2023)) // 2
}
java.time.LocalDate (Java 8+) is much cleaner than the Swift DateComponents ceremony. .dayOfWeek returns a typed enum (DayOfWeek.FRIDAY), no magic numbers.
Common mistakes
Off-by-one weekday. Apple uses 1=Sunday, ISO uses 1=Monday. If the answer's wrong, this is the first thing to check.
Force-unwrapping calendar.date(from:) blindly. For the 13th of a real month it's safe, but for general date construction the nil case is real.
Forgetting the time zone. A date built without an explicit timezone follows whatever the calendar defaults to. Tests can fail when run from different machines.
Trusting Calendar.current. It can be Buddhist, Hebrew, Persian, etc. For "weekday" calculations specifically, force .gregorian.
Mixing up DateComponents and Date. DateComponents is a recipe; Date is an actual point in time. calendar.date(from:) cooks the recipe into a Date.
What's next
Episode 2: Kotlin — moving "May" to the front of a list of months. A small sortedWith puzzle that shows how Copilot can read your intent from a single comment.
Recap
Build dates with DateComponents + Calendar.date(from:). Read weekday with calendar.component(.weekday, from:). Apple's calendar uses 1=Sunday, 6=Friday. For year-bounded queries, (1...12).filter { ... }.count is the functional one-liner. The Copilot prompt that worked: "Count how many Friday the 13ths there are in a given year." Be specific about the API you want — Copilot reads comments as specs.
Next episode: putting May at the front of a list.