It's that time of the year again~ yes, the beginning of the year!
In work scope, I'm keeping track of my tickets like this:
## 23.52: 18-29 Dec
List of tickets done
## 23.50: 4-15 Dec
List of tickets done
## 23.48: 20 Nov - 1 Dec
List of tickets done
## 23.02: 2-13 Jan
List of tickets done
23.02 refers to the year 2023 and week 2 and so on until week 52.
There must be a smarter way to generate it using Swift code right! Here's the snippet that I run in Swift playground
import UIKit
var df = DateFormatter()
df.dateFormat = "dd-MMM-yy"
var startDate = df.date(from: "2-Jan-23")!
let endDate = df.date(from: "7-Jan-24")!
var sprints: [String] = []
while startDate <= endDate {
let startSprint = startDate
let endSprint = Calendar.current.date(byAdding: .day, value: 11, to: startDate)!
let start = Calendar.current.dateComponents([.year, .day, .month], from: startSprint)
let end = Calendar.current.dateComponents([.day, .month, .weekOfYear], from: endSprint)
let startYear = String(start.year!).suffix(2)
var output = String(format: "## %@.%02d: ", String(startYear), end.weekOfYear ?? 0)
if start.month == end.month {
let monthName = Calendar.current.shortMonthSymbols[end.month!-1]
output += String(format: "%d-%d %@", start.day ?? 0, end.day ?? 0, monthName)
} else {
let startMonth = Calendar.current.shortMonthSymbols[start.month!-1]
let endMonth = Calendar.current.shortMonthSymbols[end.month!-1]
output += String(format: "%d %@ - %d %@", start.day ?? 0, startMonth, end.day ?? 0, endMonth)
}
startDate = Calendar.current.date(byAdding: .day, value: 14, to: startDate)!
sprints.append(output)
}
for s in sprints.reversed() {
print(s)
print("\n")
}
Here's the code breakdown.
Set a start and end date. I'm using DateFormatter to easily create 2 Date objects
The start of the sprint is set to the
startDate
while the end of the sprint is 11 days after that. For example, start on Monday, 2 January and end on Friday, 13 January
let startSprint = startDate
let endSprint = Calendar.current.date(byAdding: .day, value: 11, to: startDate)!
I need to split a date's components by year, day, month, and weekOfYear. The
weekOfYear
is taken from the end of the sprint date so it will be an even number.For the year, I only need the last 2 characters, which is 23. But because the dateComponents' year is an
Int?
, I need to convert it to String and use.suffix(2)
I'll begin the String output with format specifiers so it will construct something like
## 23.02:
let start = Calendar.current.dateComponents([.year, .day, .month], from: startSprint)
let end = Calendar.current.dateComponents([.day, .month, .weekOfYear], from: endSprint)
let startYear = String(start.year!).suffix(2)
var output = String(format: "## %@.%02d: ", String(startYear), end.weekOfYear ?? 0)
If a sprint happens in the same month, I want it to be displayed like 2-13 Jan. Otherwise, it should show 30 Jan - 10 Feb
DateComponents for the month returns another
Int?
, useCalendar.current.shortMonthSymbols[start.month!-1]
to get Jan, Feb, Mar, and so onAppend
output
to thesprints
String array
if start.month == end.month {
let monthName = Calendar.current.shortMonthSymbols[end.month!-1]
output += String(format: "%d-%d %@", start.day ?? 0, end.day ?? 0, monthName)
} else {
let startMonth = Calendar.current.shortMonthSymbols[start.month!-1]
let endMonth = Calendar.current.shortMonthSymbols[end.month!-1]
output += String(format: "%d %@ - %d %@", start.day ?? 0, startMonth, end.day ?? 0, endMonth)
}
startDate = Calendar.current.date(byAdding: .day, value: 14, to: startDate)!
sprints.append(output)
- Finally, I'll print it in reversed for my note's template!
for s in sprints.reversed() {
print(s)
print("\n")
}
Phew, that was some good exercise! Playing with Date is always fun and forgetful if you don't juggle with it every day.
Initially, it's easier to think forward but step 9 was added after realising that I should arrange my note in reverse, so that it's easy to add more documentation :)
Looking as the bird view of this year, it feels like I'm already going to end 2023 year again. One year is really fast as you only have 26 sprints!
// not counted, generated in case the sprint crosses another year
## 24.02: 1-12 Jan
## 23.52: 18-29 Dec
## 23.50: 4-15 Dec
## 23.48: 20 Nov - 1 Dec
## 23.46: 6-17 Nov
## 23.44: 23 Oct - 3 Nov
## 23.42: 9-20 Oct
## 23.40: 25 Sep - 6 Oct
## 23.38: 11-22 Sep
## 23.36: 28 Aug - 8 Sep
## 23.34: 14-25 Aug
## 23.32: 31 Jul - 11 Aug
## 23.30: 17-28 Jul
## 23.28: 3-14 Jul
## 23.26: 19-30 Jun
// mid of the year!
## 23.24: 5-16 Jun
## 23.22: 22 May - 2 Jun
## 23.20: 8-19 May
## 23.18: 24 Apr - 5 May
## 23.16: 10-21 Apr
## 23.14: 27 Mar - 7 Apr
## 23.12: 13-24 Mar
## 23.10: 27 Feb - 10 Mar
## 23.08: 13-24 Feb
## 23.06: 30 Jan - 10 Feb
## 23.04: 16-27 Jan
## 23.02: 2-13 Jan