3

Can I get "last monday based on 10 minutes ago" by linux date command ?

For example

  • current time: 2016-02-09 00:05:00
  • expected result: 2016-02-01 00:00:00
  • I believe you can't in a single command since syntax like last monday seems to always be relative to today. But you could use a short script that gives you the correct date based on whether 10 minutes ago was a Monday. – RealSkeptic Feb 12 '16 at 13:51
  • ITYM GNU date instead of linux date. linux is just an OS kernel software. There are several date implementations that can be compiled for Linux, the most common on non-embedded OSes that use Linux as their kernel is the one from the GNU project (part of GNU coreutils). – Stéphane Chazelas Feb 12 '16 at 15:29
6

If you have faketime and your date is dynamically linked:

faketime -f -10m date -d 'last monday' '+%F %T'

With ksh93 (only builtin commands):

printf '%(%F %T)T\n' "$(printf '%(%Y.%m.%d)T' '10 minutes ago')-0 last monday"

Here, if it was last Sunday instead of last Monday, you could do:

date -d "$(date -d '10 minutes ago' +"%F -%u day")"

Or if it was last Saturday:

date -d "$(date -d '10 minutes ago' +"%F -%w day -1 day")"

But for last Monday or any other day of the week, it involves a bit of arithmetic:

eval "date -d \"$(date -d '10 minutes ago' +'%F -$(((%u+5)%%7+1)) day')\""

Otherwise, you can always do:

d=$(date -d 'last monday'); sleep 600; printf '%s\n' "$d"

;-)

  • The 2nd example doesn't give last Monday relative to 10m ago. Just a clarification for those who would miss the joke. – Dani_l Feb 12 '16 at 16:52
  • @Dani_l, depends how you look at it. At the time that command outputs a date, the date displayed would be the last monday relative to 10m earlier. – Stéphane Chazelas Feb 12 '16 at 17:14
2

You could do it in 2 date operations. Here's a quick bash shell script:

TIME_TEN_MINUTES_AGO=`date -d '-10 min' +%T`

LAST_MON=`date -d 'last-monday' +%Y-%m-%d`

echo "NOW:      " `date "+%Y-%m-%d %T"`
echo "Last Mon: " $LAST_MON $TIME_TEN_MINUTES_AGO

This prints:

NOW:       2016-02-12 07:54:27
Last Mon:  2016-02-08 07:44:27
  • I think you missed the point. "10 minutes ago" could fall on the previous day. In that case, the "last monday" should be relative to yesterday. – RealSkeptic Feb 12 '16 at 13:56
  • Ahhh, that's true. My bad. – thedude Feb 12 '16 at 14:02
1

I had a similar problem: given a date find the previous Monday.

(to rename the videos files of a show with its airing date on tv;

DATE=$(youtube-dl -j $VID | awk -F\" '{print $28}'))

I use BSD date on macOS and I've also installed GNU date.

It seems like faketime is the easiest solution for this problem:

faketime $DATE date -v-mon +%F,

faketime $DATE gdate -d last-mon +%F.

It can be done it with just GNU date, but it’s more complicated:

eval "gdate -d \"$(gdate -d $DATE '+%D $[-%u+1] day')\" +%F".

You could also do it with BSD date only, even if it gets messy:

date -j -f "%a %d %b %Y %T %Z" "$(date -j -r \ "$(date -j -f "%Y%m%d" "$DATE" +"%s")" -v-mon)" +"%F".

0

Not too elegant but this should do the trick:

#! /bin/bash
export LC_ALL=C # makes sure we're using C locale even in subshells
day_10_minutes_ago=$(date -d '-10min' +%a) # stores which weekday it was 10 minutes ago
day_now=$(date -d +%a) # stores which weekday it is now
if [ $day_10_minutes_ago = "Mon" ]; then # if ten minutes ago it was Monday
    if [ $day_now = "Mon" ] # if it's still Monday
        date -d '-1week 00:00' '+%F +%T' # prints the date and the time it was one week ago at 00:00
    else # it can only be Tuesday before 00:10:00 AM
        date -d '-1week-1day 00:00' '+%F +%T' # prints the date and the time it was one week and one day ago at 00:00
    fi
else # it can only be Tuesday after 00:09:59 AM, Wednesday, Thursday, Friday, Saturday or Sunday
    date -d 'last-monday 00:00' '+%F +%T' # prints the date and the time it was last Monday at 00:00
fi
  • Suppose today is Tuesday a few minutes after midnight. Then "10 minutes ago" is Monday. "Last Monday" relative to "10 minutes ago" would be the previous Monday, 8 days before today. Your condition misses this. – RealSkeptic Feb 12 '16 at 16:18
  • @RealSkeptic Absolutely, thanks. I think I've fixed it. – kos Feb 12 '16 at 16:40
0

Here is a small script that solves the problem where 10 minutes ago is a previous day. I'm sure it could be done more elegantly though:

#!/bin/bash

DAY=`date --date='-10 min' +"%a"`
SEC=`date --date='-10 min' +"%s"`

if [[ "$DAY" == "Mon" ]]; then
    DDIF="7"
elif [[ "$DAY" == "Tue" ]]; then
    DDIF="1"
elif [[ "$DAY" == "Wed" ]]; then
    DDIF="2"
elif [[ "$DAY" == "Thu" ]]; then
    DDIF="3"
elif [[ "$DAY" == "Fri" ]]; then
    DDIF="4"
elif [[ "$DAY" == "Sat" ]]; then
    DDIF="5"
elif [[ "$DAY" == "Sun" ]]; then
    DDIF="6"
fi

EPOCH=$(awk "BEGIN {print $SEC-(86400*$DDIF); exit}")
date -d@"$EPOCH"

What this does is find out what day 10 minutes ago falls on. Finds out how many days removed that is from a Monday. Then multiplies that many days by 86400 (the number of seconds in one day) and subtracts it from the Epoch as based on 10 minutes ago. Finally it converts the epoch value back to standard format.

Like I said, not necessarily simple, one line, or elegant.

  • I think you missed by 7 :) If 10m ago falls on Monday, last Monday would be a week ago, not "today". DDIF should equal 7, not 0. – Dani_l Feb 12 '16 at 16:55
  • Ah yes. Corrected. – Kip K Feb 12 '16 at 17:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy