LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 5842|回复: 12

怎么计算两个日期间的天数

[复制链接]
发表于 2005-7-2 20:55:57 | 显示全部楼层 |阅读模式
有没有现成的方法?
日期的格式为YYMMDD
谢谢!~
或者计算一个日期距当前日期的天数?
 楼主| 发表于 2005-7-2 22:05:15 | 显示全部楼层
这是我写的函数..
[PHP]
interdays(){
   local s1 s2 s3
   s1=`date +%s -d$1`
   s2=`date +%s -d$2`
   if [ $s1 -gt $s2 ]
   then
        s3=$(($s1 - $s2))
   else
        s3=$(($s2 - $s1))
   fi
   return $((s3 / (60 * 60 * 24)))
}
[/PHP]
回复 支持 反对

使用道具 举报

发表于 2005-7-3 10:47:55 | 显示全部楼层
用cal来处理吧.,你上面的代码要是出现跨月份的就很难计算了.
回复 支持 反对

使用道具 举报

发表于 2005-7-3 11:24:17 | 显示全部楼层
abs-guide中有一个计算两个日期中天数的例子,但它的格式是mm/dd/yyyy:

  1. #!/bin/bash
  2. # days-between.sh:    Number of days between two dates.
  3. # Usage: ./days-between.sh [M]M/[D]D/YYYY [M]M/[D]D/YYYY
  4. #
  5. # Note: Script modified to account for changes in Bash 2.05b
  6. #+      that closed the loophole permitting large negative
  7. #+      integer return values.

  8. ARGS=2                # Two command line parameters expected.
  9. E_PARAM_ERR=65        # Param error.

  10. REFYR=1600            # Reference year.
  11. CENTURY=100
  12. DIY=365
  13. ADJ_DIY=367           # Adjusted for leap year + fraction.
  14. MIY=12
  15. DIM=31
  16. LEAPCYCLE=4

  17. MAXRETVAL=255         #  Largest permissable
  18.                       #+ positive return value from a function.

  19. diff=                 # Declare global variable for date difference.
  20. value=                # Declare global variable for absolute value.
  21. day=                  # Declare globals for day, month, year.
  22. month=
  23. year=


  24. Param_Error ()        # Command line parameters wrong.
  25. {
  26.   echo "Usage: `basename $0` [M]M/[D]D/YYYY [M]M/[D]D/YYYY"
  27.   echo "       (date must be after 1/3/1600)"
  28.   exit $E_PARAM_ERR
  29. }  


  30. Parse_Date ()                 # Parse date from command line params.
  31. {
  32.   month=${1%%/**}
  33.   dm=${1%/**}                 # Day and month.
  34.   day=${dm#*/}
  35.   let "year = `basename $1`"  # Not a filename, but works just the same.
  36. }  


  37. check_date ()                 # Checks for invalid date(s) passed.
  38. {
  39.   [ "$day" -gt "$DIM" ] || [ "$month" -gt "$MIY" ] || [ "$year" -lt "$REFYR" ] && Param_Error
  40.   # Exit script on bad value(s).
  41.   # Uses "or-list / and-list".
  42.   #
  43.   # Exercise: Implement more rigorous date checking.
  44. }


  45. strip_leading_zero () #  Better to strip possible leading zero(s)
  46. {                     #+ from day and/or month
  47.   return ${1#0}       #+ since otherwise Bash will interpret them
  48. }                     #+ as octal values (POSIX.2, sect 2.9.2.1).


  49. day_index ()          # Gauss' Formula:
  50. {                     # Days from Jan. 3, 1600 to date passed as param.

  51.   day=$1
  52.   month=$2
  53.   year=$3

  54.   let "month = $month - 2"
  55.   if [ "$month" -le 0 ]
  56.   then
  57.     let "month += 12"
  58.     let "year -= 1"
  59.   fi  

  60.   let "year -= $REFYR"
  61.   let "indexyr = $year / $CENTURY"


  62.   let "Days = $DIY*$year + $year/$LEAPCYCLE - $indexyr + $indexyr/$LEAPCYCLE + $ADJ_DIY*$month/$MIY + $day - $DIM"
  63.   #  For an in-depth explanation of this algorithm, see
  64.   #+ http://home.t-online.de/home/berndt.schwerdtfeger/cal.htm


  65.   echo $Days

  66. }  


  67. calculate_difference ()            # Difference between to day indices.
  68. {
  69.   let "diff = $1 - $2"             # Global variable.
  70. }  


  71. abs ()                             #  Absolute value
  72. {                                  #  Uses global "value" variable.
  73.   if [ "$1" -lt 0 ]                #  If negative
  74.   then                             #+ then
  75.     let "value = 0 - $1"           #+ change sign,
  76.   else                             #+ else
  77.     let "value = $1"               #+ leave it alone.
  78.   fi
  79. }



  80. if [ $# -ne "$ARGS" ]              # Require two command line params.
  81. then
  82.   Param_Error
  83. fi  

  84. Parse_Date $1
  85. check_date $day $month $year       #  See if valid date.

  86. strip_leading_zero $day            #  Remove any leading zeroes
  87. day=$?                             #+ on day and/or month.
  88. strip_leading_zero $month
  89. month=$?

  90. let "date1 = `day_index $day $month $year`"


  91. Parse_Date $2
  92. check_date $day $month $year

  93. strip_leading_zero $day
  94. day=$?
  95. strip_leading_zero $month
  96. month=$?

  97. date2=$(day_index $day $month $year) # Command substitution.


  98. calculate_difference $date1 $date2

  99. abs $diff                            # Make sure it's positive.
  100. diff=$value

  101. echo $diff

  102. exit 0
  103. #  Compare this script with
  104. #+ the implementation of Gauss' Formula in a C program at:
  105. #+    http://buschencrew.hypermart.net/software/datedif
复制代码


以下来自comp.unix.shell

在cus的fag上看到过一个date2julian()函数,把公历日期转换儒略日计数(Julian Day Count),然后就可以方便地计算出两个日期间相差的天数了
这个应该比较符合楼主需求

  1. # Date calculations using Korn shell (ksh88)
  2. # Tapani Tarvainen July 1998, May 2000
  3. # This code is in the public domain.
  4. # Julian Day Number from calendar date
  5. date2julian()   #  day month year
  6. {
  7.   typeset -i day month year tmpmonth tmpyear
  8.   day=$1;  month=$2;  year=$3
  9.   ((tmpmonth = 12 * year + month - 3))
  10.   ((tmpyear = tmpmonth / 12))
  11.   print $(( (734 * tmpmonth + 15) / 24 -  2 * tmpyear + \
  12.     tmpyear/4 - tmpyear/100 + tmpyear/400 + day + 1721119 ))
  13. }
复制代码


处理各种不同的日期格式。

  1. #!/bin/ksh
  2. ###########################################################################
  3. # Date calculations using Korn shell (ksh88)
  4. # Tapani Tarvainen July 1998, May 2000
  5. # This code is in the public domain.
  6. # Julian Day Number from calendar date
  7. date2julian()   #  day month year
  8. {
  9.   typeset -i day month year tmpmonth tmpyear
  10.   day=$1;  month=$2;  year=$3
  11.   ((tmpmonth = 12 * year + month - 3))
  12.   ((tmpyear = tmpmonth / 12))
  13.   print $(( (734 * tmpmonth + 15) / 24 -  2 * tmpyear + \
  14.     tmpyear/4 - tmpyear/100 + tmpyear/400 + day + 1721119 ))

  15. }

  16. ###
  17. # Matt's Added formatting
  18. ###

  19. # Store input dates
  20. date1=$1
  21. date2=$2

  22. # Get the dates into their respective fields.  Uncomment the format of
  23. # date input being used.

  24. # YYYYMMDD
  25. year1=${date1%????}; mmdd1=${date1#????}; month1=${mmdd1%??}; day1=${mmdd1#??}
  26. year2=${date2%????}; mmdd2=${date2#????}; month2=${mmdd2%??}; day2=${mmdd2#??}

  27. # YYYY/MM/DD  or YYYY/M/D
  28. #print $date1 |IFS=/ read year1 month1 day1
  29. #print $date2 |IFS=/ read year2 month2 day2

  30. # MM/DD/YY    or M/D/YYYY
  31. #print $date1 |IFS=/ read month1 year1 day1
  32. #print $date2 |IFS=/ read month2 year2 day2

  33. # Calculate and print the difference between dates (date2 - date1)
  34. print -- "$(($(date2julian $day2 $month2 $year2) - $(date2julian $day1 \
  35. $month1 $year1)))"
复制代码


BASH需要做一些相应修改。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-7-3 13:39:56 | 显示全部楼层
Post by kiron
用cal来处理吧.,你上面的代码要是出现跨月份的就很难计算了.


这个是为什么呢? 我把时间转换成距格林威治的秒数了,为什么会有跨月份的问题?
回复 支持 反对

使用道具 举报

发表于 2005-7-3 15:58:51 | 显示全部楼层
Post by guang
这个是为什么呢? 我把时间转换成距格林威治的秒数了,为什么会有跨月份的问题?


Sorry,我没试过就乱下结论,不好意思 :sorry
回复 支持 反对

使用道具 举报

发表于 2005-7-3 18:11:08 | 显示全部楼层
看起来没什么问题。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-7-3 18:39:11 | 显示全部楼层
to : kiron
你说用cal 怎么计算?
回复 支持 反对

使用道具 举报

发表于 2005-7-4 10:03:24 | 显示全部楼层
Post by guang
to : kiron
你说用cal 怎么计算?


cal可以打印出儒略日,只需找到你指定的天数之间的儒略日,相减即可.
回复 支持 反对

使用道具 举报

发表于 2005-7-13 14:01:47 | 显示全部楼层
用两个日期的日期戳的差/86400
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表