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
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It only takes a minute to sign up.
Sign up to join this communityIf 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"
;-)
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 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"
.
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
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.
last monday
seems to always be relative to today. But you could use a short script that gives you the correct date based on whether10 minutes ago
was a Monday.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).