Chinaunix

标题: 日期date [打印本页]

作者: nogroup    时间: 2009-04-11 11:44
标题: 日期date
任意给定一个日期,求其上一个周一的日期。
如,指定2009-04-08 ,则其上一个周一的日期是2009-04-06
或如,指定2009-04-06,则其上一个周一的日期是2009-03-30.

不知道有没有简洁方便的参数。
date -d '2009-04-09 last monday' +%Y%m%d  

这样貌似行不通。有熟悉的朋友来指点一下。
作者: deepalley    时间: 2009-04-11 12:26
用了一种比较笨的方法
---------------------------
#!/bin/sh
if [ $# -ne 1  ]
then
        echo "Usage: $0 YYYYMMDD"
        exit
fi

nowday=`date +%Y%m%d`
nowtime=`date +%H:%M:%S`

i=$1
date -s $1 > /dev/null
echo "last monday is $(date -d last-monday +%Y%m%d)"

date -s $nowday > /dev/null
date -s $nowtime >/dev/null
---------------------------------------------
output:
root@/myshell# ./dat.sh 20090406
last monday is 20090330
作者: nogroup    时间: 2009-04-11 12:55
标题: 回复 #2 deepalley 的帖子
这是不可取的,很可能是没有权限执行date -s 操作的哦。
作者: deepalley    时间: 2009-04-11 13:01
原帖由 nogroup 于 2009-4-11 12:55 发表
这是不可取的,很可能是没有权限执行date -s 操作的哦。


对,这个要root权限
作者: 我是DBA    时间: 2009-04-11 13:04
标题: 回复 #2 deepalley 的帖子
不错,这个好用,我还想用case写呢
算了。
作者: linuxboy823    时间: 2009-04-11 13:17
标题: 回复 #1 nogroup 的帖子
[linuxboy823@fc8 temp]$ cat 1.sh
#/bin/bash
a=`date +%u -d "$1"`
b=`expr $a - 1`
if [ $b -eq 0 ]
then
date -d  "-7  day $1"
else
date -d  "-${b}  day $1"
fi

[linuxboy823@fc8 temp]$ sh 1.sh 20080101
2007年 12月 31日 星期一 00:00:00 CST

[ 本帖最后由 linuxboy823 于 2009-4-11 13:23 编辑 ]
作者: ubuntuer    时间: 2009-04-11 13:29
原帖由 linuxboy823 于 2009-4-11 13:17 发表
[linuxboy823@fc8 temp]$ cat 1.sh
#/bin/bash
a=`date +%u -d "$1"`
b=`expr $a - 1`
if [ $b -eq 0 ]
then
date -d  "-7  day $1"
else
date -d  "-${b}  day $1"
fi

[linuxboy823@fc8 temp]$ sh ...

不错不错,想法值得学习^_^
作者: justlooks    时间: 2009-04-11 13:32
比如4月22日
$ echo $((22-$(date -d '04/22' '+%u')+1))
20
作者: wtuter    时间: 2009-04-11 19:23
标题: 回复 #1 nogroup 的帖子
#!/bin/bash

month=`echo $*|awk -F'-' '{print $2}'|sed '/^0/s/0\([1-9]*\)/\1/g'`

year=`echo $*|awk -F'-' '{print $1}'`

day=`echo $*|awk -F'-' '{print $3}'|sed '/^0/s/0\([1-9]*\)/\1/g'`

if [ $day -gt 7 ];then
  cal=`cal -m $month $year|sed -n "/\<$day\>/p"|awk '{print $1}'`
echo "last monday ls $year-$month-$cal"
  else
#  month=`echo $*|awk -F'-' '{print $2}'|sed '/^0/s/0\([1-9]*\)/\1/g'`
#  year=`echo $*|awk -F'-' '{print $1}'`
#  day=`echo $*|awk -F'-' '{print $3}'|sed '/^0/s/0\([1-9]*\)/\1/g'`
  x=`expr $month - 1`
   cal=`cal -m $x $year|tr -s "\n"|awk  'END{print $1}'`
    echo "last monday ls $year-$x-$cal"
  fi





[W]sh  1 2009-04-06
last monday ls 2009-3-30


[W]sh  1 2009-04-08
last monday ls 2009-4-6

[ 本帖最后由 wtuter 于 2009-4-11 19:45 编辑 ]
作者: rhlei    时间: 2009-04-11 21:00
标题: 回复 #1 nogroup 的帖子
date -d '2009-04-09 last monday' +%Y%m%d  


last monday 是什么意思?
作者: hakajawa    时间: 2009-04-11 21:59
原帖由 rhlei 于 2009-4-11 21:00 发表
date -d '2009-04-09 last monday' +%Y%m%d  


last monday 是什么意思?


上个周一的日期
作者: tuyajie    时间: 2009-04-11 22:22
只是lz要简单得写法还真不知道。
作者: blackold    时间: 2009-04-12 00:15
try:

  1. date -d "-$(date +%u -d "yesterday urdate") day urdate"
复制代码

$ date -d "-$(date +%u -d "yesterday 2009-4-6") day 2009-4-6"
Mon Mar 30 00:00:00     2009

$ date -d "-$(date +%u -d "yesterday 2009-4-8") day 2009-4-8"
Mon Apr  6 00:00:00     2009

[ 本帖最后由 blackold 于 2009-4-12 00:41 编辑 ]
作者: beginner-bj    时间: 2009-04-12 08:33
当日的前一天是周几用A表示,周日到周六依次为0-6,这个数字加6再除以7,求得余数B,得到下表:
周几 A B
周日 0 6
周一 1 0
周二 2 1
周三 3 2
周四 4 3
周五 5 4
周六 6 5

当日减(B+1)天,就是上一个周一的日子

[ 本帖最后由 beginner-bj 于 2009-4-12 08:50 编辑 ]
作者: rhlei    时间: 2009-04-12 09:03
标题: 回复 #11 hakajawa 的帖子
为什么我直行后没有效果,不显示上个周一的日期?望明示~
作者: 我是DBA    时间: 2009-04-12 10:27
标题: 回复 #15 rhlei 的帖子
要认真看一下题目才是。
作者: blackold    时间: 2009-04-12 13:26
标题: 回复 #14 beginner-bj 的帖子
Good!
作者: beginner-bj    时间: 2009-04-12 15:27
又想了下。假设当日是周几用C表示,周日到周六依次为0-6,那这样更简单:

当日 C (8-C)%7-7
周日 0 -6
周一 1 -7
周二 2 -1
周三 3 -2
周四 4 -3
周五 5 -4
周六 6 -5
作者: haimming    时间: 2009-04-12 16:23
标题: 回复 #18 beginner-bj 的帖子
太高深了,不明白,怎么用?跨年跨月如何处理?
作者: blackold    时间: 2009-04-12 18:11
标题: 回复 #19 haimming 的帖子
星期不存在跨年月问题,日期的跨年月问题留给date来处理。

搞成数学问题了。
作者: zhangshebao    时间: 2009-04-12 21:19
我在cygwin中测试,取当前日期的上周一:
date -d 'last monday' +%Y%m%d  
可以,但
date -d '2009-04-09 last monday' +%Y%m%d  
显示2009-04-09了.
我写了个awk的:

lastmonday(){
#上个周一,如果当天是周一则显示当天的日期,用法 lastmonday yyyy-mm-dd
awk -v d="$1" '
BEGIN{
   gsub("-"," ",d);
   print strftime("%Y-%m-%d",mktime(d" 0 0 0")-3600*24*((strftime("%w",mktime(d" 0 0 0"))+5)%7+1))
}'
}

lastmonday1(){
#上个周一,如果当天是周一则显示当天的日期,用法 lastmonday1 yyyy-mm-dd
awk -v d="$1" '
BEGIN{
   gsub("-"," ",d);
   print strftime("%Y-%m-%d",mktime(d" 0 0 0")-3600*24*(strftime("%w",3600*24*6+mktime(d" 0 0 0"))))
}'
}

#示例:
for a in 1 2 3 4 5 6 7
do
  echo "输入:" "2009-4-1$a"
  echo "过去的周一(含当天):\c";lastmonday "2009-4-1$a"
  echo "过去的周一(不含当天):\c";lastmonday1 "2009-4-1$a"
done

测试结果:
输入: 2009-4-11
过去的周一(含当天):2009-04-06
过去的周一(不含当天):2009-04-06
输入: 2009-4-12
过去的周一(含当天):2009-04-06
过去的周一(不含当天):2009-04-06
输入: 2009-4-13
过去的周一(含当天):2009-04-06
过去的周一(不含当天):2009-04-13
输入: 2009-4-14
过去的周一(含当天):2009-04-13
过去的周一(不含当天):2009-04-13
输入: 2009-4-15
过去的周一(含当天):2009-04-13
过去的周一(不含当天):2009-04-13
输入: 2009-4-16
过去的周一(含当天):2009-04-13
过去的周一(不含当天):2009-04-13
输入: 2009-4-17
过去的周一(含当天):2009-04-13
过去的周一(不含当天):2009-04-13
作者: beginner-bj    时间: 2009-04-12 22:31
原帖由 haimming 于 2009-4-12 16:23 发表
太高深了,不明白,怎么用?跨年跨月如何处理?


-bash-3.2$ uname -a
Linux fc8 2.6.26.6-49.fc8 #1 SMP Fri Oct 17 15:59:36 EDT 2008 i686 i686 i386 GNU/Linux
-bash-3.2$ date
Sun Apr 12 22:17:32 CST 2009
-bash-3.2$ date +%w
0
-bash-3.2$ echo \(8-`date +%w`\)%7-7 | bc
-6
-bash-3.2$ date -d $(echo \(8-`date +%w`\)%7-7 | bc)' days' +%Y%m%d
20090406
-bash-3.2$
-bash-3.2$ TheDay=2009-04-09; date -d  $TheDay' '$(echo \(8-`date -d $TheDay +%w`\)%7-7 | bc)' days' +%Y%m%d
20090406
-bash-3.2$ TheDay=2009-04-10; date -d  $TheDay' '$(echo \(8-`date -d $TheDay +%w`\)%7-7 | bc)' days' +%Y%m%d
20090406
-bash-3.2$ TheDay=2009-04-11; date -d  $TheDay' '$(echo \(8-`date -d $TheDay +%w`\)%7-7 | bc)' days' +%Y%m%d
20090406
-bash-3.2$ TheDay=2009-04-12; date -d  $TheDay' '$(echo \(8-`date -d $TheDay +%w`\)%7-7 | bc)' days' +%Y%m%d
20090406
-bash-3.2$ TheDay=2009-04-13; date -d  $TheDay' '$(echo \(8-`date -d $TheDay +%w`\)%7-7 | bc)' days' +%Y%m%d
20090406
-bash-3.2$ TheDay=2009-04-14; date -d  $TheDay' '$(echo \(8-`date -d $TheDay +%w`\)%7-7 | bc)' days' +%Y%m%d
20090413
-bash-3.2$ TheDay=2009-04-15; date -d  $TheDay' '$(echo \(8-`date -d $TheDay +%w`\)%7-7 | bc)' days' +%Y%m%d
20090413
-bash-3.2$ TheDay=2009-04-16; date -d  $TheDay' '$(echo \(8-`date -d $TheDay +%w`\)%7-7 | bc)' days' +%Y%m%d
20090413
-bash-3.2$ TheDay=2009-04-17; date -d  $TheDay' '$(echo \(8-`date -d $TheDay +%w`\)%7-7 | bc)' days' +%Y%m%d
20090413
-bash-3.2$

跨年跨月也一样没问题
-bash-3.2$ TheDay=2009-01-01; date -d  $TheDay' '$(echo \(8-`date -d $TheDay +%w`\)%7-7 | bc)' days' +%Y%m%d
20081229
-bash-3.2$

我上面只是给了个思路,不支持date -d的OS(比如AIX)用同样的思路一样可以完成任务。

另外如果支持date +%u的话,应该更简单了。
作者: haimming    时间: 2009-04-12 22:57
标题: 回复 #22 beginner-bj 的帖子
非常谢谢,
明白,深深地学习了一把!

另,bash,$(())可省bc
作者: blackold    时间: 2009-04-13 09:04
标题: 回复 #22 beginner-bj 的帖子
对于取余来说,%u和%w结果是一样的。
作者: linuxboy823    时间: 2009-04-13 10:46
原帖由 blackold 于 2009-4-12 00:15 发表
try:
date -d "-$(date +%u -d "yesterday urdate") day urdate"





黑哥的思路就是清晰,我还多算了一步,佩服!!
作者: 勒色    时间: 2009-04-15 17:12
原帖由 linuxboy823 于 2009-4-11 13:17 发表
[linuxboy823@fc8 temp]$ cat 1.sh
#/bin/bash
a=`date +%u -d "$1"`
b=`expr $a - 1`
if [ $b -eq 0 ]
then
date -d  "-7  day $1"
else
date -d  "-${b}  day $1"
fi

[linuxboy823@fc8 temp]$ sh ...


支持这个方法!
作者: pxebxp    时间: 2009-04-15 19:26
收下了




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2