I'm making a journal app where the user can edit the date time label. When the user taps on the label, it brings up a UIDatePicker. I want to make it so that when they save the Date, and if it's for "Today", then the label won't update to show today's date and will instead show the word "Today". This is something I've seen in Calendar, Journal, Fitness, and any other app that lets the user edit the entry log date.
It shows correctly when the user initially opens the view and sees the current date and time (programmatic UI):
let dateTimePicker: UIDatePicker = {
let picker = UIDatePicker()
picker.datePickerMode = .dateAndTime
picker.timeZone = NSTimeZone.local
picker.backgroundColor = UIColor.white
return picker
}()
let dateTimeLabel: UILabel = {
let now = Date()
let dateFormatter = DateFormatter()
dateFormatter.locale = Locale(identifier: "en_US")
dateFormatter.setLocalizedDateFormatFromTemplate("h:mm")
let label = UILabel(frame: CGRect(x: 0, y: 0, width: 200, height: 21))
label.attributedText = NSAttributedString(string: "Today, " + dateFormatter.string(from: now), attributes:[.underlineStyle: NSUnderlineStyle.single.rawValue])
return label
}()
The Date Picker opens as a popover. When the user clicks "Cancel", the date and time remains the same. When the user changes the date and/or time and clicks "Save", dateTimeLabel
updates accordingly. However, if it shows "Today, ___" and the user clicks "Save", then the label updates it to the current date.
Here's what I've tried:
@objc func saveTapped() {
let dateFormatter = DateFormatter()
dateFormatter.locale = Locale(identifier: "en_US")
let now = Date()
if dateTimePicker.date == now {
dateFormatter.setLocalizedDateFormatFromTemplate("h:mm")
dateTimeLabel.text = "Today, " + dateFormatter.string(from: now)
} else {
dateFormatter.setLocalizedDateFormatFromTemplate("MMMd h:mm")
dateTimeLabel.text = dateFormatter.string(from: dateTimePicker.date)
}
removePopoverView()
}
Gif to show what it currently is doing (I want it to show "Today" instead of "Apr 17" on dateTimeLabel
when user clicks "save" https://makeagif.com/i/v9mrKs
You can use Calendar method isDateInToday
to check if a date is in same day as today:
if Calendar.current.isDateInToday(dateTimePicker.date) {
// your code ...
} else if Calendar.current.isDateInYesterday(dateTimePicker.date) {
// your code ...
} else {
// your code ...
}
Note that DateFormatter
has a property called doesRelativeDateFormatting
exactly for this purpose. You just need to set it to true and it would take care of it for you with the advantage of displaying a localized string:
let date1 = DateComponents(calendar: .current, year: 2020, month: 4, day: 18, hour: 1).date!
let date2 = DateComponents(calendar: .current, year: 2020, month: 4, day: 17, hour: 23).date!
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .medium
dateFormatter.timeStyle = .short
dateFormatter.doesRelativeDateFormatting = true
dateFormatter.string(for: date1) // "Today at 1:00 AM"
dateFormatter.string(for: date2) // "Yesterday at 11:00 PM"