วันที่: รับช่วงเวลาปัจจุบัน 15 นาที


15

มีวิธีใดบ้างที่ฉันจะได้รับช่วงเวลา 15 นาทีปัจจุบันโดยใช้คำสั่ง date หรือคล้ายกัน?

เช่นบางอย่างเช่นวันที่%Y.%m.%d %H:%M จะให้ฉัน2011.02.22 10:19ฉันต้องการสิ่งที่อัตราผลตอบแทน2011.02.22 10:15ในช่วงเวลาจากไป10:1510:29

คำตอบ:


17

คุณสามารถรับเวลาปัจจุบันด้วยยูนิกซ์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"

5

วิธีการต่อไปนี้ทำให้ไม่จำเป็นต้องโทร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 

1
เพียงเพื่อความกระจ่าง - โดย "การเรียกระบบ" คุณหมายถึง "fork / exec / wait เช่น system () call" ไม่ใช่การเรียกของระบบโดยทั่วไป (ผมพูดถึงนี้เพราะการโทรระบบนอกจากนี้ยังมีค่าใช้จ่ายภายในโปรแกรมเพราะของผู้ใช้สวิทช์ / เคอร์เนลนั่นคือไม่ได้เป็นปัญหาเฉพาะที่นี่..)
mattdm

mattdm ... ขอบคุณ .. ฉันทำงานจากประสบการณ์ Linux เพียง 6 เดือนดังนั้นฉันจึงมักจะใช้วลีที่ผิด แต่ฉันได้อ่านเกี่ยวกับค่าโสหุ้ยที่เกิดขึ้นจากการโทรที่ไม่จำเป็นและจากประสบการณ์การทดสอบตัวเอง สคริปต์ฉันเห็นตัวอย่างมากมายที่โทรprintfหรือsedและ " catvs " ไฟล์ <ไม่จำเป็นจะทำให้เกิดความแตกต่างในขณะใช้งานจริง เมื่อวนรอบเช่นในตัวอย่าง "ช้าลง 500 เท่า" ของฉัน .. ดังนั้นดูเหมือนว่าการใช้เชลล์ทุกที่ที่ทำได้และการอนุญาตให้โปรแกรมเช่นdateการประมวลผลแบบแบ็ตช์เป็นสิ่งที่ฉันหมายถึง .. เช่น ตัวอย่าง Left-Pad-0 ของ Gilles, vs printf
Peter.O

3

นี่คือวิธีการทำงานกับวันที่ในเปลือก การเรียกครั้งแรก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}"

"กลอุบายของการค้าขาย" ... เป็นสิ่งที่ดี :)
Peter.O

2

อาจจะไม่สำคัญอีกต่อไป แต่คุณสามารถลองdateutilsของฉันเองได้ การปัดเศษ (ลง) เป็นนาทีเสร็จสิ้นด้วยdroundและอาร์กิวเมนต์เป็นลบ:

dround now /-15m
=>
  2012-07-11T13:00:00

หรือเป็นไปตามรูปแบบของคุณ:

dround now /-15m -f '%Y.%m.%d %H:%M'
=>
  2012.07.11 13:00

นั่นคือวิธีการใช้ประโยชน์ของคุณอีกต่อไป? ใช้ -15m ฉันได้รับกรอป้อนข้อมูลไปยังที่ใกล้ที่สุด 15 นาทีที่ผ่านมาหนึ่งชั่วโมง: dateutils.dround '2018-11-12 13:55' -15mผลิตไม่ได้2018-11-12T13:15:00 2018-11-12T13:45:00

1
@JackDouglas เครื่องมือที่มีการพัฒนาสิ่งที่คุณต้องการในขณะนี้: /-15mคือปัดเศษเป็นทวีคูณถัดไปของ 15 นาทีในหนึ่งชั่วโมง คุณลักษณะนี้จะมีไวยากรณ์ที่ยุ่งยากมากขึ้นเพราะยอมรับค่าน้อย / -13m เป็นไปไม่ได้เช่นเพราะ 13 ไม่ได้เป็นตัวหารของ 60 (นาทีในชั่วโมง)
hroptatyr

ดีฉันได้รับสิ่งที่ฉันต้องการด้วยdateutils.dround '2018-11-12 12:52:31' /450s /-15mขอบคุณ!

2

เชลล์บางตัวสามารถทำงานได้โดยไม่ต้องเรียกdateคำสั่งภายนอก:

a=$(printf '%(%s)T\n'); printf '%(%Y.%m.%d %H:%M)T\n' "#$((a-a%(15*60)))"
a=$(printf '%(%s)T\n'); printf '%(%Y.%m.%d %H:%M)T\n' "$((a-a%(15*60)))"
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 ภายนอกอาจช้าเท่ากับการเรียกวันที่:

a=$(date +%s); date -ud "@$((a-a%(15*60)))" +'%Y.%m.%d %H:%M'

ปฏิบัติการขนาดเล็กเช่น 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'

1

หากคุณสามารถใช้ชีวิตกับวันที่โทรสองครั้งหนึ่งนี้ทำงานในทุบตีบน Solaris:

date +"%Y.%m.%d %H:$(( $(date +'%M') / 15 * 15 ))"

แก้ไขในนามของความคิดเห็นที่:

date +"%Y.%m.%d %H:$(( $(date +'%M') / 15 * 15 ))" | sed 's/:0$/:00/'

1
ใน qurarter แรกของชั่วโมงนี้จะสร้างเอาต์พุตนาทีโดยมีเพียง 0 เดียวแทน 00
Peter.O

แก้ไขแล้วมันเป็นเรื่องง่าย ๆ หลังจากคำสั่งดั้งเดิม
ddeimeke

อีกหนึ่งข้อบกพร่อง: มันไม่ทำงานระหว่าง H: 08 และ H: 10 ดูคำตอบของฉันสำหรับสาเหตุและการแก้ไข
Gilles 'หยุดชั่วร้าย'

-1

ไม่แน่ใจเกี่ยวกับความต้องการที่แน่นอนของคุณ แต่ถ้าคุณต้องการสร้างเวลาหลังจาก 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

1
คุณเข้าใจผิดคำถาม จุดคือการปัดเศษวันที่ (ลง) เป็นทวีคูณของ 15 นาที
Gilles 'หยุดชั่วร้าย'
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.