iCal RRULE Generator: สร้าง recurrence string มาตรฐาน RFC 5545 ได้โดยไม่ต้องท่องจำ
เครื่องมือสร้าง RRULE string สำหรับ iCal event ออนไลน์ฟรี รองรับรูปแบบรายวัน รายสัปดาห์ รายเดือน และรายปี พร้อม BYDAY, BYMONTHDAY, COUNT และ UNTIL พร้อมตัวอย่างตารางแบบภาษามนุษย์ให้ตรวจสอบก่อนใช้งาน ทำงานฝั่งไคลเอนต์ 100%
Table of Contents
iCal RRULE Generator: สร้าง recurrence string มาตรฐาน RFC 5545 ได้โดยไม่ต้องท่องจำ
ทุกอีเวนต์ที่เกิดซ้ำที่คุณเคยกดยอมรับใน Google Calendar, Outlook หรือ Apple Calendar ไม่ว่าจะเป็นประชุมประจำสัปดาห์ แจ้งเตือนออกใบแจ้งหนี้รายเดือน หรือวันครบรอบที่วนกลับมาทุกปี ล้วนถูกขับเคลื่อนด้วยข้อความบรรทัดเดียวที่กระชับมาก นั่นคือ RRULE string ซึ่งเป็นหัวใจของระบบปฏิทินทั้งโลก แต่ตัวมันเองกลับอ่านเหมือนข้อความเข้ารหัสลับ สตริงอย่าง RRULE:FREQ=MONTHLY;INTERVAL=2;BYDAY=2TU;COUNT=12 บรรยายความหมายว่า "วันอังคารที่สองของเดือน ทุกสองเดือน ทั้งหมด 12 ครั้ง" ได้ครบถ้วน แต่แทบไม่มีใครจำ syntax พวกนี้ได้ด้วยหัวเปล่า เพราะมาตรฐาน RFC 5545 ที่กำกับอยู่แม่นยำและผ่านการใช้งานมายาวนาน แต่มันถูกเขียนขึ้นเพื่อให้เครื่องอ่าน ไม่ใช่เพื่อคน
iCal RRULE generator ฟรีของเรากลับ workflow ให้เป็นฝั่งของมนุษย์ คุณเลือกความถี่ ทั้งรายวัน รายสัปดาห์ รายเดือน หรือรายปี ตั้งค่า interval แตะเลือกวันในสัปดาห์หรือวันที่ของเดือนที่ต้องการ แล้วกำหนดว่าชุดกิจกรรมนี้จะจบหลังจากกี่ครั้ง หรือจบในวันที่กำหนด เครื่องมือจะประกอบ RRULE string ที่ถูกต้องตาม RFC 5545 จากตัวเลือกเหล่านี้ และที่สำคัญกว่านั้นคือมันแปลกลับเป็นประโยคภาษามนุษย์พร้อมตัวอย่างตารางแบบเรียลไทม์ ให้คุณตรวจสอบก่อนนำไปใช้จริง
ทุกอย่างทำงานแบบ client-side 100% ในเบราว์เซอร์ของคุณ ไม่ต้องสมัครสมาชิก ไม่มีการส่งข้อมูลขึ้นเซิร์ฟเวอร์ สตริงและตัวอย่างตารางอัปเดตทันทีที่เปลี่ยนตัวเลือก จึงเหมาะทั้งกับการสร้าง rule ใช้ครั้งเดียวจบ และกับตารางสำคัญที่จะอยู่ในระบบผลิตจริงไปอีกหลายปี
ทำไมต้องใช้ iCal RRULE Generator?
- ผลลัพธ์ถูกต้องตามมาตรฐาน: ทุกสตริงสร้างตาม RFC 5545 หรือ iCalendar specification ทำให้ Google Calendar, Outlook, Apple Calendar และ library ด้าน scheduling ตีความได้เหมือนกันหมด
- เห็นความหมายเป็นภาษามนุษย์: ตัวอย่างตารางแปลง rule เป็นประโยค เช่น "ทุก 2 สัปดาห์ วันอังคารและวันพฤหัสบดี รวม 12 ครั้ง" ให้คุณยืนยันความหมายก่อนส่งต่อเสมอ
- ครบทั้งสี่รูปแบบความถี่ พร้อมตัวเลือกเต็มสูบ: รองรับ DAILY, WEEKLY, MONTHLY และ YEARLY ร่วมกับ INTERVAL, BYDAY, BYMONTHDAY, COUNT และ UNTIL
- เคสยาก ๆ กลายเป็นคลิกเดียว: ทั้งลำดับที่ของวันในสัปดาห์อย่างวันอังคารที่สอง และการนับวันย้อนจากท้ายเดือนอย่างวันสุดท้ายของเดือน ไม่ต้องเปิด spec ขึ้นมาอ่านอีกต่อไป
- เป็นส่วนตัวตั้งแต่การออกแบบ: การสร้างสตริงทั้งหมดเกิดขึ้นฝั่งไคลเอนต์ ตารางที่อ่อนไหวอย่างวันจ่ายเงินเดือน วันเก็บเงินลูกค้า หรือช่วง maintenance ภายใน ไม่มีทางหลุดออกจากเครื่องคุณ
- คัดลอกแล้วใช้ได้ทันที: คลิกเดียวได้ RRULE ที่เสร็จสมบูรณ์ พร้อมนำไปวางในไฟล์ .ics, calendar API หรือเอกสารต่าง ๆ
ฟีเจอร์หลัก
| ฟีเจอร์ | ทำอะไรได้บ้าง |
|---|---|
| ตัวประกอบรูปแบบ | รวม FREQ, INTERVAL, BYDAY, BYMONTHDAY, COUNT และ UNTIL เป็น RRULE ที่ถูกต้องหนึ่งชุด |
| สี่รูปแบบความถี่ | ครอบคลุม DAILY, WEEKLY, MONTHLY และ YEARLY จากฟอร์มเดียว |
| รองรับ BYDAY แบบลำดับที่ | เลือกวันในสัปดาห์ลำดับที่ n เช่น 2TU คือวันอังคารที่สอง หรือ -1FR คือศุกร์สุดท้ายของเดือน |
| BYMONTHDAY รองรับเลขลบ | ระบุวันที่ตายตัวของเดือน รวมถึง -1 สำหรับวันสุดท้ายของทุกเดือนไม่ว่าเดือนนั้นจะกี่วัน |
| ตัวอย่างตารางภาษามนุษย์ | แปลง rule เป็นประโยคที่ตรวจสอบได้ในแวบเดียว |
| ทำงานฝั่งไคลเอนต์ 100% | สร้างสตริงทั้งหมดในเบราว์เซอร์ ไม่มีการอัปโหลดหรือจัดเก็บข้อมูลใด ๆ |
จุดที่ทำให้ฟีเจอร์เหล่านี้รวมกันเป็น workflow จริง ๆ มีสองเรื่อง หนึ่งคือสตริงกับประโยคภาษามนุษย์อัปเดตพร้อมกันเสมอ ความเข้าใจของคุณกับสิ่งที่ rule ทำจริงจึงไม่มีวันเหลื่อมกัน อีกเรื่องคือผลลัพธ์ยึดมาตรฐานอย่างเคร่งครัด จึงวางลงในไฟล์ .ics, ระบบ import ของปฏิทิน หรือโค้ดที่ใช้ library อย่าง rrule.js หรือ python-dateutil ได้เลยโดยไม่ต้องแก้ต่อ
วิธีใช้งาน
- เลือกความถี่ (FREQ): ตัดสินใจว่าตารางนี้เต้นเป็นจังหวะรายวัน รายสัปดาห์ รายเดือน หรือรายปี การเลือกนี้จะกำหนดส่วน FREQ และปรับฟอร์มส่วนที่เหลือให้แสดงเฉพาะตัวเลือกที่มีความหมาย
- ตั้งค่า interval: INTERVAL 1 คือทุกรอบ, 2 คือเว้นรอบละหนึ่ง แบบรายสัปดาห์ที่ interval เท่ากับ 2 คือรูปแบบเสาร์อาทิตย์เว้น (biweekly) คลาสสิก ส่วนรายเดือนที่ interval เท่ากับ 3 คือทุกไตรมาส
- ใส่เงื่อนไขวัน: แบบรายสัปดาห์ให้แตะชิป BYDAY เลือกวันที่ต้องการ ส่วนแบบรายเดือนและรายปี เลือกได้ทั้งวันในสัปดาห์แบบระบุลำดับที่ หรือตั้ง BYMONTHDAY เพื่อตรึงวันที่ของเดือนแบบตายตัว
- เลือกว่าชุดนี้จะจบอย่างไร: ปล่อยให้วนต่อเนื่องไม่สิ้นสุด ตั้ง COUNT ให้หยุดหลังจากครบจำนวนครั้งที่กำหนด หรือตั้ง UNTIL ให้จบในวันที่ระบุ
- อ่านตัวอย่างแล้วคัดลอก: ตรวจประโยคภาษามนุษย์และวันที่ที่ไฮไลต์ไว้ แก้จุดที่ดูแปลก ๆ แล้วคัดลอก RRULE ที่เสร็จแล้วไปวางในปฏิทิน แอป หรือโค้ดของคุณ
ถอดรหัสส่วนประกอบของ RRULE อย่างเข้าใจง่าย
- FREQ — จังหวะหัวใจของ rule: เป็นส่วนบังคับเพียงตัวเดียว DAILY วนเป็นรอบวัน, WEEKLY เป็นรอบสัปดาห์, MONTHLY เป็นรอบเดือน และ YEARLY เป็นรอบปี ทุกอย่างที่เหลือใน rule ทำหน้าที่ปรับจังหวะพื้นฐานนี้ให้ละเอียดขึ้น
- INTERVAL — ทุก ๆ N รอบ: ค่าเริ่มต้นคือ 1 สตริง FREQ=WEEKLY;INTERVAL=2 หมายถึงทุกสองสัปดาห์ interval ทำงานคูณกับความถี่ ดังนั้น FREQ=MONTHLY;INTERVAL=6 คือตารางที่เกิดปีละสองครั้ง
- BYDAY — วันในสัปดาห์ พร้อมลำดับที่แบบเสริม: โค้ดพื้นฐานคือ MO, TU, WE, TH, FR, SA, SU ใน rule รายเดือนและรายปี สามารถนำหน้าด้วยตัวเลขเพื่อเลือกลำดับภายในรอบ เช่น 2TU คือวันอังคารที่สอง และ -1FR คือศุกร์สุดท้าย ส่วน rule รายสัปดาห์ตัวเลขข้างหน้าไม่มีความหมาย ใช้โค้ดเปล่า ๆ ได้เลย
- BYMONTHDAY — วันที่ของเดือนแบบตายตัว: ค่า 1 ถึง 31 ตรึงวันที่เป๊ะ ๆ ส่วนค่าติดลบนับย้อนจากท้ายเดือน -1 คือวันสุดท้าย, -2 คือวันรองสุดท้าย นี่เป็นวิธีเดียวที่เชื่อถือได้ในการพูดว่า "วันสุดท้ายของเดือน" ครอบคลุมทุกเดือนที่ยาวไม่เท่ากัน
- COUNT กับ UNTIL — สองแบบจบที่ใช้ร่วมกันไม่ได้: COUNT หยุดหลังจากจำนวนครั้งที่กำหนด ส่วน UNTIL หยุดหลังจากเวลาที่กำหนด โดยเขียนเป็นรูปแบบ UTC อย่าง 20261231T235959Z ใส่ได้อย่างใดอย่างหนึ่งเท่านั้น หากใส่ทั้งคู่ parser ที่เข้มงวดจะปฏิเสธ rule ทันที
- สูตรสำเร็จที่ใช้บ่อยในโลกจริง: วันจ่ายเงินเดือนแบบเว้นสัปดาห์: FREQ=WEEKLY;INTERVAL=2;BYDAY=FR ศุกร์สุดท้ายของเดือน: FREQ=MONTHLY;BYDAY=-1FR เฉพาะวันทำการ: FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR
มาดู rule ตัวอย่างพร้อมคำอธิบายทีละส่วนกัน
RRULE:FREQ=MONTHLY;INTERVAL=2;BYDAY=2TU;COUNT=12
| | | |
| | | หยุดหลังจากครบ 12 ครั้ง
| | วันอังคารที่สองของแต่ละเดือน
| เว้นทุกสองเดือน แทนที่จะเป็นทุกเดือน
วนซ้ำตามจังหวะรายเดือน
มีกับดักสองข้อที่ควรใส่ใจเป็นพิเศษ ข้อแรกคือปัญหาวันที่ 31 ของเดือน: FREQ=MONTHLY;BYMONTHDAY=31 จะเงียบ ๆ ไม่สร้าง occurrence ในเดือนที่มีไม่ถึง 31 วัน ได้แก่ เมษายน มิถุนายน กันยายน พฤศจิกายน และกุมภาพันธ์ ถ้าความหมายที่คุณต้องการจริง ๆ คือ "วันสุดท้ายของเดือน" ให้เขียนเป็น BYMONTHDAY=-1 rule จะปรับตัวกับความยาวของทุกเดือนเอง ข้อที่สองคือการเหลื่อมเวลาจาก DST: RRULE บรรยายเวลาแบบเวลาท้องถิ่น (wall-clock) ส่วน timezone อยู่ที่ DTSTART ของอีเวนต์ ไม่ได้อยู่ในตัว rule การประชุม 9 โมงจะยังเป็น 9 โมงต่อเนื่องผ่านทั้งหมดการปรับเวลา ซึ่งมักเป็นสิ่งที่ต้องการ แต่ถ้าระบบไหนเก็บเวลาเป็น UTC โดยไม่มี timezone ที่ถูกต้องกำกับ occurrence อาจดูเพี้ยนไปหนึ่งชั่วโมงในบางช่วงของปี จึงควรให้ DTSTART มี timezone เสมอ และจำไว้ว่า UNTIL ต้องเขียนเป็น UTC
ตัวอย่างการใช้งานจริง
ตารางเก็บเงิน subscription
การเก็บเงินในโลกจริงมักไม่ได้ตรงวันเดิมทุกเดือน แพ็กรายปีต่ออายุปีละครั้ง แพ็กรายไตรมาสเกิดทุกสามเดือน และการเก็บเงินแบบ "วันเดียวกันของสัปดาห์" ใช้ BYDAY แบบระบุลำดับที่ การสร้าง RRULE ที่แน่นอน พร้อมพรีวิวรอบเก็บเงินถัด ๆ ไปหลายรอบ ช่วยกันวงจรเก็บเงินเพี้ยนหนึ่งรอบ ซึ่งเป็นเรื่องที่ทั้งรบกวนลูกค้าและทำรายงานรายได้เปื้อน
การประชุมประจำที่รอดจากทุก timezone
ทีมงานหลายเขตเวลาอยู่ได้ด้วย recurrence ที่ถูกต้อง สตริงที่สร้างจากที่นี่เมื่อจับคู่กับ DTSTART ที่มี timezone ครบ จะทำให้ประชุมวันอังคารยังเป็นวันอังคารในปฏิทินของทุกคน แม้ข้ามช่วงปรับเวลาออมแสง และการใช้ COUNT หรือ UNTIL ทำให้ชุดประชุมหมดอายุไปพร้อมโปรเจกต์ ไม่ไปหลอกหลอนปฏิทินตลอดไป
ระบบรายงานอัตโนมัติ
อีเมลสรุปรายสัปดาห์ การ export สิ้นเดือน และสแนปช็ตตรวจสอบรายไตรมาส ล้วนต้องการตารางที่เครื่องอ่านได้ แทนที่จะเขียน cron expression มือในหลายระบบ ให้สร้าง RRULE หนึ่งชุด วางลงใน scheduler หรือ .ics feed แล้วใช้ประโยคภาษามนุษย์จากตัวอย่างตารางเป็นเอกสารอธิบายไปในตัว
IoT timer และช่วงเวลาบำรุงรักษา
อุปกรณ์อัจฉริยะ ระบบในอาคาร และเซิร์ฟเวอร์ ล้วนทำงานเป็นงานย้ำ ๆ: รดน้ำสวนทุกสามวัน รีบูตเซิร์ฟเวอร์สำรองวันอาทิตย์แรกของเดือน รัน diagnostics ทุกวันทำการเที่ยง RRULE เก็บรูปแบบพวกนี้เป็นสตริงที่พกพาได้และตรวจทานได้ ส่วนพรีวิววันที่ช่วยจับความผิดพลาดก่อนที่ปั๊มน้ำจะทำงานตอนตีสาม
แนวทางปฏิบัติที่ดี
- ใช้ COUNT กับ trial และชุดที่มีความยาวตายตัว: trial 14 วันก็คือ FREQ=DAILY;COUNT=14 ชุดจบไปเองโดยไม่ต้องมีงาน cleanup ตามหลัง
- ใช้ UNTIL กับวันสิ้นสุดตามปฏิทิน: เมื่อสัญญาหรือสิทธิ์การเข้าถึงหมดอายุในวันที่เจาะจง ไม่ว่าจะมี occurrence กี่ครั้งก่อนถึงวันนั้น UNTIL สื่อความตั้งใจได้ตรงที่สุด
- อ่านพรีวิวก่อนส่งต่อทุกครั้ง: ประโยคและวันที่ที่ไฮไลต์เปลี่ยนความผิด syntax ที่มองไม่เห็นให้กลายเป็นข้อผิดพลาดที่ชัดเจน ใช้เวลาตรวจสามสิบวินาที ดีกว่าตารางพลาดทั้งรอบ
- ตั้ง DTSTART ให้ตรงกับ occurrence จริง: การ expand ตาม RFC 5545 ขึ้นกับวันเริ่มต้น ถ้าตั้ง rule "ทุกวันจันทร์" โดยให้ DTSTART เป็นวันเสาร์ ผลลัพธ์ครั้งแรกจะแปลกกว่าที่คิด
- ใช้ BYMONTHDAY=-1 กับงานแบบท้ายเดือน: ตัดปัญหาเดือนที่ไม่มีวันที่ 31 ออกไปทั้งหมด และอ่านรู้เรื่องตอน code review ด้วย
- อย่าใส่ทั้ง COUNT และ UNTIL พร้อมกัน: เลือกอย่างใดอย่างหนึ่ง validator และ parser ที่เข้มงวดจะปฏิเสธ rule ที่มีทั้งคู่
สร้าง RRULE ถัดไปของคุณได้ในไม่กี่วินาที
syntax แบบ recurrence นั้นให้รางวัลกับคนที่ท่องจำได้ และลงโทษคนที่เหลือ เอาเวลาไปลงทุนกับอย่างอื่นดีกว่า เปิด iCal RRULE generator คลิกตามรูปแบบที่อยู่ในหัวของคุณอยู่แล้ว แล้วคัดลอก RRULE ที่ผ่านการตรวจพร้อมพรีวิวภาษามนุษย์ที่เชื่อถือได้ ฟรี เป็นส่วนตัว และทำงานฝั่งไคลเอนต์ทั้งหมด
เครื่องมือที่เกี่ยวข้องที่คุณอาจสนใจ:
- Calendar Link Generator — สร้างลิงก์เพิ่มลงปฏิทินสำหรับอีเวนต์ครั้งเดียวที่ใช้ได้ทั้ง Google, Outlook และ Apple
- Date Range Splitter — แบ่งช่วงวันยาว ๆ ออกเป็นรายสัปดาห์ รายเดือน หรือชิ้นตามกำหนดเอง เพื่อวางแผนและทำ billing
- Business Days Calculator — นับวันทำการระหว่างสองวัน โดยตัดวันหยุดสุดสัปดาห์และวันหยุดนักขัตฤกษ์ให้
ขอให้สนุกกับการจัดตารางครับ
คำถามที่พบบ่อย
ถ: RRULE คืออะไรกันแน่?
ตอบ: RRULE คือ property เรื่องการเกิดซ้ำที่นิยามไว้ใน RFC 5545 หรือมาตรฐาน iCalendar สตริงหนึ่งชุดบอกปฏิทินว่าจะขยายอีเวนต์เดียวให้กลายเป็นชุดที่เกิดซ้ำได้อย่างไร ทั้งความถี่ interval เงื่อนไขวัน และการสิ้นสุด ในรูปแบบกระชับที่ไม่ผูกกับภาษาใดและปฏิทินหลักทุกตัวรองรับ
ถ: เอาสตริงที่สร้างไปวางตรงไหนได้บ้าง?
ตอบ: ทุกที่ที่เข้าใจ RFC 5545 ทั้งบรรทัด RRULE ในอีเวนต์ของไฟล์ .ics, calendar API และ library อย่าง rrule.js หรือ python-dateutil รวมถึงหน้าต่างตั้งค่า recurrence ของผลิตภัณฑ์ scheduling ส่วนใหญ่ เพราะเป็นข้อความธรรมดา จึงเก็บลงไฟล์ config หรือฐานข้อมูลได้สบาย
ถ: COUNT กับ UNTIL ต่างกันอย่างไร?
ตอบ: COUNT จบชุดหลังจากครบจำนวนครั้งที่กำหนด ส่วน UNTIL จบชุดที่จุดเวลาที่กำหนด ใช้ COUNT เมื่อสิ่งสำคัญคือความยาวของชุด เช่น คอร์ส 12 ครั้ง ใช้ UNTIL เมื่อสิ่งสำคัญคือวันตามปฏิทิน เช่น สิทธิ์เข้าถึงที่หมดอายุ 31 ธันวาคม และ rule ที่ถูกต้องต้องมีอย่างใดอย่างหนึ่งเท่านั้น
ถ: ทำไม rule รายเดือนที่ตั้งวันที่ 31 ถึงข้ามบางเดือน?
ตอบ: เพราะเดือนที่ไม่มีวันที่ 31 รองรับ occurrence นั้นไม่ได้ จึงถูกข้ามไปเงียบ ๆ ถ้าความหมายที่ต้องการจริงคือ "วันสุดท้ายของทุกเดือน" ให้ใช้ BYMONTHDAY=-1 ซึ่งจะไปทับกับวันที่ 30, 31, 28 หรือ 29 ตามแต่ละเดือนเอง
ถ: เครื่องมือส่งตารางของฉันไปที่ไหนหรือเปล่า?
ตอบ: ไม่ ทุกขั้นตอนทั้งการจัดการฟอร์ม การประกอบสตริง และการพรีวิว ทำงานแบบ client-side ในเบราว์เซอร์ของคุณ ไม่มีการอัปโหลด บันทึก หรือจัดเก็บข้อมูลใด ๆ และยังใช้งานแบบออฟไลน์ได้เลยหลังจากโหลดหน้าเว็บแล้ว