วิธีสร้างวันที่ไตรมาสปีจากบรรทัดคำสั่ง?


10

ฉันสนใจที่จะแสดงผลลัพธ์ของไตรมาสปีปัจจุบันและไตรมาสปีสำหรับเดือนก่อนหน้า

หากวันนี้คือวันที่ 1 มกราคม 2012 ฉันต้องการที่จะได้รับ

2012q1

และ

2011q4

เป็นผลลัพธ์ที่เกี่ยวข้อง

คำตอบ:


10

โซลูชันหนึ่ง (ค่อนข้างน่าเกลียด) ใช้การประเมินทางคณิตศาสตร์แบบ BASH และdateคำสั่ง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 ))

โปรดทราบว่าการ%-mป้องกันdateจากการซ้อน 0 ดังนั้นสิ่งนี้จะยังคงใช้งานได้ในเดือนสิงหาคมและกันยายน


2
รับ $ (... ) แทน backticks ที่เลิกใช้แล้ว พวกมันสามารถซ้อนกันได้ง่าย
ไม่ทราบผู้ใช้

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

ใช้dateutilsของฉัน:

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

%qและ%Qธงมีเฉพาะ dateutils Q<NUMBER>และกลับไตรมาสที่เป็นตัวเลขหรือในรูปแบบ


dconv now -f%Y%Q | tr Q qถ้าคุณต้องการให้คิวนั้นต่ำลงจริง ๆ (PS: เราบรรจุสิ่งนี้ใน Fedora ด้วยdateเป็นคำนำหน้าแทนdดังนั้น " dateconv".)
mattdm

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

@ smokris: ถูกต้อง - ฉันเลือกข้อสอบผิด
ไม่ทราบผู้ใช้


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. remapping 1..12 -> 1..4 ใช้คณิตศาสตร์ต่อไปนี้ (m-1) / 3 + 1
  4. การประเมินเดือนก่อนหน้าใช้คณิตศาสตร์โมดูโล

2

ขณะนี้มี%qรูปแบบเพื่อแสดงข้อมูลนี้

จากบันทึกการเปิดใช้งานcoreutils-8.26ตั้งแต่วันที่ 30 พฤศจิกายน 2559:

คุณสมบัติใหม่
...
วันที่ตอนนี้ยอมรับรูปแบบ% q เพื่อแสดงผลไตรมาสของปี

และใช่มันใช้งานได้!

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

0

หากคุณต้องการไตรมาสที่ 13 ในรอบปีบัญชีซึ่งยึดตามปฏิทินสัปดาห์ ISO แล้ว% q ที่มีประโยชน์ใหม่จะไม่ทำงานเศร้า ต่อไปนี้เป็นวิธีแก้ปัญหาแบบไม่ระบุเวลาของ @ manatwork ด้วย awk / strftime

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

บิต ternary บิตสุดท้ายจัดการกับปีอธิกสุรทิน ISO ซึ่งไตรมาสสุดท้ายมี 14 สัปดาห์

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.