如何从命令行生成年份-季度日期?


10

我有兴趣输出当前年度季度以及上个月的年度季度的表示形式。

如果今天是2012年1月1日,我想得到

2012q1

2011q4

作为各自的输出。

Answers:


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 ))

请注意,%-mprevents datefrom 0-padding,因此在8月和9月仍然有效。


2
以$(...)代替不推荐使用的反引号。它们可以很容易地嵌套。
用户未知

1
只是好奇:为什么其他答案使用4作为除数。
LiuYan刘研

2
@LiuYan刘研:不确定。一个季度有3个月,因此我认为3是正确的除数。(尽管起初也让我感到困惑。)
smokris

九月%m09bash会为八进制解释这是由于0领先,所以这将引发一个错误,指出09: value too great for base (error token is "09")。可以通过更改%m为禁用0填充来解决此问题%-m
马修(Matthew)

5

使用我的dateutils

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

%q%Q标志是特定于dateutils和季度回报为数字或形式Q<NUMBER>


dconv now -f%Y%Q | tr Q q如果您确实需要将Q小写。(PS:我们将它包装在Fedora中,date使用前缀而不是d,所以用“ dateconv”。)
mattdm 2015年

5

除以四的所有解决方案都会失败,例如11月:

% 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解决办法是清洁的,但perlDateTime是一个沉重的先决条件。

#!/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"

凉。我喜欢第一个日期/行,因为它避免了调用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

@smokris:您是对的-我选择了错误的测试行。
用户未知

4

另一种选择,更多是出于好奇。如果awk涉及GNU ,date则不需要:

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

3

调用date以检索当前的年和月,然后在shell中使用算术进行其余操作。

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)-评估shell脚本中的命令
  2. $((expr))-计算一个数学表达式
  3. 重新映射1..12-> 1..4使用以下数学(m-1)/ 3 + 1
  4. 评估上个月使用模数学


0

如果您想要基于ISO周日历的13周财政季度,那么令人遗憾的是,新的便捷%q将无法正常工作。这是@manatwork的无日期解决方案的awk / strftime版本。

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

最后的三进制位处理ISO leap周年,其中最后一个季度有14周。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.