Linux 检查参数是否是 bash shell 中的有效日期
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10759162/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
check if argument is a valid date in bash shell
提问by Gary
I am writing a bash shell script in Linux, this program will accept a date (mm-dd-yyyy) as a parameter. I am wondering if there is a simply way to check if the date is valid? is there an operator and I can just use test to check?
我正在 Linux 中编写 bash shell 脚本,该程序将接受日期 (mm-dd-yyyy) 作为参数。我想知道是否有一种简单的方法可以检查日期是否有效?是否有操作员,我可以使用测试来检查?
采纳答案by johnshen64
You can check with date -d "datestring"
你可以检查 date -d "datestring"
So date -d "12/31/2012"
is valid, but using hyphens, e.g. date -d "12-31-2012"
, is not valid for date
.
Sodate -d "12/31/2012"
是有效的,但使用连字符,例如date -d "12-31-2012"
,对 无效date
。
You can also use words: date -d 'yesterday'
or date -d '1 week ago'
are both valid.
您也可以使用单词:date -d 'yesterday'
或date -d '1 week ago'
两者都有效。
回答by shellter
case statements make it easy to support multiple formats and capturing date-parts, i.e.
case 语句可以轻松支持多种格式和捕获日期部分,即
case ${date} in
[0-3][0-9]-[0-1][0-9]-[0-9][0-9][0-9][0-9] )
yr=...
mn=...
dy=...
;;
[0-1][0-9]-[0-3][0-9]-[0-9][0-9][0-9][0-9] )
yr=...
dy=...
mn=...
;;
.... other formats
;;
* )
echo "ERROR on date format, from value=$date, expected formats ..."
return 1
;;
esac
I hope this helps.
我希望这有帮助。
回答by Paused until further notice.
You can use the strptime()
function available in Python's timeor datetimemodules or Perl's Time::Piecemodule.
您可以使用strptime()
Python 的time或datetime模块或 Perl 的Time::Piece模块中可用的函数。
回答by Steve Goossens
You can extract the day, month, and year values from the input date value MM-DD-YYYY and validate it as the unambiguous (ISO) format YYYY-MM-DD instead (you can validate a DD-MM-YYY formatted date as "correct" using date, e.g. 25-12-2010, but it is not a valid MM-DD-YYY date, hence the need to change the date format first)
您可以从输入日期值 MM-DD-YYYY 中提取日、月和年值,并将其验证为明确的 (ISO) 格式 YYYY-MM-DD(您可以将 DD-MM-YYY 格式的日期验证为“正确”使用日期,例如 25-12-2010,但它不是有效的 MM-DD-YYY 日期,因此需要先更改日期格式)
A valid date in the correct format is OK
格式正确的有效日期是可以的
30th November 2005 is valid:
2005 年 11 月 30 日有效:
$ DATE=11-30-2005; d=${DATE:3:2}; m=${DATE:0:2}; Y=${DATE:6:4}; echo "year=$Y, month=$m, day=$d"; if date -d "$Y-$m-$d" &> /dev/null; then echo VALID; else echo INVALID; fi
year=2005, month=11, day=30
VALID
$ DATE=11-30-2005; if date -d "${DATE:6:4}-${DATE:0:2}-${DATE:3:2}" &> /dev/null; then echo VALID; else echo INVALID; fi
VALID
An invalid date in the correct format is NOT OK
格式正确的无效日期不正常
31st November 2005 does not validate:
2005 年 11 月 31 日不验证:
$ DATE=11-31-2005; d=${DATE:3:2}; m=${DATE:0:2}; Y=${DATE:6:4}; echo "year=$Y, month=$m, day=$d"; if date -d "$Y-$m-$d" &> /dev/null; then echo VALID; else echo INVALID; fi
year=2005, month=11, day=31
INVALID
$ DATE=11-31-2005; if date -d "${DATE:6:4}-${DATE:0:2}-${DATE:3:2}" &> /dev/null; then echo VALID; else echo INVALID; fi
INVALID
A valid date in the incorrect format is NOT OK
格式不正确的有效日期不正确
20th April 1979 in DD-MM-YYYY format does not validate as a MM-DD-YYYY date:
DD-MM-YYYY 格式的 1979 年 4 月 20 日未验证为 MM-DD-YYYY 日期:
$ DATE=20-04-1979; d=${DATE:3:2}; m=${DATE:0:2}; Y=${DATE:6:4}; echo "year=$Y, month=$m, day=$d"; if date -d "$Y-$m-$d" &> /dev/null; then echo VALID; else echo INVALID; fi
year=1979, month=20, day=04
INVALID
$ DATE=20-04-1979; if date -d "${DATE:6:4}-${DATE:0:2}-${DATE:3:2}" &> /dev/null; then echo VALID; else echo INVALID; fi
INVALID
Alternate simpler method: use BASH variable string replace hyphens to slashes
另一种更简单的方法:使用 BASH 变量字符串替换连字符到斜线
$ DATE="04-30-2005"; [[ $(date -d "${DATE//-/\/}" 2> /dev/null) ]] && echo VALID || echo INVALID
VALID
$ DATE="04-31-2005"; [[ $(date -d "${DATE//-/\/}" 2> /dev/null) ]] && echo VALID || echo INVALID
INVALID
回答by user3182475
The following worked well for me. Many thanks to my co-worker, Tyler Chamberlain, for the OSX solution.
以下对我来说效果很好。非常感谢我的同事 Tyler Chamberlain 提供的 OSX 解决方案。
# Validate a given date/time in Bash on either Linux or Mac (OSX).
# Expected date/time format (in quotes from the command line): YYYY-MM-DD HH:MM:SS
# Example(s): ./this_script "2012-02-29 13:00:00" # IS valid
# ./this_script "2013-02-29 13:00:00" # Is NOT valid
START_DATETIME=
function report_error_and_exit
{
local MSG=
echo "$MSG" >&2
exit 1
}
# We can use OSTYPE to determine what OS we're running on.
# From http://stackoverflow.com/questions/394230/detect-the-os-from-a-bash-script
# Determine whether the given START_DATETIME is valid.
if [[ "$OSTYPE" == "linux-gnu" ]]
then
# Validate the date on a Linux machine (Redhat or Debian). On Linux, this is
# as easy as adding one minute and checking the return code. If one minute
# cannot be added, then the starting value is not a valid date/time.
date -d "$START_DATETIME UTC + 1 min" +"%F %T" &> /dev/null
test $? -eq 0 || report_error_and_exit "'$START_DATETIME' is not a valid date/time value. $OSTYPE"
elif [[ "$OSTYPE" == "darwin"* ]]
then
# Validate the date on a Mac (OSX). This is done by adding and subtracting
# one minute from the given date/time. If the resulting date/time string is identical
# to the given date/time string, then the given date/time is valid. If not, then the
# given date/time is invalid.
TEST_DATETIME=$(date -v+1M -v-1M -jf "%F %T" "$START_DATETIME" +"%F %T" 2> /dev/null)
if [[ "$TEST_DATETIME" != "$START_DATETIME" ]]
then
report_error_and_exit "'$START_DATETIME' is not a valid date/time value. $OSTYPE"
fi
fi
echo "The date/time is valid."
I tested this script on a Red Hat-based system, a Debian-based system and OSX, and it worked as expected on all three platforms. I did not have time to test on Windows (Cygwin).
我在基于 Red Hat 的系统、基于 Debian 的系统和 OSX 上测试了这个脚本,它在所有三个平台上都按预期工作。我没有时间在 Windows (Cygwin) 上进行测试。
回答by D LaMarche
For script use, I kept it as simple as I could. Testing the date value with the date function then checking the exit code of the process.
对于脚本使用,我尽可能地保持简单。使用 date 函数测试日期值,然后检查进程的退出代码。
date -d "02/01/2000" 2>: 1>:; echo $?
This will redirect the standard in and standard error to null :
and using echo to return the exit code with $?
allows me to check for 0=good date and 1=bad date.
这会将标准输入和标准错误重定向到 null:
并使用 echo 返回退出代码,$?
允许我检查 0=good date 和 1=bad date。
回答by eeasterly
For validation of YYYY-MM-DD (ISO 8601) dates on OSX in the BASH shell, the following approach validates both the format and the date.
为了在 BASH shell 中的 OSX 上验证 YYYY-MM-DD (ISO 8601) 日期,以下方法验证格式和日期。
isYYYYMMDDdate() {
[[ "" =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}$ ]] && [[ "" == $(date -r $(date -j -f "%Y-%m-%d" "" "+%s") '+%Y-%m-%d') ]] &> /dev/null; echo "$?"
}
- It first uses a regular expression match to check the format.
- Then, it converts the date to epoch time and then back to a date.
- If the original and twice-converted dates match, then it is valid.
- 它首先使用正则表达式匹配来检查格式。
- 然后,它将日期转换为纪元时间,然后再转换回日期。
- 如果原始日期和两次转换的日期匹配,则它是有效的。
Test a valid date: 2005-11-30
测试有效日期:2005-11-30
$ isYYYYMMDDdate 2005-11-30
0
Test an invalid date: 2005-11-31
测试无效日期:2005-11-31
$ isYYYYMMDDdate 2005-11-31
1
Test a valid date formatted incorrectly: 1979-20-04
测试格式不正确的有效日期:1979-20-04
$ isYYYYMMDDdate 1979-20-04
1
回答by Stephen Ostermiller
The date
command will parse a date given with the -d
argument. If the date is invalid, an error message is printed to STDERR and date
exits with an error status. If the date is valid, it prints the date on STDOUT and exits with a success status.
该date
命令将解析-d
参数给出的日期。如果日期无效,则会向 STDERR 打印一条错误消息并date
以错误状态退出。如果日期有效,它将在 STDOUT 上打印日期并以成功状态退出。
Because of this, date -d "$date"
can be used directly in a bash
if
statement.
正因为如此,date -d "$date"
可以直接在bash
if
语句中使用。
The first wrinkle is that to prevent printing a message for valid dates, you need to redirect STDOUT to /dev/null
using >/dev/null
.
第一个问题是为了防止打印有效日期的消息,您需要将 STDOUT 重定向到/dev/null
使用>/dev/null
.
The second wrinkle is that date
accepts an empty string as a valid date without complaint. In most cases, that should mean that your user didn't enter a date when they should have. You will want to test for an empty date separately using the test [ "z$date" != "z" ]
第二个问题是date
接受空字符串作为有效日期而没有抱怨。在大多数情况下,这应该意味着您的用户没有输入他们应该输入的日期。您将需要使用测试单独测试一个空日期[ "z$date" != "z" ]
date
also accepts a variety of formats. If you are using actual bash
(as opposed to dash
or some of ther sh
variety, you could use regular expressions against your preferred format in place of a simple check for an empty string. For example to check my preferred ISO format, I would use: [[ "$date" =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}$ ]]
date
也接受多种格式。如果您使用的是实际的bash
(而不是dash
其中的一些sh
,您可以针对您的首选格式使用正则表达式,而不是简单地检查空字符串。例如,要检查我首选的 ISO 格式,我会使用: [[ "$date" =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}$ ]]
date=2001-01-01
if [ "z$date" != "z" ] && date -d "$date" >/dev/null
then
echo "VALID DATE"
fi
If you try this with an invalid date (such as 2001-01-53
), it doesn't get into the if
and it prints out:
如果您使用无效日期(例如2001-01-53
)尝试此操作,它不会进入if
并打印出:
date: invalid date ‘2001-01-53'
日期:无效日期“2001-01-53”
Alternately, you could check if the date is invalid and exit:
或者,您可以检查日期是否无效并退出:
date=2001-01-01
if [ "z$date" == "z" ]
then
echo "No date specified"
exit 1
fi
if ! [[ "$date" =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}$ ]]
then
echo "Expected date in YYYY-MM-DD format"
exit 1
fi
if ! date -d "$date" >/dev/null
then
exit 1
fi
echo "VALID DATE"