-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[date/day-of-week] New function to get the day of week for an arbitra…
…ry date
- Loading branch information
1 parent
5943257
commit 88d6d81
Showing
3 changed files
with
144 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
# Prints the ISO day of week for a given date in the Gregorian calendar | ||
# 0 = Sunday, 1 = Monday, ..., 6 = Saturday | ||
# | ||
# This implementation works for all dates since the introduction of the | ||
# Gregorian calendar. | ||
# | ||
# Usage: | ||
# - day-of-week year month day | ||
# - day-of-week 1970 1 1 | ||
# - day-of-week 2020 2 29 | ||
# - day-of-week 2070 10 20 | ||
|
||
: "${1:?missing year}" "${2:?missing month}" "${3:?missing day}" | ||
# remove leading zeroes from arguments to prevent them from being interpreted | ||
# as octal. The year is ignored because the Gregorian calendar was only | ||
# introduced in the 16th century. | ||
set -- "${1}" "${2#0}" "${3#0}" | ||
|
||
# RFC 3339, Appendix B | ||
|
||
set -- $(($2 >= 3 ? $1 : ($1 - 1))) $(($2 >= 3 ? ($2 - 2) : ($2 + 10))) $(($3)) | ||
echo $(( | ||
( | ||
(26 * $2 - 2) / 10 | ||
+ $3 | ||
+ ($1 % 100) | ||
+ (($1 % 100) / 4) | ||
+ ($1 / 400) | ||
+ (5 * ($1 / 100)) | ||
) % 7 | ||
)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
Describe 'date/day-of-week' | ||
EnableSandbox | ||
|
||
EnableLeakDetector | ||
|
||
SetupCommandFromFile day-of-week lib/date/day-of-week.sh | ||
|
||
# check if GNU date(1) is available | ||
case $(@gdate --version 2>/dev/null) | ||
in | ||
(*'GNU coreutils'*) | ||
__have_gdate=1 ;; | ||
(*) | ||
__have_gdate=0 ;; | ||
esac | ||
have_gdate() { | ||
return $((! __have_gdate)) | ||
} | ||
skip_gdate() { | ||
return $((__have_gdate)) | ||
} | ||
|
||
# check if this shell has $RANDOM | ||
have_random_var() { | ||
case ${RANDOM-} in ('') ! : ;; esac | ||
} | ||
|
||
|
||
Context # static test values | ||
Parameters | ||
# year mon day expected day-of-week | ||
1970 1 1 4 | ||
1900 1 1 1 | ||
1900 2 28 3 | ||
1900 2 29 4 # NOTE: this is an invalid date | ||
1900 3 1 4 | ||
2000 1 1 6 | ||
2000 2 28 1 | ||
2000 2 29 2 | ||
2000 3 1 3 | ||
2020 3 1 0 | ||
2024 2 1 4 | ||
2024 2 28 3 | ||
2024 2 29 4 | ||
2024 3 1 5 | ||
End | ||
|
||
It "calculates the day of week for $(@printf '%04u-%02u-%02u' $1 $2 $3)" | ||
When run command day-of-week $1 $2 $3 | ||
|
||
The status should equal 0 | ||
The stdout should equal "$4" | ||
The stderr should equal '' | ||
End | ||
End | ||
|
||
It 'supports parameters with leading 0s' | ||
When run command day-of-week 1970 01 01 | ||
|
||
The status should be success | ||
The output should equal 4 | ||
The error should equal '' | ||
End | ||
|
||
Context # dynamic test values | ||
Parameters:dynamic | ||
n=10 | ||
|
||
if case ${RANDOM-} in ('') ! : ;; esac | ||
then | ||
while test $((n-=1)) -ge 0 | ||
do | ||
Y=$(( 1600 + (RANDOM % 1000) )) | ||
m=$(( 1 + (RANDOM % 12) )) | ||
case ${m} | ||
in | ||
(2) | ||
d=$(( 1 + (RANDOM % (28 + (0==(Y % 4)&&(0!=(Y % 100)||0==(Y % 400))))) )) ;; | ||
(1|3|5|7|8|10|12) | ||
d=$(( 1 + (RANDOM % 31) )) ;; | ||
(*) | ||
d=$(( 1 + (RANDOM % 30) )) ;; | ||
esac | ||
%data $Y $m $d | ||
done | ||
else | ||
: # skip: cannot generate random dates | ||
fi | ||
End | ||
|
||
gdate_check_dow() { | ||
test "${gdate_check_dow}" -eq $(($(TZ=GMT0 @gdate --date="$1" +%u) % 7)) | ||
} | ||
|
||
It "calculates the day of week for $(@printf '%04u-%02u-%02u' $1 $2 $3) (property test)" | ||
Skip if 'date(1) is not GNU date' skip_gdate | ||
|
||
When run command day-of-week $1 $2 $3 | ||
|
||
The status should equal 0 | ||
# NOTE: must check using function to call @gdate only if it is available | ||
The stdout should satisfy gdate_check_dow "$(@printf '%04u-%02u-%02u' $1 $2 $3)" | ||
The stderr should equal '' | ||
End | ||
End | ||
End |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
#!/bin/sh -e | ||
. "$SHELLSPEC_SUPPORT_BIN" | ||
case ${OSTYPE} | ||
in | ||
(*darwin*) invoke gdate "$@" ;; | ||
(*) invoke date "$@" ;; | ||
esac |