Как получить дату 3. среды в месяце - PullRequest
0 голосов
/ 17 октября 2018

Мне нужен пример кода для получения даты 3. среды месяца.Я просто не могу обдумать, как это сделать - последняя среда проста:

cal | awk '/^ *[0-9]/ { d=$4 } END { print d }'

В конечном итоге мне нужен сценарий для возврата «следующей 3. среды» - как если бы мы прошли3. среда этого месяца, верните 3. среду следующего месяца.

Ответы [ 5 ]

0 голосов
/ 17 октября 2018
# Third Wednesday of this month
thirdWednesday=$( cal | cut -c 10-12 | sed '/^\s*$/d' | sed -n '5p' )

# Today
today=$( date +%d )

# If already passed
if [ $today -gt $thirdWednesday ]; then
    # Next month
    nextMonth=$( date +"%m %Y" -d "next month" )

    # Get third Wednesday of next month
    thirdWednesday=$( cal $nextMonth | cut -c 10-12 | sed '/^\s*$/d' | sed -n '5p'  )
fi

# Result
echo $thirdWednesday
0 голосов
/ 17 октября 2018

Вот что я придумал:

#!/bin/bash -xv

CURRENTDAY=$(date +%e)
CURRENTMONTH=$(date +%m)
NEXTMONTH=$(( ${CURRENTMONTH}+1 ))
CURRENTYEAR=$(date +%Y)

WEDNESDAYSFORTHEMONTH=$(cal ${CURRENTMONTH} ${CURRENTYEAR} | awk 'NF <= 7 { print $4 }' | grep -v "^$"| grep -v We)

# I would normally start at 0
COUNTER=1 

#Get this months 3rd Wednesday
for WEDNESDAY in ${WEDNESDAYSFORTHEMONTH}
do
    if [[ ${COUNTER} -eq 3 ]] 
    then
        echo "This months third wednesday is: ${WEDNESDAY}"
        THISMONTHSTHIRDWEDNESDAY=${WEDNESDAY}
    fi
    COUNTER=$(( ${COUNTER}+1 ))

done

# Get the 3rd Wednesday for the next month

WEDNESDAYSFORTHEMONTH=$(cal ${NEXTMONTH} ${CURRENTYEAR} | awk 'NF <= 7 { print $4 }' | grep -v "^$"| grep -v We)
COUNTER=1

for WEDNESDAY in ${WEDNESDAYSFORTHEMONTH}
do
    if [[ ${COUNTER} -eq 3 ]]
    then
        echo "Next months third wednesday is: ${WEDNESDAY}"
        NEXTMONTHSTHIRDWEDNESDAY=${WEDNESDAY}
    fi
    COUNTER=$(( ${COUNTER}+1 ))
done

#Compare the current date with this months 3rd Wednesday
if [[ ${CURRENTDAY} -le ${THISMONTHSTHIRDWEDNESDAY} ]]
then
    echo "Wednesday to use in your script is: ${THISMONTHSTHIRDWEDNESDAY} ${CURRENTMONTH} ${CURRENTYEAR}"
else
    echo "Wednesday to use in your script is: ${NEXTMONTHSTHIRDWEDNESDAY} ${NEXTMONTH} ${CURRENTYEAR}"
fi
0 голосов
/ 17 октября 2018

если у вас есть ncal

$ ncal | awk '/We/{print $4}'

ncal, формат транспонируется в cal, и работа с строками проще.Третья среда - четвертое поле.

$ ncal

    October 2018
Su     7 14 21 28
Mo  1  8 15 22 29
Tu  2  9 16 23 30
We  3 10 17 24 31
Th  4 11 18 25
Fr  5 12 19 26
Sa  6 13 20 27

, например, для ноября

$ ncal -m 11

    November 2018
Su     4 11 18 25
Mo     5 12 19 26
Tu     6 13 20 27
We     7 14 21 28
Th  1  8 15 22 29
Fr  2  9 16 23 30
Sa  3 10 17 24

$ ncal -m 11 | awk '/We/{print $4}'

21
0 голосов
/ 17 октября 2018

Вот простой подход, который будет работать должным образом в большинстве регионов:

#!/bin/bash

export LC_TIME=C
thismonth=$(date +%m)       # this month like "10"
thisyear=$(date +%Y)        # this year like "2018"
firstdayofweek=$(date -d "${thisyear}-${thismonth}-1" +%w)
# calculates the day of week of the 1st day of the month
# returns the number between 0 and 6, where 0=Sun, 1=Mon, ...

wed1=$(( (10 - $firstdayofweek) % 7 + 1 ))
# calculates the day of month of the 1st Wednesday
wed3=$(( $wed1 + 14 ))
# the day of the 3rd Wednsday

echo $wed3

, который на сегодняшний день дает "17".
Было бы легко изменить приведенный выше код для достижения вашей следующей цели.

0 голосов
/ 17 октября 2018

Это не красиво, но в системе GNU / Linux вы можете циклически проходить каждый день месяца и считать:

#!/bin/bash
month="$1"   # e.g. 2018-10
number="$2"  # e.g. 3
weekday="$3" # e.g "Wednesday"

export LC_ALL=C TZ=UTC
date -d today > /dev/null 2>&1 || {
  echo "You are not using GNU date"
  exit 1
}

n="$number"
for day in {1..31}
do
  wd=$(date -d "$month-$day" +"%A" 2>&1) || continue
  if [[ $wd == "$weekday" ]]
  then
    (( --n )) || break
  fi
done

if ! (( n ))
then
  echo "The $weekday number $number in $month is $month-$day"
else
  echo "$month does not have a $weekday number $number"
fi

Тем не менее, обратите внимание, что даты сложны, и этот простой подход может быть неправильнымучитывать различные курьезы, такие как Самоа пропускает пятницу 2011-12-30 из-за сдвига часового пояса.

Вот несколько примеров системы GNU:

$ ./finddate 2018-10 3 Wednesday
The Wednesday number 3 in 2018-10 is 2018-10-17

$ ./finddate 2018-10 5 Thursday
2018-10 does not have a Thursday number 5

Вот пример изсистема без GNU, такая как MacOS:

$ ./finddate 2018-10 3 Wednesday
You are not using GNU date
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...