ts
เป็นไลบรารีวันที่และเวลาสำหรับ Emacs มีจุดมุ่งหมายเพื่อให้สะดวกกว่ารูปแบบเช่น (string-to-number (format-time-string "%Y"))
โดยให้การเข้าถึงที่ง่ายเช่น (ts-year (ts-now))
เพื่อปรับปรุงประสิทธิภาพ (อย่างมีนัยสำคัญ) ส่วนวันที่ที่จัดรูปแบบจะถูกคำนวณอย่างเกียจคร้านแทนที่จะสร้างอินสแตนซ์ของออบเจ็กต์การประทับเวลา และส่วนที่คำนวณแล้วจะถูกแคชเพื่อการเข้าถึงในภายหลังโดยไม่ต้องคำนวณใหม่ เบื้องหลัง เป็นการหลีกเลี่ยงการเรียก (string-to-number (format-time-string...
ที่ไม่จำเป็น ซึ่งมีราคาแพงอย่างน่าประหลาดใจ
รับส่วนของวันที่ปัจจุบัน:
; ; When the current date is 2018-12-08 23:09:14 -0600:
(ts-year (ts-now)) ; => 2018
(ts-month (ts-now)) ; => 12
(ts-day (ts-now)) ; => 8
(ts-hour (ts-now)) ; => 23
(ts-minute (ts-now)) ; => 9
(ts-second (ts-now)) ; => 14
(ts-tz-offset (ts-now)) ; => "-0600"
(ts-dow (ts-now)) ; => 6
(ts-day-abbr (ts-now)) ; => "Sat"
(ts-day-name (ts-now)) ; => "Saturday"
(ts-month-abbr (ts-now)) ; => "Dec"
(ts-month-name (ts-now)) ; => "December"
(ts-tz-abbr (ts-now)) ; => "CST"
เพิ่มวันที่ปัจจุบัน:
; ; By 10 years:
( list :now (ts-format)
:future (ts-format (ts-adjust 'year 10 (ts-now))))
; ;=> ( :now "2018-12-15 22:00:34 -0600"
; ; :future "2028-12-15 22:00:34 -0600")
; ; By 10 years, 2 months, 3 days, 5 hours, and 4 seconds:
( list :now (ts-format)
:future (ts-format
(ts-adjust 'year 10 'month 2 'day 3
'hour 5 'second 4
(ts-now))))
; ;=> ( :now "2018-12-15 22:02:31 -0600"
; ; :future "2029-02-19 03:02:35 -0600")
วันอะไรของสัปดาห์คือ 2 วันที่แล้ว?
(ts-day-name (ts-dec 'day 2 (ts-now))) ; => "Thursday"
; ; Or, with threading macros:
( thread-last (ts-now) (ts-dec 'day 2 ) ts-day-name) ; => "Thursday"
(-> > (ts-now) (ts-dec 'day 2 ) ts-day-name) ; => "Thursday"
รับการประทับเวลาสำหรับเวลานี้เมื่อสัปดาห์ที่แล้ว:
(ts-unix (ts-adjust 'day -7 (ts-now)))
; ;=> 1543728398.0
; ; To confirm that the difference really is 7 days:
( / ( - (ts-unix (ts-now))
(ts-unix (ts-adjust 'day -7 (ts-now))))
86400 )
; ;=> 7.000000567521762
; ; Or human-friendly as a list:
(ts-human-duration
(ts-difference (ts-now)
(ts-dec 'day 7 (ts-now))))
; ;=> (:years 0 :days 7 :hours 0 :minutes 0 :seconds 0)
; ; Or as a string:
(ts-human-format-duration
(ts-difference (ts-now)
(ts-dec 'day 7 (ts-now))))
; ;=> "7 days"
; ; Or confirm by formatting:
( list :now (ts-format)
:last-week (ts-format (ts-dec 'day 7 (ts-now))))
; ;=> ( :now "2018-12-08 23:31:37 -0600"
; ; :last-week "2018-12-01 23:31:37 -0600")
ตัวเข้าถึงบางตัวมีนามแฝงคล้ายกับตัวสร้าง format-time-string
:
(ts-hour (ts-now)) ; => 0
(ts-H (ts-now)) ; => 0
(ts-minute (ts-now)) ; => 56
(ts-min (ts-now)) ; => 56
(ts-M (ts-now)) ; => 56
(ts-second (ts-now)) ; => 38
(ts-sec (ts-now)) ; => 38
(ts-S (ts-now)) ; => 38
(ts-year (ts-now)) ; => 2018
(ts-Y (ts-now)) ; => 2018
(ts-month (ts-now)) ; => 12
(ts-m (ts-now)) ; => 12
(ts-day (ts-now)) ; => 9
(ts-d (ts-now)) ; => 9
แยกสตริงลงในวัตถุการประทับเวลาและฟอร์แมตใหม่:
(ts-format (ts-parse " sat dec 8 2018 12:12:12 " )) ; => "2018-12-08 12:12:12 -0600"
; ; With a threading macro:
(-> > " sat dec 8 2018 12:12:12 "
ts-parse
ts-format) ; ;=> "2018-12-08 12:12:12 -0600"
จัดรูปแบบความแตกต่างระหว่างการประทับเวลาสองครั้ง:
(ts-human-format-duration
(ts-difference (ts-now)
(ts-adjust 'day -400
'hour -2 'minute -1 'second -5
(ts-now))))
; ; => "1 years, 35 days, 2 hours, 1 minutes, 5 seconds"
; ; Abbreviated:
(ts-human-format-duration
(ts-difference (ts-now)
(ts-adjust 'day -400
'hour -2 'minute -1 'second -5
(ts-now)))
'abbr )
; ; => "1y35d2h1m5s"
แยกวิเคราะห์องค์ประกอบการประทับเวลาขององค์กรโดยตรงจาก org-element-context
และค้นหาความแตกต่างระหว่างองค์ประกอบดังกล่าวกับปัจจุบัน:
( with-temp-buffer
( org-mode )
( save-excursion
( insert " <2015-09-24 Thu .+1d> " ))
(ts-human-format-duration
(ts-difference (ts-now)
(ts-parse-org-element ( org-element-context )))))
; ;=> "3 years, 308 days, 2 hours, 24 minutes, 21 seconds"
แยกสตริงการประทับเวลาขององค์กร (ซึ่งมีตัวทวนสัญญาณ) และจัดรูปแบบปีและเดือน:
; ; Note the use of `format' rather than `concat' , because `ts-year'
; ; returns the year as a number rather than a string.
( let* ((ts (ts-parse-org " <2015-09-24 Thu .+1d> " )))
( format " %s , %s " (ts-month-name ts) (ts-year ts)))
; ;=> "September, 2015"
; ; Or, using dash.el:
(-- > (ts-parse-org " <2015-09-24 Thu .+1d> " )
( format " %s , %s " (ts-month-name it) (ts-year it)))
; ;=> "September, 2015"
; ; Or, if you remember the format specifiers:
(ts-format " %B, %Y " (ts-parse-org " <2015-09-24 Thu .+1d> " ))
; ;=> "September, 2015"
วันนี้เมื่อปี 1970 นานแค่ไหนแล้ว?
( let* ((now (ts-now))
(then (ts-apply :year 1970 now)))
( list (ts-format then)
(ts-human-format-duration
(ts-difference now then))))
; ;=> ("1970-08-04 07:07:10 -0500"
; ; "49 years, 12 days")
ยุคเริ่มต้นเมื่อนานมาแล้ว?
(ts-human-format-duration
(ts-diff (ts-now) (make-ts :unix 0 )))
; ;=> "49 years, 227 days, 12 hours, 12 minutes, 30 seconds"
ในช่วง 100 ปีที่ผ่านมา วันคริสต์มาสเป็นวันเสาร์ใด
( let ((ts (ts-parse " 2019-12-25 " ))
(limit ( - (ts-year (ts-now)) 100 )))
( cl-loop while ( >= (ts-year ts) limit)
when ( string= " Saturday " (ts-day-name ts))
collect (ts-year ts)
do (ts-decf (ts-year ts))))
; ;=> (2010 2004 1999 1993 1982 1976 1971 1965 1954 1948 1943 1937 1926 1920)
สำหรับตัวอย่างที่น่าสนใจกว่านี้ การประทับเวลาจะอยู่ภายในสัปดาห์ปฏิทินก่อนหน้าหรือไม่
; ; First, define a function to return the range of the previous calendar week.
( defun last-week-range ()
" Return timestamps (BEG . END) spanning the previous calendar week. "
( let* ( ; ; Bind `now' to the current timestamp to ensure all calculations
; ; begin from the same timestamp. (In the unlikely event that
; ; the execution of this code spanned from one day into the next,
; ; that would cause a wrong result.)
(now (ts-now))
; ; We start by calculating the offsets for the beginning and
; ; ending timestamps using the current day of the week. Note
; ; that the `ts-dow' slot uses the "%w" format specifier, which
; ; counts from Sunday to Saturday as a number from 0 to 6.
(adjust-beg-day ( - ( + 7 (ts-dow now))))
(adjust-end-day ( - ( - 7 ( - 6 (ts-dow now)))))
; ; Make beginning/end timestamps based on `now' , with adjusted
; ; day and hour/minute/second values. These functions return
; ; new timestamps, so `now' is unchanged.
(beg ( thread-last now
; ; `ts-adjust' makes relative adjustments to timestamps.
(ts-adjust 'day adjust-beg-day)
; ; `ts-apply' applies absolute values to timestamps.
(ts-apply :hour 0 :minute 0 :second 0 )))
(end ( thread-last now
(ts-adjust 'day adjust-end-day)
(ts-apply :hour 23 :minute 59 :second 59 ))))
( cons beg end)))
(-let* ( ; ; Bind the default format string for `ts-format' , so the
; ; results are easy to understand.
(ts-default-format " %a, %Y-%m-%d %H:%M:%S %z " )
; ; Get the timestamp for 3 days before now.
(check-ts (ts-adjust 'day -3 (ts-now)))
; ; Get the range for the previous week from the function we defined.
((beg . end) (last-week-range)))
( list :last-week-beg (ts-format beg)
:check-ts (ts-format check-ts)
:last-week-end (ts-format end)
:in-range-p (ts-in beg end check-ts)))
; ;=> (:last-week-beg "Sun, 2019-08-04 00:00:00 -0500"
; ; :check-ts "Fri, 2019-08-09 10:00:34 -0500"
; ; :last-week-end "Sat, 2019-08-10 23:59:59 -0500"
; ; :in-range-p t)
ts-B (STRUCT)
ts
struct STRUCT
ts-H (STRUCT)
ts
struct STRUCT
ts-M (STRUCT)
ts
struct STRUCT
ts-S (STRUCT)
ts
struct STRUCT
ts-Y (STRUCT)
ts
struct STRUCT
ts-b (STRUCT)
ts
struct STRUCT
ts-d (STRUCT)
ts
struct STRUCT
ts-day (STRUCT)
ts
struct STRUCT
ts-day-abbr (STRUCT)
ts
struct STRUCT
ts-day-name (STRUCT)
ts
struct STRUCT
ts-day-of-month-num (STRUCT)
ts
struct STRUCT
ts-day-of-week-abbr (STRUCT)
ts
struct STRUCT
ts-day-of-week-name (STRUCT)
ts
struct STRUCT
ts-day-of-week-num (STRUCT)
ts
struct STRUCT
ts-day-of-year (STRUCT)
ts
struct STRUCT
ts-dom (STRUCT)
ts
struct STRUCT
ts-dow (STRUCT)
ts
struct STRUCT
ts-doy (STRUCT)
ts
struct STRUCT
ts-hour (STRUCT)
ts
struct STRUCT
ts-internal (STRUCT)
ts
struct STRUCT
Slot แสดงถึงค่าเวลาภายในของ Emacs (เช่นที่ส่งคืนโดย current-time
)ts-m (STRUCT)
ts
struct STRUCT
ts-min (STRUCT)
ts
struct STRUCT
ts-minute (STRUCT)
ts
struct STRUCT
ts-month (STRUCT)
ts
struct STRUCT
ts-month-abbr (STRUCT)
ts
struct STRUCT
ts-month-name (STRUCT)
ts
struct STRUCT
ts-month-num (STRUCT)
ts
struct STRUCT
ts-moy (STRUCT)
ts
struct STRUCT
ts-sec (STRUCT)
ts
struct STRUCT
ts-second (STRUCT)
ts
struct STRUCT
ts-tz-abbr (STRUCT)
ts
struct STRUCT
ts-tz-offset (STRUCT)
ts
struct STRUCT
ts-unix (STRUCT)
ts
struct STRUCT
ts-week (STRUCT)
ts
struct STRUCT
ts-week-of-year (STRUCT)
ts
struct STRUCT
ts-woy (STRUCT)
ts
struct STRUCT
ts-year (STRUCT)
ts
struct STRUCT
ts-apply (&rest SLOTS TS)
TS
พร้อมค่าช่องใหม่ กรอกช่องการประทับเวลา เขียนทับค่าช่องที่กำหนด และส่งคืนการประทับเวลาใหม่ด้วยค่าการประทับเวลา Unix ที่ได้มาจากค่าช่องใหม่ SLOTS
คือรายการคู่คีย์-ค่าที่สลับกันแบบเดียวกับที่ส่งไปยัง make-ts
ts-adjust (&rest ADJUSTMENTS)
ADJUSTMENTS
กับ TS
ADJUSTMENTS
ควรเป็นชุดของ SLOTS
และ VALUES
สลับกันเพื่อใช้ในการปรับเปลี่ยน ตัวอย่างเช่น แบบฟอร์มนี้จะส่งคืนการประทับเวลาใหม่ที่เป็น 47 ชั่วโมงข้างหน้า: (ts-adjust 'hour -1 'day +2 (ts-now))
เนื่องจากอาร์กิวเมนต์การประทับเวลาเป็นค่าสุดท้าย จึงเหมาะสำหรับใช้ในมาโครเธรด
ts-dec (SLOT VALUE TS)
TS
โดยที่ SLOT
ลดลงด้วย VALUE
SLOT
ควรระบุเป็นสัญลักษณ์ธรรมดา ไม่ใช่คำหลักts-inc (SLOT VALUE TS)
TS
โดย SLOT
จะเพิ่มขึ้นทีละ VALUE
SLOT
ควรระบุเป็นสัญลักษณ์ธรรมดา ไม่ใช่คำหลักts-update (TS)
TS
หลังจากอัปเดตการประทับเวลา Unix จากช่องอื่นๆ ไม่ทำลาย. เพื่อใช้หลังจากตั้งค่าช่องด้วย เช่น ts-fill
ทำลายล้าง
ts-adjustf (TS &rest ADJUSTMENTS)
TS
ที่ใช้ ADJUSTMENTS
ฟังก์ชั่นนี้เป็นแบบทำลายล้างเนื่องจากมันเรียก setf
บน TS
ADJUSTMENTS
ควรเป็นชุดของ SLOTS
และ VALUES
สลับกันเพื่อใช้ในการปรับเปลี่ยน ตัวอย่างเช่น แบบฟอร์มนี้จะปรับการประทับเวลาเป็น 47 ชั่วโมงในอนาคต:
(let ((ts (ts-now))) (ts-adjustf ts 'hour -1 'day +2))
ts-decf (PLACE &optional (VALUE 1))
PLACE
ด้วย VALUE
(ค่าเริ่มต้น 1) อัปเดตการประทับเวลา Unix และส่งกลับค่าใหม่ของ PLACE
ts-incf (PLACE &optional (VALUE 1))
PLACE
ด้วย VALUE
(ค่าเริ่มต้น 1) อัปเดตการประทับเวลา Unix และส่งกลับค่าใหม่ของ PLACE
ts-in (BEG END TS)
TS
อยู่ในช่วง BEG
ถึง END
รวมอยู่ด้วย อาร์กิวเมนต์ทั้งหมดควรเป็น ts
structts< (AB)
A
น้อยกว่าการประทับเวลา B
ts<= (AB)
A
คือ <= timestamp B
ts= (AB)
A
เหมือนกับการประทับเวลา B
เปรียบเทียบเฉพาะสล็อต unix
ของการประทับเวลา โปรดทราบว่าสล็อต Unix ของการประทับเวลาเป็นแบบทศนิยมและอาจมีความแตกต่างกันน้อยกว่าหนึ่งวินาที ซึ่งทำให้ไม่เท่ากันแม้ว่าส่วนที่จัดรูปแบบทั้งหมดของประทับเวลาจะเหมือนกันก็ตามts> (AB)
A
มากกว่าการประทับเวลา B
ts>= (AB)
A
คือ >= การประทับเวลา B
ts-human-duration (SECONDS)
SECONDS
มีหน่วยเป็นปี วัน ชั่วโมง นาที และวินาที นี่เป็นการคำนวณง่ายๆ ที่ไม่นับปีอธิกสุรทิน วินาทีอธิกสุรทิน ฯลฯts-human-format-duration (SECONDS &optional ABBREVIATE)
SECONDS
ถ้า SECONDS
น้อยกว่า 1 จะส่งกลับ "0 seconds"
ถ้า ABBREVIATE
ไม่ใช่ศูนย์ ให้ส่งคืนเวอร์ชันที่สั้นกว่าโดยไม่ต้องเว้นวรรค นี่เป็นการคำนวณง่ายๆ ที่ไม่นับปีอธิกสุรทิน วินาทีอธิกสุรทิน ฯลฯ ts-format (&optional TS-OR-FORMAT-STRING TS)
format-time-string
หาก TS-OR-FORMAT-STRING
เป็นการประทับเวลาหรือไม่มี ให้ใช้ค่าของ ts-default-format
ถ้าทั้ง TS-OR-FORMAT-STRING
และ TS
เป็นศูนย์ ให้ใช้เวลาปัจจุบัน ts-parse (STRING)
ts
ใหม่ แยกวิเคราะห์ STRING
ด้วย parse-time-string
ts-parse-fill (FILL STRING)
ts
ใหม่ แยกวิเคราะห์ STRING
ด้วย parse-time-string
ค่าชั่วโมง/นาที/วินาทีที่ว่างเปล่าจะถูกกรอกตาม FILL
: if begin
ด้วย 0; ถ้า end
ชั่วโมงจะเต็มไปด้วย 23 และนาที/วินาทีด้วย 59 ถ้าไม่มี ข้อผิดพลาดอาจถูกส่งสัญญาณเมื่อค่าเวลาว่างเปล่า โปรดทราบว่าเมื่อ FILL
end
ค่าเวลา เช่น "12:12" จะถูกเติมเป็น "12:12:00" ไม่ใช่ "12:12:59"ts-parse-org (ORG-TS-STRING)
ORG-TS-STRING
โปรดทราบว่ามีการเรียกใช้ฟังก์ชัน org-parse-time-string
ซึ่งควรโหลดก่อนที่จะเรียกใช้ฟังก์ชันนี้ts-parse-org-fill (FILL ORG-TS-STRING)
ORG-TS-STRING
โปรดทราบว่ามีการเรียกใช้ฟังก์ชัน org-parse-time-string
ซึ่งควรโหลดก่อนที่จะเรียกใช้ฟังก์ชันนี้ ค่าชั่วโมง/นาที/วินาทีจะถูกกรอกตาม FILL
: ถ้า begin
ด้วย 0; หาก end
ชั่วโมงจะเต็มไปด้วย 23 และนาที/วินาทีด้วย 59 โปรดทราบว่า org-parse-time-string
ไม่รองรับการประทับเวลาที่มีวินาทีts-parse-org-element (ELEMENT)
ELEMENT
องค์ประกอบควรมีลักษณะเหมือนองค์ประกอบที่แยกวิเคราะห์โดย org-element
องค์ประกอบแรกคือ timestamp
ถือว่าการประทับเวลาไม่ใช่ช่วง copy-ts (TS)
TS
ts-difference (AB)
A
และ B
ts-diff
ts-difference
ts-fill (TS &optional ZONE)
TS
โดยเติมช่องทั้งหมดจากการประทับเวลา Unix สิ่งนี้ไม่ทำลายล้าง ZONE
ถูกส่งผ่านไปยัง format-time-string
ซึ่งจะเห็นts-now
ts
struct ที่ตั้งค่าเป็นตอนนี้ts-p (STRUCT)
ts-reset (TS)
TS
โดยล้างช่องทั้งหมดยกเว้น unix
ไม่ทำลาย. เช่นเดียวกับ: (make-ts :unix (ts-unix ts))
ts-defstruct (&rest ARGS)
cl-defstruct
แต่มีตัวเลือกสล็อตเพิ่มเติมตัวเลือกและค่าสล็อตเพิ่มเติม:
:accessor-init
: sexp ที่เริ่มต้นช่องใน accessor หากช่องเป็นศูนย์ struct
สัญลักษณ์จะถูกผูกไว้กับโครงสร้างปัจจุบัน ตัวเข้าถึงถูกกำหนดไว้หลังจากที่โครงสร้างถูกกำหนดโดยสมบูรณ์ ดังนั้นจึงอาจอ้างอิงถึงคำจำกัดความของโครงสร้าง (เช่น โดยใช้แมโคร cl-struct
pcase
)
:aliases
: A
สัญลักษณ์ซึ่งจะถูกสร้างนามแฝงให้กับ slot accessor โดยนำหน้าด้วยชื่อ struct (เช่น struct ts
ที่มี slot year
และ alias y
จะสร้างนามแฝง ts-y
)
ts-human-format-duration
เทียบกับ format-seconds
Emacs มีฟังก์ชันในตัว format-seconds
ที่สร้างเอาต์พุตคล้ายกับ ts-human-format-duration
เอาต์พุตยังสามารถควบคุมได้ด้วยสตริงรูปแบบ อย่างไรก็ตาม หากเอาต์พุตของ ts-human-format-duration
เพียงพอ ก็จะทำงานได้ดีกว่า format-seconds
มาก เกณฑ์มาตรฐานง่ายๆ นี้ ซึ่งรัน 100,000 ครั้ง แสดงให้เห็นว่ามันทำงานเร็วกว่ามากและสร้างขยะน้อยลง:
(bench-multi-lexical :times 100000
:forms (( " ts-human-format-duration " (ts-human-format-duration 15780.910933971405 t ))
( " format-seconds " ( format-seconds " %yy%dd%hh%mm%ss%z " 15780.910933971405 ))))
รูปร่าง | x เร็วกว่าครั้งต่อไป | รันไทม์ทั้งหมด | #ของGC | รันไทม์ GC ทั้งหมด |
---|---|---|---|---|
ts-รูปแบบมนุษย์-ระยะเวลา | 5.82 | 0.832945 | 3 | 0.574929 |
รูปแบบวินาที | ช้าที่สุด | 4.848253 | 17 | 3.288799 |
(ดูคู่มือนักพัฒนาแพ็คเกจ Emacs สำหรับมาโคร bench-multi-lexical
)
เพิ่มแล้ว
ts-fill
ยอมรับอาร์กิวเมนต์ ZONE
เช่นเดียวกับที่ส่งผ่านไปยัง format-time-string
ซึ่งจะเห็น ที่ตายตัว
ts-human-format-duration
ส่งคืนสตริงว่างสำหรับระยะเวลาน้อยกว่า 1 วินาที (ตอนนี้ส่งคืน "0 seconds"
) เพิ่มแล้ว
ts-parse-fill
และ ts-parse-org-fill
ts-in
เปลี่ยน
ts-now
ไม่ได้อยู่ในบรรทัดอีกต่อไป สิ่งนี้ทำให้สามารถเปลี่ยนแปลงได้ในขณะรันไทม์ด้วย เช่น cl-letf
ซึ่งมีประโยชน์ในการทดสอบที่ตายตัว
ts-fill
(ฟังก์ชัน split-string
ซึ่งเรียกว่าฟังก์ชันนี้ จะแก้ไขข้อมูลที่ตรงกัน)ts-parse-org
(ฟังก์ชัน org-parse-time-string
ซึ่งถูกเรียกในนั้น จะแก้ไขข้อมูลที่ตรงกัน)เอกสารประกอบ
การเปิดตัวแท็กครั้งแรก เผยแพร่ไปยัง MELPA
GPLv3