รับวันที่ของวันสุดท้ายของเดือนที่แล้วในเชลล์สคริปต์


11

ฉันจะได้รับวันที่สิ้นสุดเดือนก่อนหน้าตามวันที่ประมวลผลได้อย่างไร

ตัวอย่าง:

  • วันที่ดำเนินการ = 15jan2015
  • วันที่คาดหวัง = 31dec2014

  • วันที่ดำเนินการ = 10feb2015
  • วันที่คาดหวัง = 31jan2015

คำตอบ:


27

ด้วย GNU date:

$ date +%d%b%Y
16Aug2015
$ date -d "$(date +%Y-%m-01) -1 day" +%d%b%Y
31Jul2015

เชลล์บางตัวมีการสนับสนุนในตัวสำหรับการจัดการวันที่:

ด้วยksh93:

$ printf "%(%d%b%Y)T\n" "1st day, yesterday"
31Jul2015

ด้วยzsh:

$ zmodload zsh/datetime
$ strftime -s d %Y-%m-01-12 $EPOCHSECONDS
$ strftime -rs d %Y-%m-%d-%H $d
$ strftime %d%b%Y $((d-86400))
31Jul2015

4

มีหลายวิธีในการทำเช่นนี้ นี่คือสิ่งที่ง่ายที่สุดที่ฉันพบ (ที่นี่สมมติว่า GNU date):

$ date -d "-$(date +%d) days"
Fri Jul 31 16:07:23 EDT 2015

1
คำตอบของ @stephane ชัดเจนขึ้นและอันนี้จะไม่ทำงานในบางปีที่แปลกซึ่งวันที่ข้าม / เพิ่มในช่วงกลางของเดือน ใช่สิ่งนี้เกิดขึ้น ดูyoutube.com/watch?v=-5wpm-gesOY
ctrl-alt-delor

@ Richard, วิธีการชดเชยวันที่ของ GNU (ชดเชย 1 วันไม่เหมือนกับ 24 ชั่วโมง) ฉันคิดว่าคำตอบนี้และฉันควรจะเทียบเท่าและล้มเหลวในเขตเวลาที่จะข้ามวันสุดท้ายของหนึ่งเดือน ( โดยทั่วไปถ้าเกิดขึ้นที่อาจจะอยู่ในเกาะแปซิฟิกเพื่อสลับไปที่ -12: 00 ชดเชยเป็น 12:00 ชดเชย (หรือ -13 ถึง 11 ... ) ...
Stéphane Chazelas

@ สตีเฟนขอบคุณสำหรับการชี้ปัญหาอื่น ๆ เวลาเป็นเรื่องยาก หมายเหตุในโซลูชันของคุณในกรณีที่ลบกลางเดือน (เกิดขึ้น) จากนั้นวันที่ 30 ไม่ใช่วันที่ 30 ดังนั้นการลบ 30 จะไม่นำคุณไปสู่วันสุดท้ายของเดือนก่อน ฉันไม่สามารถดูได้ว่าทำไมคนนี้ถึงไม่ทำงานถ้ามีวันที่ 1 ของเดือน (ไม่รับประกัน) อย่างไรก็ตามนี่ไม่ได้หมายความว่ามันจะ
ctrl-alt-delor

@ Richard, TZ=Pacific/Apia faketime '2011-12-31 12:00' date -d '1 day ago'ดู คุณได้รับข้อผิดพลาดเพราะไม่มี 2011-12-30 นั่นคือชดเชยวันเสร็จในเวลาปฏิทิน 2011-12-31 ลบ 31 วันให้ 2011-11-30 เพราะมันใช้เวลา 31 ปิด 31 มันไม่ได้ใช้เวลา 31 * 24 * 60 * 60 * 60 วินาทีจากเวลาปัจจุบัน เปรียบเทียบกับTZ=Pacific/Apia faketime '2011-12-31 12:00' date -d '24 hour ago'วันที่ 29 ซึ่งคือเวลานี้วันที่เป็น 24 * 60 * 60 * 60 วินาทีที่ผ่านมา
Stéphane Chazelas

2

นี่คือรุ่นที่ใช้งานได้บน Mac OS ซึ่งใช้dateยูทิลิตี้BSD :

date -v1d -v-1d +%d%b%Y

อาร์กิวเมนต์ถูกนำไปใช้ตามลำดับ คุณสามารถจินตนาการได้ว่ามีการกำหนดวันที่จากอาร์กิวเมนต์หนึ่งไปยังอีกอาร์กิวเมนต์ ตัวอย่างเช่น:

  • เริ่มต้นด้วยวันที่ปัจจุบัน ( date) -> 2017-03-06
  • ตั้งวันที่นั้นเป็นวันที่ 1 ของเดือน ( -v1d) -> 2017-03-01
  • ลบหนึ่งวันจากนั้น ( -v-1d)-> 2017-02-28
  • จัดรูปแบบวันที่ ( +%d%b%Y) -> 28Feb2017

คุณสามารถไปถึงจำนวนเดือนไปข้างหน้าหรือข้างหลังโดยใช้date -v-1m -v1d -v-1dแทนที่-1mด้วยจำนวนเดือนไปข้างหน้าหรือข้างหลัง ( +1m) ที่คุณต้องการ

นั่นเป็นคำตอบทั่วไป คำถามนี้ถามเกี่ยวกับวันที่โดยเฉพาะเมื่อเทียบกับวันที่เริ่มต้น ยูทิลิตี้วันที่ของ Mac OS / BSD ไม่อนุญาตให้คุณจัดหา datestamp เพื่อเริ่มต้น แต่คุณสามารถตั้งค่าแต่ละองค์ประกอบวันที่แยกต่างหาก:

date -v2015y -v1m -v15d -v1d -v-1d +%d%b%Y -> 31Dec2014


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