Search This Blog

Loading...

Saturday, November 14, 2009

Fun with Date Arithmetic

We all know that the date command tells you the current time. Occasionally, you use the same command to set the time. That however becomes rarer these days with the advent of the ntp service that automatically synchronizes your computer's time with a super accurate public time server of your choice.

Various implementations of the date command are in use today. This article discusses the date command of the GNU coreutils package.

By default, the date command tells you the time now. The date command also lets you do some basic date addition and subtraction. This is achieved by specifying the -d option which displays a time that you entered as a parameter rather than now.

How many times have you asked yourself what the calendar date is N days ago? Just the other day, I needed to find out the precise date of 30 days ago in order to locate the proper log file.

$ date
Sat Nov 14 17:54:51 PST 2009
$ date -d -30days
Thu Oct 15 18:54:56 PDT 2009


Just like you use subtraction to calculate a back date, you use addition to calculate a forward date. The example below displays the date 30 days from today.
$ date -d +30days
Thu Oct 15 18:54:56 PDT 2009


Besides days as the unit, you can also manipulate years, months, hours, minutes, and seconds.
peter@tiger:~$ date -d +2months
Thu Jan 14 18:48:43 PST 2010


You can combine them together like this:
$ date -d +2months17days
Sun Jan 31 18:49:45 PST 2010


Note that all the above are calculated relative to today's date. What about queries like 10 days tomorrow?
$ date -d tomorrow+10days
date -d tomorrow+10days
Wed Nov 25 18:52:03 PST 2009


10 days yesterday?
$ date -d yesterday-10days
Tue Nov 3 18:53:07 PST 2009


You can also perform your arithmetic relative to a specific day, say January 21, 2010.
$ date -d '2010-01-21 + 2 weeks 3 days'
Sun Feb 7 00:00:00 PST 2010


Lastly, the date command also recognizes the day of weeks (Sunday, Monday, ...) and the 2 keywords "last" and "next".
$ date -d 'next tuesday + 1 day'
Wed Nov 18 00:00:00 PST 2009


I hope you have fun with this versatile tool.

StumbleUpon Toolbar

9 comments:

puneet said...

Hi

I tried this command
date -d -30days
on KSH but it is not working
error it is giving is :

date -d -30days
date: illegal option -- d
Usage: date [-u] [+Field Descriptors]

can you please explain

Anonymous said...

you can try "date --version" and see which one your using, I can attest it works with "date (GNU coreutils) 7.4"

Peter Leung said...

I tried it on ksh93 (as opposed to ksh88), and it worked.

See below

$ ksh --version
version sh (AT&T Labs Research) 1993-12-28 r
$ date -d -30days
Sun Dec 27 10:37:15 PST 2009
$ date --version
date (GNU coreutils) 5.97
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software. You may redistribute copies of it under the terms of
the GNU General Public License .
There is NO WARRANTY, to the extent permitted by law.

Written by David MacKenzie.

What version of ksh and date are you using?

Chris said...

It also works with date (GNU coreutils) 6.11 and date (coreutils) 5.2.1 .

Wondered how much "1month" is as it could be anywhere from 28-31 days. Playing around I found that it just keeps the day of month the same and just in/decreases the month (duh).

So I wondered what happens when you ask for "date -d +1month" on January 30th. Anybody wants to guess? Here goes:

$ date -d '2010-01-30 + 1month'
Tue Mar 2 00:00:00 CET 2010

So I guess '1month' equals number of days of the current month.

Not so important but interesting I thought.

Nuno said...

An incredible tool, indeed. I had no idea it was so powerful. Thank you for this excellent post!

Anonymous said...

Whatever I was searching I found it here ..

Thanks,
Sandeep

Anonymous said...

Thanks for fixing my script with your great examples!

Date can even combine arithmetic with output formatting:

date -d +10days +%Y-%m-%d
2013-04-14

date --help
explains the format symbols

Paul

Anonymous said...

For a whole set of calculation tools (difference between dates, date sequences, etc.) try dateutils, has to be compiled and installed first though :(

Sandeep Mule said...

Thanks a lot for writing this post. Excellent Explaination.