Start learning free

LESSON 165 OF 173 · BACKEND: BACKEND WITH AI

Dates the AI Got Wrong

Practice

An AI assistant wrote GET /orders?since=… for the shop: the orders placed on or after a date. Customers type the date day first, like 18/04/2026. The database keeps each order's date year first, like 2026-04-18. The AI compared the two texts as they are:

app.HandleFunc("GET /orders", func(w http.ResponseWriter, r *http.Request) {
    since := r.URL.Query().Get("since")
    rows, _ := db.Query("SELECT * FROM orders")
    defer rows.Close()
    result := []Order{}
    for rows.Next() {
        var o Order
        rows.Scan(&o.ID, &o.CustomerID, &o.Ordered, &o.Status)
        if o.Ordered >= since {
            result = append(result, o)
        }
    }
    writeJSON(w, 200, result)
})

Go compares strings byte by byte, and the first difference decides. "2026-03-02" >= "18/04/2026" is true, because "2" comes after "1". So since=18/04/2026 answered all 7 orders and since=30/04/2026 answered none. The impossible 31/04/2026 got 200 and an empty list, and a request without since compared every date with "" and got all 7 orders.

The fix: turn each text into a real time with time.Parse(layout, text), then compare times. Go writes a layout with one reference date, 2 January 2006: 02 is the day, 01 the month and 2006 the four-digit year. A text that doesn't fit the layout, or a day that doesn't exist, gives an error:

d, _ := time.Parse("02/01/2006", "07/05/2026")
fmt.Println(d.Day(), int(d.Month()), d.Year())   // 7 5 2026
_, err := time.Parse("02/01/2006", "30/02/2026")
fmt.Println(err)   // parsing time "30/02/2026": day out of range

Times compare with methods: a.Before(b) is true when a is earlier, and a.After(b) when it is later. The requests and the answers your route must give:

GET /orders?since=18/04/2026  →  200  [{"id": 4, "customer_id": 3, "ordered": "2026-04-18", "status": "shipped"}, …]   (orders 4 to 7)
GET /orders?since=30/04/2026  →  200  [{"id": 5, "customer_id": 4, "ordered": "2026-05-07", "status": "paid"}, …]   (orders 5 to 7)
GET /orders?since=01/06/2026  →  200  []
GET /orders?since=31/04/2026  →  400  {"error": "since must be a date like 18/04/2026"}
GET /orders  →  400  {"error": "since must be a date like 18/04/2026"}

Your task: rewrite the orders handler. Read since as a time with the layout "02/01/2006", and answer 400 with the error when it isn't one. Read each order's Ordered with "2006-01-02", and answer the orders placed on or after since.


Assignment
Follow the Coding Tutorial to rewrite the orders handler so it compares real times instead of texts.


Hint
Check the err of time.Parse right away, answer 400 and return. A missing since reads as "", which time.Parse refuses too, so it lands in the same if. "On or after" means "not before", so an order placed on the since day itself is kept.


STEP 1 OF 12
    Ctrl + Enter to check