`

Bash中关于日期时间操作的常用自定义函数

阅读更多

在编写Linux Bash脚本时,经常会用到一些日期时间有关的命令,下面是我多年Shell编程中常用的函数,现在整理出来,希望起到抛砖引玉的作用。

 

 

附件包括三个文件:

datetime.sh  包含了Bash中关于日期时间操作的常用自定义函数

test_datetime.sh 用来展示datetime.sh中自定义函数的用法

test_datetime.txt 是test_datetime.sh的一次执行输出样本

 

执行命令:

./test_datetime.sh >test_datetime.txt

 

 

文件:datetime.sh

#!/bin/sh


# Copyright (c) 2010 codingstandards. All rights reserved.
# file: datetime.sh
# description: Bash中关于日期时间操作的常用自定义函数
# license: LGPL
# author: codingstandards
# email: codingstandards@gmail.com
# version: 1.0
# date: 2010.02.27


# usage: yesterday
# 昨天
# 比如今天是2010年2月27日,那么结果就是2010-02-26
yesterday()
{
	date --date='1 day ago' +%Y-%m-%d
}

# usage: today
# 今天
# 比如今天是2010年2月27日,那么结果就是2010-02-27
today()
{
	date +%Y-%m-%d
}

# usage: now
# 现在,包括日期和时间、纳秒
# 比如:2010-02-27 11:29:52.991774000
now()
{
    date "+%Y-%m-%d %H:%M:%S.%N"
}

# usage: curtime
# 当前时间,包括日期和时间
# 比如:2010-02-27 11:51:04
curtime()
{
	date '+%Y-%m-%d %H:%M:%S'
	# 也可写成:date '+%F %T'
}

# usage: last_month
# 取上个月的年月
# 比如:2010-01
last_month()
{
	date --date='1 month ago' '+%Y-%m'
}

# usage: last_month_packed
# 取上个月的年月
# 比如:201001
last_month_packed()
{
	date --date='1 month ago' '+%Y%m'
}

# usage: first_date_of_last_month
# 取上个月的第一天
# 比如本月是2010年2月,那么结果就是2010-01-01
first_date_of_last_month()
{
	date --date='1 month ago' '+%Y-%m-01'
}

# usage: last_date_of_last_month
# 取上个月的最后一天
# 比如当前是2010年2月,那么结果就是2010-01-31
last_date_of_last_month()
{
	date --date="$(date +%e) days ago" '+%Y-%m-%d'
}

# usage: day_of_week
# 今天的星期
# day of week (0..6);  0 represents Sunday
day_of_week()
{
	date +%w
}

# usage: last_hour
# 上个小时
# 比如:2010-02-27-10
# 适合处理log4j生成的日志文件名
last_hour()
{
	date --date='1 hour ago' +%Y-%m-%d-%H
}

# usage: the_hour
# 当前的小时,为方便算术比较,结果不以0开头
# 比如:12
the_hour()
{
	#date +%H	# hour (00..23)
	date +%k	# hour ( 0..23)
}

# usage: the_minute
# 当前的分钟,为方便算术比较,结果不以0开头
# 比如:
the_minute()
{
	MM=$(date +%M)	# minute (00..59)
	echo $[1$MM-100]
}

# usage: the_second
# 当前的秒数
# 比如:
the_second()
{
	SS=$(date +%S)	# second (00..60); the 60 is necessary to accommodate a leap  second
	echo $[1$SS-100]
}

# usage: the_year
# 当前的年份 year (1970...)
# 比如:2010
the_year()
{
	date +%Y
}

# usage: the_month
# 当前的月份,为方便算术比较,结果不以0开头
# 比如:2
the_month()
{
	M=$(date +%m) # month (01..12)
	echo $[1$M-100]
}

# usage: the_date
# 当前的日期,为方便算术比较,结果不以0开头
# 比如:27
the_date()
{
	date +%e	# day of month, blank padded ( 1..31)
}

# usage: days_ago <n>
# 取n天前的日期
# 比如:days_ago 0就是今天,days_ago 1就是昨天,days_ago 2就是前天,days_ago -1就是明天
# 格式:2010-02-27
days_ago()
{
	date --date="$1 days ago" +%Y-%m-%d
}

# usage: chinese_date_and_week()
# 打印中文的日期和星期
# 比如:2月27日 星期六
chinese_date_and_week()
{
	WEEKDAYS=(星期日 星期一 星期二 星期三 星期四 星期五 星期六)
	WEEKDAY=$(date +%w)
	#DT="$(date +%Y年%m月%d日) ${WEEKDAYS[$WEEKDAY]}"   
	MN=1$(date +%m)
	MN=$[MN-100]
	DN=1$(date +%d)
	DN=$[DN-100]
	DT="$MN月$DN日 ${WEEKDAYS[$WEEKDAY]}"
	echo "$DT"
}

# usage: rand_digit
# 随机数字,0-9
rand_digit()
{
    S="$(date +%N)"
    echo "${S:5:1}"
}

# usage: seconds_of_date [<date> [<time>]]
# 获取指定日期的秒数(自1970年)
# 比如:seconds_of_date "2010-02-27" 返回 1267200000
seconds_of_date()
{
	if [ "$1" ]; then
		date -d "$1 $2" +%s
	else
		date +%s
	fi
}

# usage: date_of_seconds <seconds>
# 根据秒数(自1970年)得到日期
# 比如:date_of_seconds 1267200000 返回 2010-02-27
date_of_seconds()
{
	date -d "1970-01-01 UTC $1 seconds" "+%Y-%m-%d"
}

# usage: datetime_of_seconds <seconds>
# 根据秒数(自1970年)得到日期时间
# 比如:datetime_of_seconds 1267257201 返回 2010-02-27 15:53:21
datetime_of_seconds()
{
	date -d "1970-01-01 UTC $1 seconds" "+%Y-%m-%d %H:%M:%S"
}

# usage: leap_year <yyyy>
# 判断是否闰年
# 如果yyyy是闰年,退出码为0;否则非0
# 典型示例如下:
# if leap_year 2010; then
# 	echo "2010 is leap year";
# fi
# if leap_year 2008; then
# 	echo "2008 is leap year";
# fi
# 摘自脚本:datetime_util.sh (2007.06.11)
# 注:这个脚本来自网络,略有修改(原脚本从标准输入获取年份,现改成通过参数指定)
# Shell program to read any year and find whether leap year or not
# -----------------------------------------------
# Copyright (c) 2005 nixCraft project <http://cyberciti.biz/fb/>
# This script is licensed under GNU GPL version 2.0 or above
# -------------------------------------------------------------------------
# This script is part of nixCraft shell script collection (NSSC)
# Visit http://bash.cyberciti.biz/ for more information.
# -------------------------------------------------------------------------
leap_year()
{
	# store year
	yy=$1
	isleap="false"

	#echo -n "Enter year (yyyy) : "
	#read yy

	# find out if it is a leap year or not

	if [ $((yy % 4)) -ne 0 ] ; then
		: #  not a leap year : means do nothing and use old value of isleap
	elif [ $((yy % 400)) -eq 0 ] ; then
		# yes, it's a leap year
		isleap="true"
	elif [ $((yy % 100)) -eq 0 ] ; then
		: # not a leap year do nothing and use old value of isleap
	else
		# it is a leap year
		isleap="true"
	fi
	#echo $isleap
	if [ "$isleap" == "true" ]; then
		#  echo "$yy is leap year"
		return 0
	else
		#  echo "$yy is NOT leap year"
		return 1
	fi
}

# usage: validity_of_date <yyyy> <mm> <dd>
# 判断yyyy-mm-dd是否合法的日期
# 如果是,退出码为0;否则非0
# 典型示例如下:
# if validity_of_date 2007 02 03; then
# 	echo "2007 02 03 is valid date"
# fi
# if validity_of_date 2007 02 28; then
# 	echo "2007 02 28 is valid date"
# fi
# if validity_of_date 2007 02 29; then
# 	echo "2007 02 29 is valid date"
# fi
# if validity_of_date 2007 03 00; then
# 	echo "2007 03 00 is valid date"
# fi
# 摘自脚本:datetime_util.sh (2007.06.11)
# 注:这个脚本来自网络,略有修改(原脚本从标准输入获取年月日,现改成通过参数指定)
# Shell program to find the validity of a given date
# -----------------------------------------------
# Copyright (c) 2005 nixCraft project <http://cyberciti.biz/fb/>
# This script is licensed under GNU GPL version 2.0 or above
# -------------------------------------------------------------------------
# This script is part of nixCraft shell script collection (NSSC)
# Visit http://bash.cyberciti.biz/ for more information.
# -------------------------------------------------------------------------
validity_of_date()
{
	# store day, month and year
	yy=$1
	mm=$2
	dd=$3

	# store number of days in a month
	days=0

	# get day, month and year
	#echo -n "Enter day (dd) : "
	#read dd

	#echo -n "Enter month (mm) : "
	#read mm

	#echo -n "Enter year (yyyy) : "
	#read yy

	# if month is negative (<0) or greater than 12 
	# then it is invalid month
	if [ $mm -le 0 -o $mm -gt 12 ]; then
		#echo "$mm is invalid month."
		return 1
	fi

	# Find out number of days in given month
	case $mm in 
		1) days=31;;
		01) days=31;;
		2) days=28 ;;
		02) days=28 ;;
		3) days=31 ;;
		03) days=31 ;;
		4) days=30 ;;
		04) days=30 ;;
		5) days=31 ;;
		05) days=31 ;;
		6) days=30 ;;
		06) days=30 ;;
		7) days=31 ;;
		07) days=31 ;;
		8) days=31 ;;
		08) days=31 ;;
		9) days=30 ;;
		09) days=30 ;;
		10) days=31 ;;
		11) days=30 ;;
		12) days=31 ;;
		*) days=-1;;
	esac

	# find out if it is a leap year or not

	if [ $mm -eq 2 ]; then # if it is feb month then only check of leap year
		if [ $((yy % 4)) -ne 0 ] ; then
			: #  not a leap year : means do nothing and use old value of days
		elif [ $((yy % 400)) -eq 0 ] ; then
			# yes, it's a leap year
			days=29
		elif [ $((yy % 100)) -eq 0 ] ; then
			: # not a leap year do nothing and use old value of days
		else
			# it is a leap year
			days=29
		fi
	fi

	#echo $days

	# if day is negative (<0) and if day is more than 
	# that months days then day is invaild
	if [ $dd -le 0 -o $dd -gt $days ]; then
		#echo "$dd day is invalid"
		return 3
	fi

	# if no error that means date dd/mm/yyyy is valid one
	#echo "$dd/$mm/$yy is a vaild date"
	#echo "$yy-$mm-$dd is a valid date"
	#echo "valid"
	return 0
}

# usage: days_of_month <mm> <yyyy>
# 获取yyyy年mm月的天数,注意参数顺序
# 比如:days_of_month 2 2007 结果是28
days_of_month()
{
	# store day, month and year
	mm=$1
	yy=$2

	# store number of days in a month
	days=0

	# get day, month and year
	#echo -n "Enter day (dd) : "
	#read dd

	#echo -n "Enter month (mm) : "
	#read mm

	#echo -n "Enter year (yyyy) : "
	#read yy

	# if month is negative (<0) or greater than 12 
	# then it is invalid month
	if [ $mm -le 0 -o $mm -gt 12 ]; then
		#echo "$mm is invalid month."
		echo -1
		return 1
	fi

	# Find out number of days in given month
	case $mm in 
		1) days=31;;
		01) days=31;;
		2) days=28 ;;
		02) days=28 ;;
		3) days=31 ;;
		03) days=31 ;;
		4) days=30 ;;
		04) days=30 ;;
		5) days=31 ;;
		05) days=31 ;;
		6) days=30 ;;
		06) days=30 ;;
		7) days=31 ;;
		07) days=31 ;;
		8) days=31 ;;
		08) days=31 ;;
		9) days=30 ;;
		09) days=30 ;;
		10) days=31 ;;
		11) days=30 ;;
		12) days=31 ;;
		*) days=-1;;
	esac

	# find out if it is a leap year or not

	if [ $mm -eq 2 ]; then # if it is feb month then only check of leap year
		if [ $((yy % 4)) -ne 0 ] ; then
			: #  not a leap year : means do nothing and use old value of days
		elif [ $((yy % 400)) -eq 0 ] ; then
			# yes, it's a leap year
			days=29
		elif [ $((yy % 100)) -eq 0 ] ; then
			: # not a leap year do nothing and use old value of days
		else
			# it is a leap year
			days=29
		fi
	fi

	echo $days
}

 

文件:test_datetime.sh

#!/bin/sh

# TODO: 注意根据datetime.sh的实际位置更改
. /opt/shtools/commons/datetime.sh

echo "当前时间(date):$(date)"
echo "昨天(yesterday):$(yesterday)"
echo "今天(today):$(today)"
echo "现在(now):$(now)"
echo "现在(curtime):$(curtime)"
echo "上月(last_month):$(last_month)"
echo "上月(last_month_packed):$(last_month_packed)"
echo "上月第一天(first_date_of_last_month):$(first_date_of_last_month)"
echo "上月最后一天(last_date_of_last_month):$(last_date_of_last_month)"
echo "今天星期几(day_of_week):$(day_of_week)"
echo "上个小时(last_hour):$(last_hour)"
echo "当前的小时(the_hour):$(the_hour)"
echo "当前的分钟(the_minute):$(the_minute)"
echo "当前的秒钟(the_second):$(the_second)"
echo "当前的年份(the_year):$(the_year)"
echo "当前的月份(the_month):$(the_month)"
echo "当前的日期(the_date):$(the_date)"
echo "前天(days_ago 2):$(days_ago 2)"
echo "明天(days_ago -1):$(days_ago -1)"
echo "后天(days_ago -2):$(days_ago -2)"
echo "十天前的日期(days_ago 10):$(days_ago 10)"
echo "中文的日期星期(chinese_date_and_week):$(chinese_date_and_week)"
echo "随机数字(rand_digit):$(rand_digit)"
echo "随机数字(rand_digit):$(rand_digit)"
echo "自1970年来的秒数(seconds_of_date):$(seconds_of_date)"
echo "自1970年来的秒数(seconds_of_date 2010-02-27):$(seconds_of_date 2010-02-27)"
echo "自1970年来的秒数(seconds_of_date 2010-02-27 15:53:21):$(seconds_of_date 2010-02-27 15:53:21)"
echo "自1970年来的秒数对应的日期(date_of_seconds 1267200000):$(date_of_seconds 1267200000)"
echo "自1970年来的秒数对应的日期时间(datetime_of_seconds 1267257201):$(datetime_of_seconds 1267257201)"

if leap_year 2010; then
	echo "2010年是闰年";
fi
if leap_year 2008; then
	echo "2008年是闰年";
fi
if validity_of_date 2007 02 03; then
	echo "2007 02 03 日期合法"
fi
if validity_of_date 2007 02 28; then
	echo "2007 02 28 日期合法"
fi
if validity_of_date 2007 02 29; then
	echo "2007 02 29 日期合法"
fi
if validity_of_date 2007 03 00; then
	echo "2007 03 00 日期合法"
fi

echo "2010年2月的天数(days_of_month 2 2010):$(days_of_month 2 2010)"
echo "2008年2月的天数(days_of_month 2 2008):$(days_of_month 2 2008)"

 

文件:test_datetime.txt

 
当前时间(date):六  2月 27 15:58:28 CST 2010
昨天(yesterday):2010-02-26
今天(today):2010-02-27
现在(now):2010-02-27 15:58:28.734817000
现在(curtime):2010-02-27 15:58:28
上月(last_month):2010-01
上月(last_month_packed):201001
上月第一天(first_date_of_last_month):2010-01-01
上月最后一天(last_date_of_last_month):2010-01-31
今天星期几(day_of_week):6
上个小时(last_hour):2010-02-27-14
当前的小时(the_hour):15
当前的分钟(the_minute):58
当前的秒钟(the_second):28
当前的年份(the_year):2010
当前的月份(the_month):2
当前的日期(the_date):27
前天(days_ago 2):2010-02-25
明天(days_ago -1):2010-02-28
后天(days_ago -2):2010-03-01
十天前的日期(days_ago 10):2010-02-17
中文的日期星期(chinese_date_and_week):2月27日 星期六
随机数字(rand_digit):5
随机数字(rand_digit):9
自1970年来的秒数(seconds_of_date):1267257508
自1970年来的秒数(seconds_of_date 2010-02-27):1267200000
自1970年来的秒数(seconds_of_date 2010-02-27 15:53:21):1267257201
自1970年来的秒数对应的日期(date_of_seconds 1267200000):2010-02-27
自1970年来的秒数对应的日期时间(datetime_of_seconds 1267257201):2010-02-27 15:53:21
2008年是闰年
2007 02 03 日期合法
2007 02 28 日期合法
2010年2月的天数(days_of_month 2 2010):28
2008年2月的天数(days_of_month 2 2008):29
1
2
分享到:
评论

相关推荐

    自定义函数实现linux ls -a -l 命令_ls函数linux_自定义函数实现linux命令_

    在Linux操作系统中,`ls`命令是一个非常基础且常用的工具,用于列出目录中的文件和子目录。`ls -a -l`是`ls`命令的一个组合选项,它提供了丰富的信息展示,包括隐藏文件(以`.`开头的文件)以及每个文件或目录的详细...

    《Learning the bash Shell,3rd Edition,by Cameron Newham》.pdf

    - 介绍bash中的基本文件操作,如创建、删除和移动文件。 - **1.7 输入和输出** - 描述标准输入、标准输出和标准错误的概念。 - **1.8 后台作业** - 解释如何将任务放到后台运行以及如何管理这些任务。 - **1.9...

    ch8 Bash编程1

    Bash编程,也被称为Shell脚本编程,是Linux和Unix系统中常用的一种自动化任务执行方式。它利用Bourne-Again SHell (Bash) —— Linux默认的Shell,来编写一系列可执行的命令,形成一个可执行文件。Shell脚本能够帮助...

    高级Bash脚本编程指南

    Bash允许创建自定义函数,提升代码复用性。如: ```bash myfunc() { echo "Hello, $1!" } myfunc "World" ``` ### 3. 数组 不同于许多编程语言,Bash中的数组是索引从0开始的。声明数组: ```bash arr=("apple" ...

    shell脚本学习,高级Bash脚本

    Bash(Bourne-Again SHell)是Unix/Linux系统中最常用的Shell,因此深入理解并掌握高级Bash脚本编写技巧对于提升工作效率至关重要。 **一、Bash脚本基础** 1. **变量**:在Bash脚本中,变量用于存储数据。声明变量...

    Linux各种shell的区别

    3. **别名和函数**:与ksh一样,Bash也支持命令别名和自定义函数。 4. **历史扩展**:除了基本的历史命令回溯,还支持历史替换(!)和其他高级历史功能。 5. **作业控制**:如同csh,Bash也提供作业控制功能。 在...

    bash_shell@鸟哥

    Bash(Bourne-Again SHell)是Linux中最常用的一种shell,它基于早期的Bourne Shell (`sh`)并添加了许多新特性。Bash支持命令历史、别名定义、命令行编辑等功能,并且可以运行复杂的shell脚本。它还支持各种环境变量...

    react-reactdaterangepicker基于react的日期范围选择组件

    4. **事件回调**:提供了丰富的事件回调函数,如`onApply`、`onCancel`,以便在用户选择日期范围后执行相应的操作。 5. **日期格式化**:可以设置日期格式,以显示用户友好的日期字符串。 6. **预设日期范围**:...

    终极Shell——Zsh 转载

    - **函数定义**:用户可以定义自定义函数,实现特定功能。 - **插件管理**:Zsh有众多插件,如`oh-my-zsh`,可以通过`.zshrc`加载和配置。 - **提示符设置**:通过`PS1`变量定义提示符格式,可以包含日期、用户名...

    bash:Bash脚本

    - **Shell函数**:创建自定义函数,提高代码复用性。 - **Shell重定向**:使用`&gt;`、`、`&gt;&gt;`等操作符改变输入/输出流。 - **管道**:`|`符号用于连接命令,将一个命令的输出作为另一个命令的输入。 6. **调试与...

    shell 报时 time

    Bash是目前最常用的Linux默认shell,提供了丰富的命令行操作和脚本编程能力。在编写Shell脚本时,我们可以利用内置的命令、变量、控制结构以及函数来实现各种复杂的任务。 报时功能通常涉及到`date`命令,这是Linux...

    Python库 | dt_utils-0.0.1-py3-none-any.whl

    在Python中,这类库通常提供方便的数据转换、分析和时间日期相关的便捷函数。下面我们将深入探讨这个库可能包含的一些关键知识点: 1. **数据处理**: - 可能包括数据清洗、数据格式转换等功能,如去除重复值、...

    tocc-photo-importer:一个可以轻松将照片导入 Tocc 的 bash 脚本

    4. **函数**:Bash 脚本可以定义函数,封装常用操作,提高代码复用性。在 Tocc-photo-importer 中,可能有专门的函数负责验证图片,或者处理单个图片的导入。 5. **错误处理**:良好的脚本会包含错误处理机制,比如...

    Linux-101-Hacks

    通过自定义函数,可以自动纠正错误拼写的目录名。 ```bash cd() { [ -d "$1" ] && builtin cd "$1" || echo "No such directory." } ``` ### Chapter 2: Essential Linux Commands #### Hack 7. Grep Command `...

    Unix系统用户登录、操作命令日志配置方法-(二)+Linux篇+Korn+Shell.doc

    Korn Shell(ksh)是Unix和Linux环境中常用的交互式命令解释器,它也支持自定义脚本。为了记录用户的命令操作,可以通过设置shell的提示符(PS1环境变量)来包含时间戳和其他信息,这样每次用户输入命令时,都会自动...

Global site tag (gtag.js) - Google Analytics