diff --git a/Manito/Manito.xcodeproj/project.pbxproj b/Manito/Manito.xcodeproj/project.pbxproj index f90823f65..8a4ced9e0 100644 --- a/Manito/Manito.xcodeproj/project.pbxproj +++ b/Manito/Manito.xcodeproj/project.pbxproj @@ -25,6 +25,7 @@ 395402D42AAF0BC5003F3012 /* UIViewController+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 395402D32AAF0BC5003F3012 /* UIViewController+Extension.swift */; }; 395B5BC22A25E20000CE1420 /* DetailWaitViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 395B5BC12A25E20000CE1420 /* DetailWaitViewModel.swift */; }; 395B5BCC2A2F6A9700CE1420 /* DetailWaitViewModelTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 395B5BCB2A2F6A9700CE1420 /* DetailWaitViewModelTest.swift */; }; + 3962803E2B0CEC8600B0DC4B /* TimeInterval+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3962803D2B0CEC8600B0DC4B /* TimeInterval+Extension.swift */; }; 39632A282AD81F2E00A6E61D /* DetailWaitUsecaseTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39632A272AD81F2E00A6E61D /* DetailWaitUsecaseTest.swift */; }; 39632A2B2AD842A800A6E61D /* DetailWaitUsecaseError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39632A2A2AD842A800A6E61D /* DetailWaitUsecaseError.swift */; }; 39632A732AF0DC2E00A6E61D /* DetailEditViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39632A722AF0DC2E00A6E61D /* DetailEditViewModel.swift */; }; @@ -294,6 +295,7 @@ 395402D32AAF0BC5003F3012 /* UIViewController+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIViewController+Extension.swift"; sourceTree = ""; }; 395B5BC12A25E20000CE1420 /* DetailWaitViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DetailWaitViewModel.swift; sourceTree = ""; }; 395B5BCB2A2F6A9700CE1420 /* DetailWaitViewModelTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DetailWaitViewModelTest.swift; sourceTree = ""; }; + 3962803D2B0CEC8600B0DC4B /* TimeInterval+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TimeInterval+Extension.swift"; sourceTree = ""; }; 39632A272AD81F2E00A6E61D /* DetailWaitUsecaseTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DetailWaitUsecaseTest.swift; sourceTree = ""; }; 39632A2A2AD842A800A6E61D /* DetailWaitUsecaseError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DetailWaitUsecaseError.swift; sourceTree = ""; }; 39632A722AF0DC2E00A6E61D /* DetailEditViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DetailEditViewModel.swift; sourceTree = ""; }; @@ -1364,6 +1366,7 @@ B5E1F2AD285B2917006D880B /* Int+RandomNumber.swift */, 39C957CF2879521400A04A2B /* String+DateFormatter.swift */, 39C957D12879523200A04A2B /* Date+Extension.swift */, + 3962803D2B0CEC8600B0DC4B /* TimeInterval+Extension.swift */, ); path = Type; sourceTree = ""; @@ -2245,6 +2248,7 @@ 398B1C9B29F10B0300DEFCEC /* DetailEditView.swift in Sources */, B50B1AFD2856C3500080992C /* SendLetterTextView.swift in Sources */, B5A085F42A9733A700C8A98D /* LoginDTO.swift in Sources */, + 3962803E2B0CEC8600B0DC4B /* TimeInterval+Extension.swift in Sources */, B53A35D02A97194D00B720BC /* TokenRepositoryImpl.swift in Sources */, B5706BF629B9D4650093D198 /* GuideView.swift in Sources */, B50B1B41285B048A0080992C /* OpenManittoViewController.swift in Sources */, diff --git a/Manito/Manito/Screens/Detail-Wait/DetailEditViewController.swift b/Manito/Manito/Screens/Detail-Wait/DetailEditViewController.swift index 06e773a1b..9cde8b2a5 100644 --- a/Manito/Manito/Screens/Detail-Wait/DetailEditViewController.swift +++ b/Manito/Manito/Screens/Detail-Wait/DetailEditViewController.swift @@ -52,9 +52,8 @@ final class DetailEditViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() self.setupPresentationController() - self.configureDelegation() self.bindViewModel() - self.bindCancelButton() + self.bindUI() } // MARK: - func @@ -64,10 +63,6 @@ final class DetailEditViewController: UIViewController { self.isModalInPresentation = true } - private func configureDelegation() { - self.detailEditView.configureCalendarDelegate(self) - } - private func setupRoomInfoView(roomInfo: RoomInfo) { let startDate = roomInfo.roomInformation.startDate let endDate = roomInfo.roomInformation.endDate @@ -161,12 +156,18 @@ final class DetailEditViewController: UIViewController { .store(in: &self.cancellable) } - private func bindCancelButton() { + private func bindUI() { self.detailEditView.cancelButtonPublisher .sink(receiveValue: { [weak self] _ in self?.dismiss(animated: true) }) .store(in: &self.cancellable) + + self.detailEditView.calendarView.startDateTapPublisher.combineLatest(self.detailEditView.calendarView.endDateTapPublisher) + .sink(receiveValue: { [weak self] startText, endText in + self?.detailEditView.setupChangeButton(startText != "" && endText != "") + }) + .store(in: &self.cancellable) } } @@ -194,9 +195,3 @@ extension DetailEditViewController: UIAdaptivePresentationControllerDelegate { self.presentationControllerDidAttemptToDismissAlert() } } - -extension DetailEditViewController: CalendarDelegate { - func detectChangeButton(_ value: Bool) { - self.detailEditView.setupChangeButton(value) - } -} diff --git a/Manito/Manito/Screens/Detail-Wait/UIComponent/CalendarView.swift b/Manito/Manito/Screens/Detail-Wait/UIComponent/CalendarView.swift index 1d58e0843..31628a9ce 100644 --- a/Manito/Manito/Screens/Detail-Wait/UIComponent/CalendarView.swift +++ b/Manito/Manito/Screens/Detail-Wait/UIComponent/CalendarView.swift @@ -11,10 +11,6 @@ import UIKit import FSCalendar import SnapKit -protocol CalendarDelegate: AnyObject { - func detectChangeButton(_ value: Bool) -} - final class CalendarView: UIView { private enum CalendarMoveType { @@ -66,18 +62,12 @@ final class CalendarView: UIView { // MARK: - property private var selectStartDate: Date = Date() - private let oneDayInterval: TimeInterval = 86400 - private let sevenDaysInterval: TimeInterval = 604800 - var changeButtonState: ((Bool) -> ())? - var startDateText: String = "" - var endDateText: String = "" - private var tempStartDateText: String = "" - private var tempEndDateText: String = "" + private var startDateText: String = "" + private var endDateText: String = "" var isFirstTap: Bool = false - private weak var delegate: CalendarDelegate? - let startDateTapPublisher = PassthroughSubject() - let endDateTapPublisher = PassthroughSubject() + let startDateTapPublisher: PassthroughSubject = PassthroughSubject() + let endDateTapPublisher: PassthroughSubject = PassthroughSubject() // MARK: - init @@ -121,23 +111,13 @@ final class CalendarView: UIView { } self.previousButton.addAction(action, for: .touchUpInside) } + private func setupNextButton() { let action = UIAction { [weak self] _ in self?.changeMonth(with: CalendarMoveType.next) } self.nextButton.addAction(action, for: .touchUpInside) } - - func configureCalendarDelegate(_ delegate: CalendarDelegate) { - self.delegate = delegate - } - - func setupButtonState() { - let hasDate = self.tempStartDateText != "" && self.tempEndDateText != "" - self.delegate?.detectChangeButton(hasDate) - // FIXME: - delegate로 통일 후 삭제해야함 - self.changeButtonState?(hasDate) - } private func setupDelegation() { self.calendar.delegate = self @@ -154,65 +134,79 @@ final class CalendarView: UIView { } func setupDateRange() { - self.startDateTapPublisher.send("20\(self.startDateText)") - self.endDateTapPublisher.send("20\(self.endDateText)") - guard let startDate = self.startDateText.toDefaultDate else { return } - guard let endDate = self.endDateText.toDefaultDate else { return } - self.setupCalendarRange(startDate: startDate, endDate: endDate) + self.startDateTapPublisher.send(self.startDateText) + self.endDateTapPublisher.send(self.endDateText) + guard let startDate = self.startDateText.toDefaultDate, + let endDate = self.endDateText.toDefaultDate else { return } + self.setupInitialCalendarRange(startDate: startDate, endDate: endDate) } - private func setupCalendarRange(startDate: Date, endDate: Date) { + private func setupInitialCalendarRange(startDate: Date, endDate: Date) { self.calendar.select(startDate) self.calendar.select(endDate) self.setDateRange() } - func setDateRange() { + private func setDateRange() { guard self.countDateRange() <= 7 else { return } let isFirstClickPastDate = self.calendar.selectedDates[0] < self.calendar.selectedDates[1] if isFirstClickPastDate { - self.setSelecteDate(startIndex: 0, + self.setSelectedDate(startIndex: 0, endIndex: 1) } else { - self.setSelecteDate(startIndex: 1, + self.setSelectedDate(startIndex: 1, endIndex: 0) } } - func setSelecteDate(startIndex: Int, endIndex: Int) { + private func setSelectedDate(startIndex: Int, endIndex: Int) { var startDate = self.calendar.selectedDates[startIndex] while startDate < self.calendar.selectedDates[endIndex] { guard let addDate = Calendar.current.date(byAdding: .day, value: 1, to: startDate) else { return } self.calendar.select(addDate) - startDate += self.oneDayInterval + startDate += .oneDayInterval } - self.tempStartDateText = self.calendar.selectedDates[startIndex].toDefaultString - self.tempEndDateText = self.calendar.selectedDates[endIndex].toDefaultString + self.startDateText = self.calendar.selectedDates[startIndex].toDefaultString + self.endDateText = self.calendar.selectedDates[endIndex].toDefaultString } - func countDateRange() -> Int { + private func countDateRange() -> Int { let isFirstClickPastDate = self.calendar.selectedDates[0] < self.calendar.selectedDates[1] let selectdDate = isFirstClickPastDate ? self.calendar.selectedDates[1].timeIntervalSince(self.calendar.selectedDates[0]) : self.calendar.selectedDates[0].timeIntervalSince(self.calendar.selectedDates[1]) - let dateRangeCount = selectdDate / 86400 + let dateRangeCount = selectdDate / .oneDayInterval return Int(dateRangeCount) + 1 } - func getTempStartDate() -> String { - return self.tempStartDateText + func getStartDate() -> String { + return self.startDateText } - func getTempEndDate() -> String { - return self.tempEndDateText + func getEndDate() -> String { + return self.endDateText + } + + func setStartDateText(_ text: String) { + self.startDateText = text + } + + func setEndDateText(_ text: String) { + self.endDateText = text + } + + private func showAlertOverDateSelect() { + self.viewController?.makeAlert(title: TextLiteral.Common.Calendar.maxAlertTitle.localized(), + message: TextLiteral.Common.Calendar.maxDateContent.localized()) } } extension CalendarView: FSCalendarDelegate { + /// 캘린더의 날짜를 선택했을 때 실행되는 함수. func calendar(_ calendar: FSCalendar, didSelect date: Date, at monthPosition: FSCalendarMonthPosition) { self.isFirstTap = true let isCreatedRoomOnlySelectedStartDate = calendar.selectedDates.count == 1 @@ -227,16 +221,15 @@ extension CalendarView: FSCalendarDelegate { DispatchQueue.main.async { calendar.deselect(date) } - self.viewController?.makeAlert(title: TextLiteral.Common.Calendar.maxAlertTitle.localized(), - message: TextLiteral.Common.Calendar.maxDateContent.localized()) + self.showAlertOverDateSelect() } else { - self.tempEndDateText = date.toDefaultString + self.endDateText = date.toDefaultString self.setDateRange() calendar.reloadData() } } else if isReclickedStartDate { - self.tempStartDateText = date.toDefaultString - self.tempEndDateText = "" + self.startDateText = date.toDefaultString + self.endDateText = "" (calendar.selectedDates).forEach { calendar.deselect($0) } @@ -245,13 +238,14 @@ extension CalendarView: FSCalendarDelegate { calendar.reloadData() } - self.startDateTapPublisher.send(self.getTempStartDate()) - self.endDateTapPublisher.send(self.getTempEndDate()) - self.setupButtonState() + self.startDateTapPublisher.send(self.getStartDate()) + self.endDateTapPublisher.send(self.getEndDate()) } - + + /// 이미 선택 되어있는 날짜를 클릭했을 때 실행되는 함수. func calendar(_ calendar: FSCalendar, didDeselect date: Date, at monthPosition: FSCalendarMonthPosition) { - self.tempEndDateText = "" + self.endDateText = "" + self.endDateTapPublisher.send("") self.isFirstTap = true (calendar.selectedDates).forEach { calendar.deselect($0) @@ -259,11 +253,11 @@ extension CalendarView: FSCalendarDelegate { self.selectStartDate = date calendar.select(date) calendar.reloadData() - self.setupButtonState() } + /// 선택할 수 없는 날짜 지정 함수 func calendar(_ calendar: FSCalendar, shouldSelect date: Date, at monthPosition: FSCalendarMonthPosition) -> Bool { - if date < Date() - self.oneDayInterval { + if date < Date() - .oneDayInterval { self.viewController?.makeAlert(title: TextLiteral.Common.Calendar.pastAlertTitle.localized(), message: TextLiteral.Common.Calendar.pastAlertMessage.localized()) return false @@ -272,9 +266,10 @@ extension CalendarView: FSCalendarDelegate { } } + /// 캘린더의 숫자 색에 대한 함수 func calendar(_ calendar: FSCalendar, appearance: FSCalendarAppearance, titleDefaultColorFor date: Date) -> UIColor? { - let isBeforeToday = date < Date() - self.oneDayInterval - let isAWeekBeforeAfter = date < self.selectStartDate + self.sevenDaysInterval && date > self.selectStartDate - self.sevenDaysInterval + let isBeforeToday = date < Date() - .oneDayInterval + let isAWeekBeforeAfter = date < self.selectStartDate + .sevenDaysInterval && date > self.selectStartDate - .sevenDaysInterval let isDoneSelectedDate = calendar.selectedDates.count > 2 if isBeforeToday { return .grey004.withAlphaComponent(0.4) diff --git a/Manito/Manito/Screens/Detail-Wait/View/DetailEditView.swift b/Manito/Manito/Screens/Detail-Wait/View/DetailEditView.swift index 8e735a1db..8f7b4cb80 100644 --- a/Manito/Manito/Screens/Detail-Wait/View/DetailEditView.swift +++ b/Manito/Manito/Screens/Detail-Wait/View/DetailEditView.swift @@ -101,7 +101,6 @@ final class DetailEditView: UIView, BaseViewType { // MARK: - property - private weak var calendarDelegate: CalendarDelegate? private let editMode: EditMode private var maximumMemberCount: Int? { willSet(count) { @@ -264,26 +263,23 @@ final class DetailEditView: UIView, BaseViewType { func setupDateRange(from startDateString: String, to endDateString: String) { guard let startDate = startDateString.toDefaultDate else { return } if startDate.isPast { - let fiveDaysInterval: TimeInterval = 86400 * 4 - self.calendarView.startDateText = Date().toDefaultString - self.calendarView.endDateText = (Date() + fiveDaysInterval).toDefaultString + let fiveDaysInterval: TimeInterval = .oneDayInterval * 4 + + self.calendarView.setStartDateText(Date().toFullString) + self.calendarView.setEndDateText((Date() + fiveDaysInterval).toFullString) } else { - self.calendarView.startDateText = startDateString - self.calendarView.endDateText = endDateString + self.calendarView.setStartDateText(startDateString) + self.calendarView.setEndDateText(endDateString) } self.calendarView.setupDateRange() } - func configureCalendarDelegate(_ delegate: CalendarDelegate) { - self.calendarView.configureCalendarDelegate(delegate) - } - private func bindChangeButton() { self.changeButton.tapPublisher.sink(receiveValue: { [weak self] _ in self?.changeButtonSubject.send(CreatedRoomInfoRequestDTO(title: self?.roomTitle ?? "", capacity: self?.sliderPublisher.value ?? 0, - startDate: "20\(self?.calendarView.getTempStartDate() ?? "")", - endDate: "20\(self?.calendarView.getTempEndDate() ?? "")")) + startDate: "20\(self?.calendarView.getStartDate() ?? "")", + endDate: "20\(self?.calendarView.getEndDate() ?? "")")) }) .store(in: &self.cancellable) } diff --git a/Manito/Manito/Util/Extension/Type/Date+Extension.swift b/Manito/Manito/Util/Extension/Type/Date+Extension.swift index 17f7358d5..4c939a168 100644 --- a/Manito/Manito/Util/Extension/Type/Date+Extension.swift +++ b/Manito/Manito/Util/Extension/Type/Date+Extension.swift @@ -12,13 +12,13 @@ extension Date { var isToday: Bool { let now = Date() let distance = self.distance(to: now) - return distance > 0 && distance < 86400 + return distance > 0 && distance < .oneDayInterval } /// 해당 날짜가 지난날인지 var isPast: Bool { let distance = self.distance(to: Date()) - return distance > 86400 + return distance > .oneDayInterval } /// Date 값을 yy.MM.dd 형식의 String 값으로 변환 diff --git a/Manito/Manito/Util/Extension/Type/TimeInterval+Extension.swift b/Manito/Manito/Util/Extension/Type/TimeInterval+Extension.swift new file mode 100644 index 000000000..a9d3022cf --- /dev/null +++ b/Manito/Manito/Util/Extension/Type/TimeInterval+Extension.swift @@ -0,0 +1,13 @@ +// +// TimeInterval+Extension.swift +// Manito +// +// Created by Mingwan Choi on 11/21/23. +// + +import Foundation + +extension TimeInterval { + static let oneDayInterval: TimeInterval = 86400 + static let sevenDaysInterval: TimeInterval = 604800 +} diff --git a/Manito/ManitoTests/Domain/Entity/RoomInfoTest.swift b/Manito/ManitoTests/Domain/Entity/RoomInfoTest.swift index 514864dce..4ed5e33fd 100644 --- a/Manito/ManitoTests/Domain/Entity/RoomInfoTest.swift +++ b/Manito/ManitoTests/Domain/Entity/RoomInfoTest.swift @@ -42,9 +42,8 @@ final class RoomInfoTest: XCTestCase { func test_canStart_방장이아니고_시작인원이4명이하고_시작날짜가오늘일때() { // given - let oneTimeInterval: TimeInterval = 86400 let todayString = Date().toFullString - let endDate = todayString.toDefaultDate! + oneTimeInterval + let endDate = todayString.toDefaultDate! + .oneDayInterval let endDateString = endDate.toFullString let sut = RoomInfo( roomInformation: RoomListItem(id: 0, @@ -96,9 +95,8 @@ final class RoomInfoTest: XCTestCase { func test_canStart_방장이아니고_시작인원이4명이상이고_시작날짜가오늘일때() { // given - let oneTimeInterval: TimeInterval = 86400 let todayString = Date().toFullString - let endDate = todayString.toDefaultDate! + oneTimeInterval + let endDate = todayString.toDefaultDate! + .oneDayInterval let endDateString = endDate.toFullString let sut = RoomInfo( roomInformation: RoomListItem(id: 0, @@ -150,9 +148,8 @@ final class RoomInfoTest: XCTestCase { func test_canStart_방장이고_시작인원이4명이하고_시작날짜가오늘일때() { // given - let oneTimeInterval: TimeInterval = 86400 let todayString = Date().toFullString - let endDate = todayString.toDefaultDate! + oneTimeInterval + let endDate = todayString.toDefaultDate! + .oneDayInterval let endDateString = endDate.toFullString let sut = RoomInfo( roomInformation: RoomListItem(id: 0, @@ -204,9 +201,8 @@ final class RoomInfoTest: XCTestCase { func test_canStart_방장이고_시작인원이4명이상이고_시작날짜가오늘일때() { // given - let oneTimeInterval: TimeInterval = 86400 let todayString = Date().toFullString - let endDate = todayString.toDefaultDate! + oneTimeInterval + let endDate = todayString.toDefaultDate! + .oneDayInterval let endDateString = endDate.toFullString let sut = RoomInfo( roomInformation: RoomListItem(id: 0, diff --git a/Manito/ManitoTests/Domain/Entity/RoomListItemTest.swift b/Manito/ManitoTests/Domain/Entity/RoomListItemTest.swift index aaa1147a6..0d89e2388 100644 --- a/Manito/ManitoTests/Domain/Entity/RoomListItemTest.swift +++ b/Manito/ManitoTests/Domain/Entity/RoomListItemTest.swift @@ -69,7 +69,7 @@ final class RoomListItemTest: XCTestCase { func test_isStartDatePast_오늘날짜에대해_올바르게_반환하는가() { // given let today = Date() - let ondDay: TimeInterval = 86400 + let ondDay: TimeInterval = .oneDayInterval let todayAfterFiveDays = Date() + ondDay let todayString = today.toFullString let endDateString = todayAfterFiveDays.toFullString diff --git a/Manito/ManitoTests/Domain/Usecase/DetailEditUsecaseTest.swift b/Manito/ManitoTests/Domain/Usecase/DetailEditUsecaseTest.swift index 49d2fd7d6..eb74330d3 100644 --- a/Manito/ManitoTests/Domain/Usecase/DetailEditUsecaseTest.swift +++ b/Manito/ManitoTests/Domain/Usecase/DetailEditUsecaseTest.swift @@ -48,8 +48,7 @@ final class DetailEditUsecaseTest: XCTestCase { func test_vaildStartDateIsNotPast함수에_내일날짜가_들어갔을때() { // given - let oneDay: TimeInterval = 86400 - let tomorrow = (Date() + oneDay).toFullString + let tomorrow = (Date() + .oneDayInterval).toFullString // when let sut = self.mockUsecase.vaildStartDateIsNotPast(startDate: tomorrow) // then diff --git a/Manito/ManitoTests/Util/Extension/Type/Date+ExtensionTest.swift b/Manito/ManitoTests/Util/Extension/Type/Date+ExtensionTest.swift index 73799e9b6..4346fe3d4 100644 --- a/Manito/ManitoTests/Util/Extension/Type/Date+ExtensionTest.swift +++ b/Manito/ManitoTests/Util/Extension/Type/Date+ExtensionTest.swift @@ -29,10 +29,9 @@ final class Date_ExtensionTest: XCTestCase { func test_isToday_과거날짜에_올바르게_반환하는가() { // given - let oneTimeInterval: TimeInterval = 86400 let dateString = Date().toFullString let today = dateString.toFullDate! - let sut = today - oneTimeInterval + let sut = today - .oneDayInterval // when let isToday = sut.isToday @@ -43,10 +42,9 @@ final class Date_ExtensionTest: XCTestCase { func test_isToday_미래날짜에_올바르게_반환하는가() { // given - let oneTimeInterval: TimeInterval = 86400 let dateString = Date().toFullString let today = dateString.toFullDate! - let sut = today + oneTimeInterval + let sut = today + .oneDayInterval // when let isToday = sut.isToday @@ -63,10 +61,9 @@ final class Date_ExtensionTest: XCTestCase { func test_isPast_과거날짜에_올바르게_반환하는가() { // given - let oneTimeInterval: TimeInterval = 86400 let dateString = Date().toFullString let today = dateString.toFullDate! - let sut = today - oneTimeInterval + let sut = today - .oneDayInterval // when let isPast = sut.isPast @@ -77,10 +74,9 @@ final class Date_ExtensionTest: XCTestCase { func test_isPast_미래날짜에_올바르게_반환하는가() { // given - let oneTimeInterval: TimeInterval = 86400 let dateString = Date().toFullString let today = dateString.toFullDate! - let sut = today + oneTimeInterval + let sut = today + .oneDayInterval // when let isPast = sut.isPast