มีวิธีใดบ้างที่ฉันจะได้รับช่วงเวลา 15 นาทีปัจจุบันโดยใช้คำสั่ง date หรือคล้ายกัน?
เช่นบางอย่างเช่นวันที่%Y.%m.%d %H:%M
จะให้ฉัน2011.02.22 10:19
ฉันต้องการสิ่งที่อัตราผลตอบแทน2011.02.22 10:15
ในช่วงเวลาจากไป10:15
10:29
มีวิธีใดบ้างที่ฉันจะได้รับช่วงเวลา 15 นาทีปัจจุบันโดยใช้คำสั่ง date หรือคล้ายกัน?
เช่นบางอย่างเช่นวันที่%Y.%m.%d %H:%M
จะให้ฉัน2011.02.22 10:19
ฉันต้องการสิ่งที่อัตราผลตอบแทน2011.02.22 10:15
ในช่วงเวลาจากไป10:15
10:29
คำตอบ:
คุณสามารถรับเวลาปัจจุบันด้วยยูนิกซ์date "+%s"
ค้นหาไตรมาสปัจจุบันด้วยคณิตศาสตร์ง่ายๆ (ตัวอย่างของฉันอยู่ในbash
) และพิมพ์กลับด้วยรูปแบบที่ดีขึ้นด้วยdate
:
curdate=`date "+%s"`
curquarter=$(($curdate - ($curdate % (15 * 60))))
date -d"@$curquarter"
@
ไวยากรณ์เพื่อตั้งค่าวันที่และเวลาปัจจุบันจากการประทับเวลาเป็น extention GNU ถึงวันถ้ามันไม่ทำงานบนระบบปฏิบัติการของคุณคุณสามารถทำเช่นเดียวกันเช่นนี้ (อย่าลืมที่จะระบุ UTC มิฉะนั้นจะได้รับรางวัล' ทำงานที):
date -d"1970-01-01 $curquarter seconds UTC"
วิธีการต่อไปนี้ทำให้ไม่จำเป็นต้องโทรdate
สองครั้ง
ค่าใช้จ่ายในการโทรของระบบสามารถทำให้คำสั่ง "แบบง่าย" ช้ากว่าการทุบตี 100 เท่าที่ทำสิ่งเดียวกันในสภาพแวดล้อมท้องถิ่นของตัวเอง
อัพเดทเพียงแค่พูดถึงอย่างรวดเร็วเกี่ยวกับความคิดเห็นข้างต้นของฉัน: "ช้าลง 100 เท่า" สามารถอ่านได้ " 500ช้าลงครั้ง" ... ฉันเพิ่งตกลง (ไม่เดินสุ่มสี่สุ่มห้า) ในเรื่องนี้ นี่คือลิงค์: วิธีที่รวดเร็วในการสร้างไฟล์ทดสอบ
eval $(date +Y=%Y\;m=%m\;d=%d\;H=%H\;M=%M)
[[ "$M" < "15" ]] && M=00 # cater for octal clash
M=$(((M/15)*15))
((M==0)) && M=00 # the math returns 0, so make it 00
echo $Y.$m.$d $H:$M
หรือ
eval $(date +Y=%Y\;m=%m\;d=%d\;H=%H\;M=%M)
if [[ "$M" < "15" ]] ; then M=00
elif [[ "$M" < "30" ]] ; then M=15
elif [[ "$M" < "45" ]] ; then M=30
else M=45
fi
echo $Y.$m.$d $H:$M
ทั้งสองเวอร์ชันจะส่งคืนเท่านั้น
2011.02.23 01:00
2011.02.23 01:15
2011.02.23 01:30
2011.02.23 01:45
นี่คืออันแรกที่มีลูปการทดสอบสำหรับค่า 60 ทั้งหมด {00..59}
for X in {00..59} ; ###### TEST
do ###### TEST
eval $(date +Y=%Y\;m=%m\;d=%d\;H=%H\;M=%M)
M=$X ###### TEST
[[ "$M" < "15" ]] && M=00 # cater for octal clash
M=$(((M/15)*15))
((M==0)) && M=00 # the math returns 0, so make it 00
echo $Y.$m.$d $H:$M
done ###### TEST
printf
หรือsed
และ " cat
vs " ไฟล์ <ไม่จำเป็นจะทำให้เกิดความแตกต่างในขณะใช้งานจริง เมื่อวนรอบเช่นในตัวอย่าง "ช้าลง 500 เท่า" ของฉัน .. ดังนั้นดูเหมือนว่าการใช้เชลล์ทุกที่ที่ทำได้และการอนุญาตให้โปรแกรมเช่นdate
การประมวลผลแบบแบ็ตช์เป็นสิ่งที่ฉันหมายถึง .. เช่น ตัวอย่าง Left-Pad-0 ของ Gilles, vs printf
นี่คือวิธีการทำงานกับวันที่ในเปลือก การเรียกครั้งแรกdate
เพื่อรับส่วนประกอบและเติมพารามิเตอร์ตำแหน่ง ( $1
, $2
และอื่น ๆ ) ด้วยส่วนประกอบ (โปรดทราบว่านี่เป็นหนึ่งในกรณีที่หายากเหล่านี้ซึ่งคุณต้องการใช้$(…)
นอกเครื่องหมายคำพูดคู่เพื่อแบ่งสตริงเป็นคำ) จากนั้นดำเนินการทางคณิตศาสตร์การทดสอบหรือสิ่งที่คุณต้องทำกับส่วนประกอบ ในที่สุดก็ประกอบส่วนประกอบ
ส่วนเลขคณิตอาจยุ่งยากเล็กน้อยเพราะเปลือกหอย0
ถือเป็นส่วนนำหน้าฐานแปด ตัวอย่างเช่นที่นี่$(($5/15))
จะล้มเหลวในเวลา 8 หรือ 9 นาทีที่ผ่านมา เนื่องจากมีมากที่สุดคนหนึ่งชั้นนำ0
, ${5#0}
มีความปลอดภัยสำหรับการทางคณิตศาสตร์ การเพิ่ม 100 และการลอกทีหลัง1
เป็นวิธีการรับจำนวนหลักคงที่ในเอาต์พุต
set $(date "+%Y %m %d %H %M")
m=$((100+15*(${5#0}/15)))
last_quarter_hour="$1.$2.$3 $4:${m#1}"
อาจจะไม่สำคัญอีกต่อไป แต่คุณสามารถลองdateutilsของฉันเองได้ การปัดเศษ (ลง) เป็นนาทีเสร็จสิ้นด้วยdround
และอาร์กิวเมนต์เป็นลบ:
dround now /-15m
=>
2012-07-11T13:00:00
หรือเป็นไปตามรูปแบบของคุณ:
dround now /-15m -f '%Y.%m.%d %H:%M'
=>
2012.07.11 13:00
dateutils.dround '2018-11-12 13:55' -15m
ผลิตไม่ได้2018-11-12T13:15:00
2018-11-12T13:45:00
/-15m
คือปัดเศษเป็นทวีคูณถัดไปของ 15 นาทีในหนึ่งชั่วโมง คุณลักษณะนี้จะมีไวยากรณ์ที่ยุ่งยากมากขึ้นเพราะยอมรับค่าน้อย / -13m เป็นไปไม่ได้เช่นเพราะ 13 ไม่ได้เป็นตัวหารของ 60 (นาทีในชั่วโมง)
เชลล์บางตัวสามารถทำงานได้โดยไม่ต้องเรียกdate
คำสั่งภายนอก:
ksh
a=$(printf '%(%s)T\n'); printf '%(%Y.%m.%d %H:%M)T\n' "#$((a-a%(15*60)))"
bash a=$(printf '%(%s)T\n'); printf '%(%Y.%m.%d %H:%M)T\n' "$((a-a%(15*60)))"
zsh zmodload zsh/datetime; a=$EPOCHSECONDS; strftime '%Y-%m-%d %H:%M' $((a-a%(15*60)))
ทั้งสามข้อนี้ให้เวลาท้องถิ่น (ไม่ใช่ UTC) ใช้ส่วนนำ TZ = UTC0 หากจำเป็น
ไวยากรณ์ ksh และ bash เกือบจะเหมือนกัน (ยกเว้นที่จำเป็น#
ในหน่วย ksh) zsh ต้องการโหลดโมดูล (รวมอยู่ในการกระจาย zsh)
นอกจากนี้ยังเป็นไปได้ที่จะทำกับ (GNU) awk:
เพ่งพิศ awk 'BEGIN{t=systime();print strftime("%Y.%m.%d %H:%M",t-t%(15*60),1)}'
สิ่งนี้ให้ผลลัพธ์ UTC (เปลี่ยนล่าสุด1
เป็น0
) หากจำเป็นต้องใช้โลคัล แต่การโหลด awk ภายนอกหรือโมดูล zsh ภายนอกอาจช้าเท่ากับการเรียกวันที่:
GNU วัน a=$(date +%s); date -ud "@$((a-a%(15*60)))" +'%Y.%m.%d %H:%M'
ปฏิบัติการขนาดเล็กเช่น busybox
สามารถให้ผลลัพธ์ที่คล้ายกัน:
busybox วัน a=$(busybox date +%s);busybox date -ud "@$((a-a%(15*60)))" +'%Y.%m.%d %H:%M'
โปรดทราบว่าอาจมีการตัดคำ busybox ชั้นนำออกหาก busybox เชื่อมโยงกับชื่อเหล่านั้นในไดเรกทอรีของ PATH
ทั้งสองdate
และbusybox date
ข้างต้นจะพิมพ์ครั้ง UTC ลบ-u
ตัวเลือกสำหรับเวลาท้องถิ่น
หากระบบปฏิบัติการของคุณมีรุ่นที่ จำกัด มากขึ้น (และนั่นคือสิ่งที่คุณต้องใช้) ให้ลอง:
a=$(date +%s); a=$(( a-a%(15*60) ))
date -d"1970-01-01 $a seconds UTC" +'%Y.%m.%d %H:%M'
หรือถ้าเป็นใน FreeBSD ให้ลอง:
a=$(date +%s); a=$(( a-a%(15*60) ))
date -r "$a" +'%Y.%m.%d %H:%M'
หากคุณสามารถใช้ชีวิตกับวันที่โทรสองครั้งหนึ่งนี้ทำงานในทุบตีบน Solaris:
date +"%Y.%m.%d %H:$(( $(date +'%M') / 15 * 15 ))"
แก้ไขในนามของความคิดเห็นที่:
date +"%Y.%m.%d %H:$(( $(date +'%M') / 15 * 15 ))" | sed 's/:0$/:00/'
ไม่แน่ใจเกี่ยวกับความต้องการที่แน่นอนของคุณ แต่ถ้าคุณต้องการสร้างเวลาหลังจาก 15 date -d '+15 min'
นาทีแล้วคุณสามารถใช้สิ่งที่ต้องการ เอาท์พุทที่แสดงด้านล่าง:
$ date; date -d '+15 min'
Tue Feb 22 18:12:39 IST 2011
Tue Feb 22 18:27:39 IST 2011