EDIT: Первоначально я сформировал ответ, который работает хорошо на Linux, но не на Solaris. Это намного дольше, с первоначальным ответом ниже.
Для этого просто в оболочке, на Solaris, можно использовать только функцию date
. Вид. Вам нужно будет также создать некоторые функции оболочки, чтобы помочь с вычитанием дней с определенной даты.
Используя функцию ниже, вы можете сделать следующее, чтобы получить желаемые результаты:
$ mydate="$(date '+%Y%m%d')"
$ hours="$(date '+%H')"
$ echo "$(date_subtract "${mydate}" 30)${hours}" | adb
или что-то подобное ...
В Solaris, команда date
только обеспечивает григорианские даты.С этим труднее работать с целью этого вопроса, поэтому я создал функцию оболочки gregorian_to_julian
, которая может конвертировать дату в формате «YYYYMMDD» в юлианскую дату «YYYYDDD».
function gregorian_to_julian {
# "Expecting input as YYYYMMDD."
typeset gregorian_date=$1
typeset _year=$(echo "${gregorian_date}" | cut -c1-4)
typeset _month=$(echo "${gregorian_date}" | cut -c5-6)
typeset _day=$(echo "${gregorian_date}" | cut -c7-8)
typeset days
days[01]=31
days[02]=$((days[01] + 28))
if ((_year % 4 == 0)) && ((_year % 100 != 0)) || ((_year % 400 == 0)); then
days[02]=$((days[01] + 29))
fi
days[03]=$((31 + days[02]))
days[04]=$((30 + days[03]))
days[05]=$((31 + days[04]))
days[06]=$((30 + days[05]))
days[07]=$((31 + days[06]))
days[08]=$((31 + days[07]))
days[09]=$((30 + days[08]))
days[10]=$((31 + days[09]))
days[11]=$((30 + days[10]))
typeset julian_date=0
case "${_month}" in
"01") julian_date=$_day ;;
"02") julian_date=$((days[01] + _day)) ;;
"03") julian_date=$((days[02] + _day)) ;;
"04") julian_date=$((days[03] + _day)) ;;
"05") julian_date=$((days[04] + _day)) ;;
"06") julian_date=$((days[05] + _day)) ;;
"07") julian_date=$((days[06] + _day)) ;;
"08") julian_date=$((days[07] + _day)) ;;
"09") julian_date=$((days[08] + _day)) ;;
"10") julian_date=$((days[09] + _day)) ;;
"11") julian_date=$((days[10] + _day)) ;;
"12") julian_date=$((days[11] + _day)) ;;
esac
julian_date="${_year}${julian_date}"
echo "${julian_date}"
}
Понимание того, что ОП хочет дату отформатированный как григорианский дату, я создал вторую функцию, которая преобразует julian_to_gregorian
дату юлианского обратно.
function julian_to_gregorian {
# "Expecting input as YYYYDDD."
#set -x
typeset julian_date=$1
typeset _year="$(echo "${julian_date}" | cut -c1-4)"
typeset _month=""
typeset julian_day="$(echo "${julian_date}" | cut -c5-7)"
typeset -RZ2 _day=0
typeset days
days[01]=31
days[02]=$((days[01] + 28))
if ((_year % 4 == 0)) && ((_year % 100 != 0)) || ((_year % 400 == 0)); then
days[02]=$((days[01] + 29))
fi
days[03]=$((31 + days[02]))
days[04]=$((30 + days[03]))
days[05]=$((31 + days[04]))
days[06]=$((30 + days[05]))
days[07]=$((31 + days[06]))
days[08]=$((31 + days[07]))
days[09]=$((30 + days[08]))
days[10]=$((31 + days[09]))
days[11]=$((30 + days[10]))
if ((days[11] < julian_day)); then _month="12"; _day=$((julian_day - days[11]));
elif ((days[10] < julian_day)); then _month="11"; _day=$((julian_day - days[10]));
elif ((days[09] < julian_day)); then _month="10"; _day=$((julian_day - days[09]));
elif ((days[08] < julian_day)); then _month="09"; _day=$((julian_day - days[08]));
elif ((days[07] < julian_day)); then _month="08"; _day=$((julian_day - days[07]));
elif ((days[06] < julian_day)); then _month="07"; _day=$((julian_day - days[06]));
elif ((days[05] < julian_day)); then _month="06"; _day=$((julian_day - days[05]));
elif ((days[04] < julian_day)); then _month="05"; _day=$((julian_day - days[04]));
elif ((days[03] < julian_day)); then _month="04"; _day=$((julian_day - days[03]));
elif ((days[02] < julian_day)); then _month="03"; _day=$((julian_day - days[02]));
elif ((days[01] < julian_day)); then _month="02"; _day=$((julian_day - days[01]));
else
_month="01"; _day=${julian_day};
fi
echo "${_year}${_month}${_day}"
}
Третья функция, date_subtract
, принимает григорианскую дату, преобразует его в Julian, делает дату математику, и преобразует обратно в григорианский.
function date_subtract {
typeset julian_from_date=$(gregorian_to_julian "$1")
typeset number_of_days=$2
typeset julian_year=$(echo "${julian_from_date}" | cut -c1-4)
typeset julian_days=$(echo "${julian_from_date}" | cut -c5-7)
typeset leap_year="FALSE"
if ((julian_days - number_of_days > 0)); then
((julian_days -= number_of_days))
else
((julian_year -= 1))
if ((julian_year % 4 == 0)) && ((julian_year % 100 != 0)) || ((julian_year % 400 == 0)); then
leap_year="TRUE"
fi
if [[ "${leap_year}" == "TRUE" ]]; then
((julian_days = julian_days + 366 - number_of_days))
else
((julian_days = julian_days + 365 - number_of_days))
fi
fi
typeset gregorian_date=$(julian_to_gregorian "${julian_year}${julian_days}")
echo "${gregorian_date}"
}
EDIT: Следующие работы хорошо на Linux. И намного проще.
Если вам нужна дата, отформатированная как YYMMDDHH
, тогда это достаточно просто, как @FrankH. Как отметил в своем комментарии:
date +"%Y%m%d%H"
хитрее часть вычисления даты 30 дней назад, который, кажется, ваше намерение. Команда date
может занять секунды с эпохи и преобразовать ее в строку даты. Это делается с флагом -d
. например
$ date -d @123456789
Thu Nov 29 15:33:09 CST 1973
Так что, если вам нужна дата тридцать дней назад, мы можем принять этот принцип и сделать немного математики, чтобы получить нужное значение.
Обратите внимание, что date '+%s'
дает нам секунд с эпохи.
$ date -d @$(($(date '+%s') - $((60 * 60 * 24 * 30)))) '+%Y%m%d%H'
2014011211
Если вам нужно труба, датирующая строку adb
, то вы можете окружить команду с $ (...).
echo $(date -d @$(($(date '+%s') - $((60 * 60 * 24 * 30)))) '+%Y%m%d%H') | adb
я должен связать это на meta.stackoverflow.com «XY вопрос» ... почему вы не можете просто позвонить 'дата +"% Y% м% d% H "' (который непосредственно дает выход 'YYYYMMDDHH', см. http://pubs.opengroup.org/onlinepubs/009604599/utilities/date.html для возможностей спецификации формата)? –