A cute little bug

Handling date and time in Go

I have been working on https://rentobase.com - a rental property management SaaS.

One of the features is the ability to record a rental income collection.

There are two important date atrributes things that you have to record:

  • the date when the rental payment goes into effect
  • the date when the rental payment becomes due.

How do you do this simplistically?

  • Validate that the start date is not in the past.
  • Validate that the end date is not in the past as well.
  • Check that the end date and start date are not the same.

What was I doing?

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
startDate, _ := time.Parse("2006-01-02", req.StartDate)
endDate, _ := time.Parse("2006-01-02", req.EndDate)

if startDate.Before(time.Now()) || endDate.Before(time.Now()) {
	c.JSON(http.StatusBadRequest, gin.H{"message": "Dates cannot be in the past"})
	return
}   

if startDate.After(endDate) {
	c.JSON(http.StatusBadRequest, gin.H{"message": "Start date cannot be after end date"})
	return
}

Here’s where it gets interesting. If you validate using the above code, you will get a false negative because startDate.Before(time.Now()) will return false if startDate is today.

I spent quite a chunk of my afternoon wondering why this was the case.

The fix is quite simple. Truncate the current time to midnight using time.Now().Truncate(24 * time.Hour) to compare dates at the day level rather than exact timestamps.

1
2
3
4
5
6
7
8
startDate, _ := time.Parse("2006-01-02", req.StartDate)
	endDate, _ := time.Parse("2006-01-02", req.EndDate)

	currentDate := time.Now().Truncate(24 * time.Hour)
	if startDate.Before(currentDate) {
		//throw error
		return
	}

There you have it!