Forum OpenACS Q&A: Response to datetime to "Nice Dates"

Collapse
Posted by Michael A. Cleverly on
Given the examples you gave, I wrote the following Tcl procedure that do what you want:

proc pretty_pg_date {pg_date} {
    set pgtime [clock scan $pg_date]
    set now    [ns_time]
    set diff   [expr $now - $pgtime]
 
    if {$diff < 0} {
        set diff [expr abs($diff)]
        set neighbor Tomorrow
        set neighbor_day -86400
    } else {
        set neighbor Yesterday
        set neighbor_day 86400
    }
 
    # 31536000 seconds in a 365-day year
    if {$diff > 31536000} {
        return [ns_fmttime $pgtime "%A, %b %e, %Y"]
    }
 
    set pg_day_of_year [ns_fmttime $pgtime %j]
    set now_day_of_year [ns_fmttime $now %j]
 
    if {[string compare $pg_day_of_year $now_day_of_year] == 0} {
        return "Today at [string trimleft [ns_fmttime $pgtime %I:%M%p] 0]"
    }
 
    set neighbor_day_of_year [ns_fmttime [expr $pgtime + $neighbor_day] %j]
 
    if {[string compare $now_day_of_year $neighbor_day_of_year] == 0} {
        return "$neighbor at [string trimleft [ns_fmttime $pgtime %I:%M%p] 0]"
    }
 
    switch -- [ns_fmttime $pgtime %d] {
        01  -
        21  -
        31  { set suffix st }
        02  -
        22  { set suffix nd }
        03  { set suffix rd }
        default { set suffix th }
    }
 
    return [ns_fmttime $pgtime "%A, %b %e"]$suffix
 
}
This will only work on AOLserver 3.0 (since AOLserver 2.3 is Tcl 7.4-based, and the clock scan command wasn't added until Tcl 7.6). It also only works on dates between the start of the epoch, up through integer overflow (ie January 1, 1970 — sometime in August(?) of 2038).