Làm thế nào để tạo một ngày trong quý từ dòng lệnh?


10

Tôi quan tâm đến việc xuất một đại diện của quý hiện tại, cũng như quý của tháng trước.

Nếu hôm nay là ngày 1 tháng 1 năm 2012, tôi muốn nhận

2012q1

2011q4

như các đầu ra tương ứng.

Câu trả lời:


10

Một giải pháp (xấu xí), sử dụng đánh giá số học BASH và datelệnh GNU :

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

Lưu ý rằng các %-mngăn chặn datetừ 0-padding, vì vậy điều này sẽ vẫn hoạt động cho tháng 8 và tháng 9.


2
Lấy $ (...) thay vì các backticks không dùng nữa. Chúng có thể dễ dàng được lồng nhau.
người dùng không xác định

1
chỉ tò mò: tại sao các câu trả lời khác sử dụng 4 làm ước số.
LiuYan 刘

2
@LiuYan: Không chắc chắn. Có 3 tháng trong một quý, vì vậy tôi nghĩ 3 là ước số chính xác. (Mặc dù lúc đầu cũng làm tôi bối rối.)
smokris

Vào tháng Chín %mcho 09mà cố gắng bash để giải thích như bát phân do nhập số 0 đầu, vì vậy đây ném một lỗi mà nói 09: value too great for base (error token is "09"). Điều này có thể được khắc phục bằng cách vô hiệu hóa 0-padding bằng cách thay đổi %mthành %-m.
Matthew

5

Sử dụng dateutils của tôi :

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

Các cờ %q%Qlà cụ thể cho dateutils, và trả lại quý dưới dạng số hoặc trong biểu mẫu Q<NUMBER>.


dconv now -f%Y%Q | tr Q qnếu bạn thực sự cần Q đó để được hạ thấp. (PS: chúng tôi đóng gói cái này ở Fedora với datetiền tố thay vì tiền tố d, vì vậy " dateconv".)
mattdm

5

Tất cả các giải pháp chia cho bốn lần thất bại, ví dụ tháng 11:

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

Toán học đúng sẽ là:

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

Và như vậy, quý của tháng hiện tại và tháng trước sẽ là:

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

Đó chỉ là mười hai giá trị để kiểm tra

% 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 Đối với "Tất cả các giải pháp chia cho thất bại". Bạn đúng! Một phần tư kéo dài trong 3 tháng, vì vậy các câu trả lời nên được chia cho 3.
Stephen Quan

4

Có lẽ, không có giải pháp trực tiếp.

Bạn có thể sử dụng awkđể tránh rất nhiều dấu hiệu ngược.

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);}'

Một perlgiải pháp sẽ được sạch hơn nhưng perlDateTimelà một điều kiện tiên quyết nặng.

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

Mát mẻ. Tôi thích dòng ngày / awk đầu tiên, vì nó tránh gọi (và truyền tham số đến) datehai lần.
smokris

4

Chia định dạng theo ngày, tính toán với awk, định dạng bằng printf:

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

Chỉ cần hẹn hò và bash:

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

Đầu ra dòng đầu tiên 2012q0không chính xác.
smokris

@smokris: Bạn nói đúng - Tôi đã chọn sai dòng bài kiểm tra của mình.
người dùng không xác định

4

Một thay thế, nhiều hơn như một sự tò mò. Nếu GNU awkcó liên quan, datekhông cần thiết:

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

3

Gọi dateđể lấy năm và tháng hiện tại và thực hiện phần còn lại với số học trong trình bao.

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

Quý của tháng này

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

Năm-quý cho tháng năm

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

2

Toán cơ bản cho quý này và quý trước:

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

Kịch bản sử dụng các phần sau:

  1. $ (unix-cmd) - đánh giá một lệnh trong shell script
  2. $ ((expr)) - đánh giá biểu thức toán học
  3. ánh xạ lại 1..12 -> 1..4 sử dụng phép toán sau (m - 1) / 3 + 1
  4. đánh giá tháng trước sử dụng toán modulo

2

Bây giờ có %qđịnh dạng để hiển thị thông tin này.

Từ nhật ký phát hành coreutils-8.26 từ ngày 30 tháng 11 năm 2016:

Các tính năng mới
...
ngày nay chấp nhận định dạng% q để xuất ra quý của năm.

Và vâng, nó hoạt động!

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

0

Nếu bạn muốn quý 13 tuần tài chính dựa trên lịch tuần ISO, thì% q tiện dụng mới sẽ không hoạt động, thật đáng buồn. Đây là phiên bản của giải pháp dữ liệu của @ manatwork với awk / strftime

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

Bit ternary nhỏ cuối cùng xử lý các năm nhuận của ISO trong đó quý cuối cùng có 14 tuần.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.