Operator function '<' requires that 'Date' conform to 'StringProtocol'

Hi. I would like to add an if statement to my list that only shows items that are only seven days in the future from the current date, and 30 days in the future. This is how tasks should be sorted. So upcoming tasks in the next 7 days and as an extra list tasks in the next 30 days. But I always get this error ("Operator function '<' requires that 'Date' conform to 'StringProtocol'"), or is there another way to sort the list like this?

List {

                 Section(header: Text("Test1")){

                     ForEach(homeLists, id: \.id) { homeList in

                          if homeList.listdate < Date.now {

                              NavigationLink {

                               HomeTabView(homeList: homeList)

                                } label: {

The content of the list is then written in the label underneath.

Answered by darkpaw in 737511022

I think @Claude31's answer is helpful, but I personally would not do a String comparison for Dates. I think you should make sure listDate is a Date, not a String.

Here's a chunk of code that shows how the comparisons with Strings can be wrong if the format isn't always right:

let dateFormatter = DateFormatter()

struct ContentView: View {
    var body: some View {
        VStack {
	      		// Trying with YY/MM/dd Strings.
	      		// This works because the String goes highest number to lowest number, i.e. years then months then days.
	      		if("27/12/2022" < "28/11/2022") {
		        		Text("'27/12/2022' < '28/11/2022'")

	      		} else {
	        			Text("'27/12/2022' >= '28/11/2022'")
	      		}

	      		// Now try with a different date format, i.e. "dd/MM/yyyy".
	      		// This won't work because the 1st Dec 2022 is lower than the 2nd January 2022 because it begins with a 1.
	      		if("01/12/2022" < "02/01/2022") {
	        			Text("'01/12/2022' < '02/01/2022' = incorrect")

	      		} else {
	        			Text("'01/12/2022' >= '02/01/2022' = correct")
	      		}

	      		// Now try the comparison with Dates taken from Strings
	      		let date1String: String = "01/12/2022T15:00:00+0000"
	      		let date2String: String = "02/01/2022T15:00:00+0000"
	      		let date1Date: Date = getDateFromString(date1String)
	      		let date2Date: Date = getDateFromString(date2String)
	      		if(date1Date < date2Date) {
		        		Text("'01/12/2022' < '02/01/2022' = incorrect")

      			} else {
	        			Text("'01/12/2022' >= '02/01/2022' = correct")
	      		}
        }
    }

	func getDateFromString(_ dateString: String) -> Date {
		  dateFormatter.dateFormat = "dd/MM/yyyy'T'HH:mm:ssZ"
		  return dateFormatter.date(from: dateString)!
	}
}

You don't show enough code.

How is homeList.listdate defined ? Is it a Date ? Or a String ? With the error you get, it is probably defined as String, which causes the error.

So, 2 options:

  • define homeList.listdate as a Date
  • transform Date.now to a String format (in which case, it must be same format as homeList.listdate)
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "YY/MM/dd"  // If that is the format of homeList.listdate
let nowString = dateFormatter.string(from: Date.now)

You can now test:

   if homeList.listdate < nowString {
Accepted Answer

I think @Claude31's answer is helpful, but I personally would not do a String comparison for Dates. I think you should make sure listDate is a Date, not a String.

Here's a chunk of code that shows how the comparisons with Strings can be wrong if the format isn't always right:

let dateFormatter = DateFormatter()

struct ContentView: View {
    var body: some View {
        VStack {
	      		// Trying with YY/MM/dd Strings.
	      		// This works because the String goes highest number to lowest number, i.e. years then months then days.
	      		if("27/12/2022" < "28/11/2022") {
		        		Text("'27/12/2022' < '28/11/2022'")

	      		} else {
	        			Text("'27/12/2022' >= '28/11/2022'")
	      		}

	      		// Now try with a different date format, i.e. "dd/MM/yyyy".
	      		// This won't work because the 1st Dec 2022 is lower than the 2nd January 2022 because it begins with a 1.
	      		if("01/12/2022" < "02/01/2022") {
	        			Text("'01/12/2022' < '02/01/2022' = incorrect")

	      		} else {
	        			Text("'01/12/2022' >= '02/01/2022' = correct")
	      		}

	      		// Now try the comparison with Dates taken from Strings
	      		let date1String: String = "01/12/2022T15:00:00+0000"
	      		let date2String: String = "02/01/2022T15:00:00+0000"
	      		let date1Date: Date = getDateFromString(date1String)
	      		let date2Date: Date = getDateFromString(date2String)
	      		if(date1Date < date2Date) {
		        		Text("'01/12/2022' < '02/01/2022' = incorrect")

      			} else {
	        			Text("'01/12/2022' >= '02/01/2022' = correct")
	      		}
        }
    }

	func getDateFromString(_ dateString: String) -> Date {
		  dateFormatter.dateFormat = "dd/MM/yyyy'T'HH:mm:ssZ"
		  return dateFormatter.date(from: dateString)!
	}
}
Operator function '&lt;' requires that 'Date' conform to 'StringProtocol'
 
 
Q