How to find the difference in days between two dates?

A = "2002-20-10"
B = "2003-22-11"

How to find the difference in days between two dates?

+63
date bash shell
Feb 09 2018-11-17T00:
source share
18 answers

If you have GNU date , it allows you to print an arbitrary date representation ( -d ). In this case, convert the dates in seconds with EPOCH, subtract and divide by 24 * 3600.

Or do you need a portable way?

+24
Feb 09 2018-11-11T00:
source share

The bash way is to convert the dates to the format% y% m% d, and then you can do it directly from the command line:

 echo $(( ($(date --date="031122" +%s) - $(date --date="021020" +%s) )/(60*60*24) )) 
+50
Aug 4 2018-11-11T00:
source share

And in python

 $python -c "from datetime import date; print (date(2003,11,22)-date(2002,10,20)).days" 398 
+14
Nov 18 '11 at 8:10
source share

Beware! Many of the bash solutions here are broken for date ranges that span the start of daylight saving time (where applicable). This is because the $ ((math)) construct performs the "floor" / truncation operation on the resulting value, returning only an integer. Let me illustrate:

DST began March 8 this year in the US, so let’s use a date range that covers this:

 start_ts=$(date -d "2015-03-05" '+%s') end_ts=$(date -d "2015-03-11" '+%s') 

Let's see what happened with double parentheses:

 echo $(( ( end_ts - start_ts )/(60*60*24) )) 

Returns "5".

Doing this with "bc" gives us a different result with greater accuracy:

 echo "scale=2; ( $end_ts - $start_ts )/(60*60*24)" | bc 

Returns "5.95" - the missing 0.05 is a lost hour after switching DST.

So how to do it right?
I would suggest using this instead:

 printf "%.0f" $(echo "scale=2; ( $end_ts - $start_ts )/(60*60*24)" | bc) 

Here "printf" rounds off the more accurate result calculated by "bc", giving us the correct date range of "6".

Edit: highlighting the answer in a comment from @ hank-schultz below, which I used recently:

 date_diff=$(( ($(date -d "2015-03-11 UTC" +%s) - $(date -d "2015-03-05 UTC" +%s) )/(60*60*24) )) 

This should also be a safe second step, provided that you always subtract the earlier date from the later, since the seconds of the jump will only add to the difference - truncation is effectively rounded to the correct result.

+14
Mar 12 '15 at 19:53
source share

Here is the Mac OS X version for your convenience.

 $ A="2002-20-10"; B="2003-22-11"; $ echo $((('date -jf %Y-%d-%m $B +%s' - 'date -jf %Y-%d-%m $A +%s')/86400)) 

NJoy!

+6
Dec 27
source share

If the -d option works on your system, this is another way to do this. There is a caution that he will not take leap years into account since I reviewed 365 days a year.

 date1yrs=`date -d "20100209" +%Y` date1days=`date -d "20100209" +%j` date2yrs=`date +%Y` date2days=`date +%j` diffyr=`expr $date2yrs - $date1yrs` diffyr2days=`expr $diffyr \* 365` diffdays=`expr $date2days - $date1days` echo `expr $diffyr2days + $diffdays` 
+4
Feb 09 '11 at 17:09
source share

Even if you don't have a GNU date, you probably installed Perl:

 use Time::Local; sub to_epoch { my ($t) = @_; my ($y, $d, $m) = ($t =~ /(\d{4})-(\d{2})-(\d{2})/); return timelocal(0, 0, 0, $d+0, $m-1, $y-1900); } sub diff_days { my ($t1, $t2) = @_; return (abs(to_epoch($t2) - to_epoch($t1))) / 86400; } print diff_days("2002-20-10", "2003-22-11"), "\n"; 

This returns 398.041666666667 - 398 days and one hour due to daylight saving time.




The question returned to my feed. Here's a more concise method using the Perl module built-in

 days=$(perl -MDateTime -le ' sub parse_date { @f = split /-/, shift; return DateTime->new(year=>$f[0], month=>$f[2], day=>$f[1]); } print parse_date(shift)->delta_days(parse_date(shift))->in_units("days"); ' $A $B) echo $days # => 398 
+4
Feb 09 '11 at 17:51
source share

This works for me:

 A="2002-10-20" B="2003-11-22" echo $(( ($(date -d $B +%s) - $(date -d $A +%s)) / 86400 )) days 

Print

 398 days 

What's happening?

  1. Specify the correct time string in A and B
  2. Use date -d to handle timelines
  3. Use date %s to convert timelines to seconds since 1970 (unix epoche)
  4. Use the bash parameter extension to subtract seconds
  5. divide by seconds per day (86400 = 60 * 60 * 24) to get the difference in days
  6. ! DST is not taken into account! See this answer on unix.stackexchange !
+2
Apr 09 '18 at 7:57
source share

I would introduce another possible solution in Ruby. It seems to be the smallest and most beautiful of them:

 A=2003-12-11 B=2002-10-10 DIFF=$(ruby -rdate -e "puts Date.parse('$A') - Date.parse('$B')") echo $DIFF 
+1
Feb 10 '11 at 15:52
source share

on unix, you must set the GNU dates. you do not need to deviate from bash. here is the crossed out decision considering the days, just to show the steps. It can be simplified and expanded to full dates.

 DATE=$(echo `date`) DATENOW=$(echo `date -d "$DATE" +%j`) DATECOMING=$(echo `date -d "20131220" +%j`) THEDAY=$(echo `expr $DATECOMING - $DATENOW`) echo $THEDAY 
+1
Nov 30 '13 at 4:11
source share

Try:

 perl -e 'use Date::Calc qw(Delta_Days); printf "%d\n", Delta_Days(2002,10,20,2003,11,22);' 
0
Feb 09 '11 at 18:00
source share

Another version of Python:

 python -c "from datetime import date; print date(2003, 11, 22).toordinal() - date(2002, 10, 20).toordinal()" 
0
Dec 12 '11 at 19:17
source share

Use shell functions from http://cfajohnson.com/shell/ssr/ssr-scripts.tar.gz ; they work in any standard Unix shell.

 date1=2012-09-22 date2=2013-01-31 . date-funcs-sh _date2julian "$date1" jd1=$_DATE2JULIAN _date2julian "$date2" echo $(( _DATE2JULIAN - jd1 )) 

See the documentation at http://cfajohnson.com/shell/ssr/08-The-Dating-Game.shtml

0
Feb 02 '13 at 3:30
source share

Suppose we manually back up Oracle DB on a tertiary disk manually. Then we want to delete the old backups on this disk. So here is a small bash script:

 #!/bin/sh for backup_dir in {'/backup/cmsprd/local/backupset','/backup/cmsprd/local/autobackup','/backup/cfprd/backupset','/backup/cfprd/autobackup'} do for f in `find $backup_dir -type d -regex '.*_.*_.*' -printf "%f\n"` do f2=`echo $f | sed -e 's/_//g'` days=$(((`date "+%s"` - `date -d "${f2}" "+%s"`)/86400)) if [ $days -gt 30 ]; then rm -rf $backup_dir/$f fi done done 

Change the shelf life and shelf life ("30 days") to suit your needs.

0
Feb 18
source share

Using mysql command

 $ echo "select datediff('2013-06-20 18:12:54+08:00', '2013-05-30 18:12:54+08:00');" | mysql -N 

Result: 21

NOTE. Only parts of the value date are used in the calculations.

Link: http://dev.mysql.com/doc/refman/5.6/en/date-and-time-functions.html#function_datediff

0
Jun 20 '13 at 10:25
source share

This assumes that the month is 1/12 of the year:

 #!/usr/bin/awk -f function mktm(datespec) { split(datespec, q, "-") return q[1] * 365.25 + q[3] * 365.25 / 12 + q[2] } BEGIN { printf "%d\n", mktm(ARGV[2]) - mktm(ARGV[1]) } 
0
Dec 29 '16 at 3:35
source share

For MacOS sierra (possibly from Mac OS X yosemate),

To get the time of an era (seconds since 1970) from a file and save it in var: old_dt=`date -j -r YOUR_FILE "+%s"`

To get the time of the current time new_dt=`date -j "+%s"`

To calculate the difference above two eras (( diff = new_dt - old_dt ))

To check if diff is more than 23 days (( new_dt - old_dt > (23*86400) )) && echo Is more than 23 days

0
Jun 11 '17 at 13:05
source share

This is the simplest thing that I managed to get started with Centos 7:

 OLDDATE="2018-12-31" TODAY=$(date -d $(date +%Y-%m-%d) '+%s') LINUXDATE=$(date -d "$OLDDATE" '+%s') DIFFDAYS=$(( ($TODAY - $LINUXDATE) / (60*60*24) )) echo $DIFFDAYS 
0
Jan 22 '19 at 13:49
source share



All Articles