Як генерувати дату чверть кварталу з командного рядка?


10

Мені цікаво представити представлення поточного кварталу року, а також кварталу року за попередній місяць.

Якщо сьогодні 2012 рік, 1 січня, я хотів би отримати

2012q1

і

2011q4

як відповідні виходи.

Відповіді:


10

Одне (якесь потворне) рішення, що використовує арифметичну оцінку BASH та команду GNU date:

echo $(date +%Y)q$(( ($(date +%-m)-1)/3+1 ))
echo $(date -d "-1 month" +%Y)q$(( ($(date -d "-1 month" +%-m)-1)/3+1 ))

Зверніть увагу, що %-mзапобігання dateвід 0-прокладки, тому це все ще працюватиме в серпні та вересні.


2
Візьміть $ (...) замість застарілих задників. Вони легко вкладаються.
користувач невідомий

1
просто будьте цікаві: чому інші відповіді використовують 4 як дільник.
LiuYan 刘 研

2
@LiuYan 刘 研: Не впевнений. У кварталі є 3 місяці, тому я думаю, що 3 - це правильний подільник. (Хоча це спочатку і мене бентежило.)
smokris

У вересні %mдає, 09який баш намагається інтерпретувати як восьмеричний через провідний 0, тому це видає помилку, яка говорить 09: value too great for base (error token is "09"). Це можна виправити, відключивши 0-padding, змінивши %mна %-m.
Матвій

5

Використовувати мої дати :

dconv 2012-01-01 -f '%Y%Q'
=>
  2012Q1

%qІ %Qпрапори є специфічними для dateutils, і повернути чверть як число або в формі Q<NUMBER>.


dconv now -f%Y%Q | tr Q qякщо вам дійсно потрібен цей Q, щоб він був нижчим. (PS: ми dateddateconv
упаковуємо

5

Усі рішення, які діляться на чотири, провалюються, наприклад листопад:

% echo $(( 11/4+1 ))
3

Правильною математикою було б:

$(( (m-1)/3 +1 ))

І як такий, квартал поточного та попереднього місяця буде таким:

echo curr ${y}q$(((m-1)/3+1))
if [ $m = 1 ]; then
  echo prev $((y-1))q4
else
  echo prev ${y}q$(((m-2)/3+1))
fi

Це перевірити лише дванадцять значень…

% for m in {1..12}; do echo $m Q$(((m-1)/3+1)); done
1 Q1
2 Q1
3 Q1
4 Q2
5 Q2
6 Q2
7 Q3
8 Q3
9 Q3
10 Q4
11 Q4
12 Q4

1
+1 Для "Усі рішення, які поділяються на помилки". Ти правий! Чверть триває 3 місяці, тож відповіді слід розділити на 3.
Стівен Куан

4

Напевно, прямого рішення немає.

Ви можете використовувати, awkщоб уникнути стільки зворотних кліщів.

date +"%Y %m" | awk '{q=int($2/4)+1; printf("%sq%s\n", $1, q);}'
date +"%Y %m" | awk '{q=int($2/4);y=$1;if (q==0){q=4;y=y-1;}; printf("%sq%s\n", y, q);}'

perlРішення було б чистіше , але perlі DateTimeє важким умовою.

#!/usr/bin/perl

use DateTime;

my $today = DateTime->now;
print "today: " . $today->year . "q" . $today->quarter . "\n";

my $ago = DateTime->now->subtract( months=> 4);
print "some time ago: " . $ago->year . "q" . $ago->quarter . "\n"

Класно. Мені подобається перший рядок дата / awk, оскільки він уникає виклику (і передачі параметрів) dateдвічі.
smokris

4

Розділіть формат на дату, обчисліть за допомогою awk, формат з printf:

date +"%Y %m" | awk '{printf ("%4dq%1d\n", $1, ($2/4)+1)}'

Тільки дата і баш:

echo $(date +%Yq)$(($(date +%m)/4+1))

Перший рядок виводить 2012q0неправильно.
смокрис

@smokris: Ти маєш рацію - я вибрав неправильну лінію своїх тестів.
користувач невідомий

4

Альтернатива, більше як цікавість. Якщо GNU awkзадіяний, dateвін не потрібен:

awk 'BEGIN{print strftime("%Y")"q"int((strftime("%-m")-1)/3)+1}'

3

Зателефонуйте, dateщоб отримати поточний рік та місяць, а решта виконайте з арифметикою в оболонці.

set $(date '+%Y %m');
this_quarter=${1}q$(($2 / 4 + 1))
if [ $2 -eq 1 ]; then
  last_month_quarter=$(($1 - 1))q4
else
  last_month_quarter=${1}q$((($2 - 1) / 4 + 1))
fi

2

Рік-квартал для цього місяця

date +"%Yq$(expr $(expr $(date +%m) - 1) / 3 + 1)"

Рік-квартал для місяця-юстера

date +"%Yq$(expr $(expr $(date -d '-1 month' +%m) - 1) / 3 + 1)"

2

Основна математика для цього кварталу та кварталу минулого місяця:

y1=$(date +%Y)
m1=$(date +%m)
q1=$(( (m1 - 1) / 3 + 1))
y2=$(( y1 - (m1 == 1) ))
m2=$(( (m1 + 10) % 12 + 1 ))
q2=$(( (m2 - 1) / 3 + 1 ))
echo This Quarter: $((y1))q$q1
echo Last Month Quarter: $((y2))q$q2

Сценарій використовує такі частини:

  1. $ (unix-cmd) - оцінює команду в скрипті оболонки
  2. $ ((expr)) - оцінює математичний вираз
  3. переоформлення 1..12 -> 1..4 використовує наступну математику (m-1) / 3 + 1
  4. при оцінці попереднього місяця використовується модульна математика

2

Зараз існує %qформат показу цієї інформації.

З журналу випуску coreutils-8.26 від 30 листопада 2016 року:

Нові функції
...
дата тепер приймає формат% q для виведення на чверть року.

І так, це працює!

$ date "+%q"
4
$ date "+%Yq%q"
2016q4

0

Якщо ви хочете, щоб фінансовий 13-тижневий квартал, який базується на календарі тижня ISO, тоді новий зручний% q не буде працювати, на жаль. Ось версія безрезультатного рішення @ manatwork з awk / strearch.

awk 'BEGIN{$x=int((strftime("%V")-1)/13)+1;print strftime("%G")"q"($x>4?4:$x)}'

Останній маленький потрійний шматочок обробляє ISO-високосні роки, де в останній чверті 14 тижнів.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.