I understand the command date -d 'last-monday - 14 days' +%Y%m%d will print the Monday two weeks ago from "Today's date". I need a way to test this for different dates and see the result. Almost like I need to mention the date command to do calculations off a relative date.

I need something to test with different dateslike :

date -d 'last-monday - 14 days' %Y%m%d from 20190315

date -d 'last-monday - 14 days' %Y%m%d from 20180217

date -d 'last-monday - 14 days' %Y%m%d from 201700914

and see the respective outputs.

  • You'd want a way to get (respectively to your example) results such as: 20190225 and 20180129 and 20170828, am I correct ?
    – LL3
    Mar 20 '19 at 22:24
$ date
Wed Mar 20 15:02:23 MST 2019
$ date -d "last-monday"
Mon Mar 18 00:00:00 MST 2019
$ date -d "last-monday - 1 week"
Mon Mar 11 00:00:00 MST 2019
  • 3
    The issue seems to be finding the date of the Monday two weeks before a particular date.
    – Kusalananda
    Mar 20 '19 at 22:16
  • 2
    Not an answer to the original question, but definitely what I was looking for. Useful to know the date-command can do maths like this. Jan 20 at 9:01

On at least Debian there is a faketime package

faketime '2019-03-15' date
Fri 15 Mar 00:00:00 GMT 2019

faketime '2019-03-15' date --date 'last monday - 14 days'
Mon 25 Feb 00:00:00 GMT 2019

# Our given dates

# Loop over the given dates
for thedate in "${dates[@]}"; do
    # Get day of the week as digit (1 is Monday, 7 is Sunday)
    day=$( date -d "$thedate" +%u )
    # The Monday the same week is $(( day - 1 )) days earlier than the given date.
    # The Monday two weeks earlier is 14 days earlier still.

    date -d "$thedate -$(( day - 1 + 14 )) days" +"$thedate --> %Y%m%d"


20190315 --> 20190225
20180217 --> 20180129
20170914 --> 20170828

The difficult bit about this is to figure out how to construct the correct --date or -d string for GNU date to compute the final date. I opted for computing the day of week of the given date, and then using that to compute a date string that offsets the given date by a number of days so that the resulting date is the Monday two weeks earlier.

The actual strings that ends up being used for the option argument to -d in the above script, using the dates given in the script, are

20190315 -18 days
20180217 -19 days
20170914 -17 days

Condensing the script into a single command that does the computation for a single date in $thedate:

date -d "$thedate -$(date -d "$thedate" +%u) days -13 days" +%Y%m%d


date -d "$thedate -$(date -d "$thedate" +"-%u days -13 days")" +%Y%m%d

The overkill solution:

Create a bare-bones virtual machine.  Run it in single user mode, so no background services are running.  Just to be sure, double-check that NTP is not running.

Then set the date to whatever you want to set it to, and do your tests.


Use the date command's -s/--set option:

# date
Wed Mar 20 23:02:18 CET 2019
# date -s '20190315' > /dev/null; date -d 'last-monday - 14 days'
Mon Feb 25 00:00:00 CET 2019

Depending on your system, you might have to prefix with sudo or reset afterwards via ntpdate

  • 1
    Setting the system's clock seems like overkill just to get the correct output. It may also confuse certain services and scheduled tasks, and other users of the system if it's a multi-user system.
    – Kusalananda
    Mar 20 '19 at 22:09
  • @Kusalananda I agree, in principle, but most modern systems will automatically resync via ntp anyway. When I tested this, date returned the correct time immediately afterwards; hence the ; instead of using two separate commands to show what I'm doing. But if you really don't want to touch your system time, there does exist a faketime package.
    – Entropy0
    Mar 20 '19 at 22:19
  • The ntpd daemon won't resync if you exceed its the 300 second variance.
    – roaima
    Mar 20 '19 at 22:44
  • Then there is something else going on in my system (Mint 19), because 5d > 300s and as I said: running above command didn't affect anything beyond the commands in the current line. In fact: # date -s '19700102' ; date ; sleep 1 ; date yields Fri Jan 2 00:00:00 CET 1970 Fri Jan 2 00:00:00 CET 1970 Wed Mar 20 23:49:26 CET 2019
    – Entropy0
    Mar 20 '19 at 22:49
  • Maybe you're running ntpdate from cron (ugh), or perhaps chrony has a larger leeway. Or there again there's whatever the systemd borg has done to NTP.
    – roaima
    Mar 20 '19 at 22:56

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.