Get last monday date

Viewed 305

I want to get the last Monday date for the given date. For example If my input is 190113 I want the output as 190107 which is last Monday.

if {$current_date == "Mon"} {

    set startday [clock seconds]
    set startday [clock format $startday -format %y%m%d]
    puts $startday

} else {

    puts "no monday today"
    #I don't know how to get last monday date


}
2 Answers

This can be done fairly simply, by taking advantage of the fact that clock scan has quite a complex parser, and you can supply a timestamp that everything is relative to via the -base option. Also, both clock scan and clock format take -format options so that you can specify exactly what is going on in your input and output data.

proc getLastMonday {baseDate} {
    set base [clock scan $baseDate -format "%y%m%d"]
    set timestamp [clock scan "12:00 last monday" -base $base]
    return [clock format $timestamp -format "%y%m%d"]
    # This would work as a one-liner, provided you like long lines
}

Demonstrating:

puts [getLastMonday 190113];  # ==> 190107
puts [getLastMonday 190131];  # ==> 190128

Reference: https://www.tcl.tk/man/tcl/TclCmd/clock.htm#M22

Here's a sample code-snippet for the purpose. Added inline comments for understanding:

proc get_last_monday_date {date} {
  # Get the end timestamp for the specified date
  set end_timestamp [clock scan ${date}-23:59:59 -format %y%m%d-%H:%M:%S]

  # Get day of the week for the current date
  set day_of_week [clock format $end_timestamp -format %u]

  # Sunday may report as 0 or 7. If 0, change to 7
  # if {$day_of_week == 0} {
  #     set day_of_week 7
  # }

  # Monday is 1st day of the week. Monday = 1.
  # Find how many days to go back in time
  set delta_days [expr $day_of_week - 1]

  # Multiply the delta by 24 hours and subtract from end of the day timestamp
  # Get the timestamp for the result. That's last Monday's timestamp.
  return [clock format [clock add $end_timestamp -[expr $delta_days * 24] hours] -format %D]

}
puts "Last Monday for 01-Jan-2019:  [get_last_monday_date 190101]"
puts "Last Monday for 06-Jan-2019:  [get_last_monday_date 190106]"
puts "Last Monday for 15-Jan-2019:  [get_last_monday_date 190115]"
puts "Last Monday for 31-Jan-2019:  [get_last_monday_date 190131]"

Execution output:

Last Monday for 01-Jan-2019:  12/31/2018
Last Monday for 06-Jan-2019:  12/31/2018
Last Monday for 15-Jan-2019:  01/14/2019
Last Monday for 31-Jan-2019:  01/28/2019
Related