ระบบอัตโนมัติด้วย Python
การจัดการกับวันที่ใน Python
บทความนี้เกี่ยวกับการจัดการที่เป็นไปได้ที่คุณสามารถทำได้กับตัวแปร DateTime
คุณประสบปัญหาเมื่อต้องจัดการกับวัตถุ DateTime หรือไม่? ก็ต้องยอมรับว่าทะเลาะกันบ่อย ฉันจำเป็นต้องค้นหาวิธีการที่เหมาะสมสำหรับกรณีการใช้งานของฉันอยู่เสมอ จากนั้น ฉันจึงตัดสินใจเขียนบทความนี้ เพื่อเป็นเอกสารสำหรับผู้อ่านที่รักและตัวฉันเอง
พื้นหลัง
เมื่อฉันกำลังพัฒนาเครื่องมือเพื่อเตรียมรายงานหรือรวมไฟล์ Excel โดยอัตโนมัติ ฉันจะต้องสามารถระบุข้อมูลจากชื่อไฟล์หรือโฟลเดอร์ได้ โดยปกติไฟล์ที่ระบบสร้างขึ้นหรือรายงานเป็นระยะๆ จะถูกตั้งชื่อตามรูปแบบที่ตายตัวและจะถูกจัดเก็บไว้ในโฟลเดอร์เดียวกัน
โดยปกติชื่อไฟล์จะเป็นการรวมกันของชื่อรายงาน วันที่หรือรอบระยะเวลาของรายงาน และนามสกุลไฟล์ ตัวอย่างเช่น รายงานเป็นระยะชื่อ “รายงานการใช้ไฟฟ้าปี 2022_Q4_WW43.xlsx”และรายงานรายวันชื่อ “รายงานคำขอเครื่องมือ 20221021.csv” ในการดึงไฟล์ที่ถูกต้อง เราจะต้องคำนวณวันที่หรือรอบระยะเวลาในชื่อไฟล์ตามเวลาที่เครื่องมือรายงานอัตโนมัติทำงาน
ด้วยเหตุนี้ บทความนี้จะมีโครงสร้างดังนี้:
- การแยกวิเคราะห์และการจัดรูปแบบ DateTime (strptimevs strftime)
- ดึงข้อมูลปี / เดือน / วัน
- คำนวณสัปดาห์โลกจากวันที่
- คำนวณวันสัปดาห์จากวันที่
- แปลงวัตถุ DateTime เป็นงวด
- คำนวณช่วงเวลาข้อมูล
มาเริ่มกันเลย!
การแยกวิเคราะห์ DateTime หมายความว่าเราแปลงวัตถุสตริงที่มีวันที่เป็นวัตถุ DateTime ตัวอย่างเช่น เมื่อเราได้รับวันที่จากรายงาน “Tools Requisition Report 20221021.csv”ด้วยนิพจน์ทั่วไปหรือวิธีอื่นใด วันที่ “20221021” จะเป็นตัวแปรสตริง
หลังจากที่เราแยกวิเคราะห์แล้ว มันจะกลายเป็นออบเจ็กต์ DateTime และจะเขียนในรูปแบบ ISO (ปปปป-ดด-วว) 2022–10–21 จากนั้นเราจะจัดรูปแบบเป็นรูปแบบเฉพาะได้ เช่น วันที่ 21 ตุลาคม 2022 โปรดทราบว่าออบเจ็กต์ DateTime จะกลายเป็นออบเจ็กต์สตริงหลังจากที่เราจัดรูปแบบแล้ว
น่าสับสนใช่ไหม? ไม่ต้องกังวล!
คุณจะมีภาพที่ชัดเจนขึ้นจากตัวอย่างด้านล่าง
1. การแยกวิเคราะห์และการจัดรูปแบบ DateTime
กำลังแยกวิเคราะห์ DateTime
มีสองวิธีจากไลบรารี DateTime เพื่อแยกวิเคราะห์วันที่:
datetime.fromisoformat()
datetime.strptime()
มาดูกันว่าความแตกต่างระหว่างพวกเขาคืออะไร!
import datetime as dt my_date1 = "2022-07-01" print(my_date1) print(type(my_date1)) my_date2 = "01-07-2022" print(my_date2) print(type(my_date2)) my_date3 = "01July2022" print(my_date3) print(type(my_date3))
โอเค ฉันจึงสร้างวันที่ที่แตกต่างกัน 3 วันเป็นตัวแปร ซึ่งถือเป็นวัตถุสตริงในขณะนี้ มาแยกวิเคราะห์พวกมันลงในวัตถุ DateTime กันตอนนี้
my_date1a = dt.datetime.fromisoformat(my_date1) print(type(my_date1a)) my_date3a = dt.datetime.fromisoformat(my_date3) print(type(my_date3a))
สำหรับวิธีแรก datetime.fromisoformat()
เช่นเดียวกับชื่อวิธีการ จะสามารถแยกวิเคราะห์วันที่ที่อยู่ในรูปแบบ ISO คือ YYYY-MM-DD เช่นเดียวกับในตัวแปรชื่อ my_date1
ดังนั้น เมื่อเราพยายามใช้วิธีนี้กับรูปแบบ DateTime อื่นๆ เช่นเดียวกับใน my_date3
ก็จะส่งกลับ ข้อผิดพลาดของค่า ตัวแปร my_date1a
คือวัตถุ DateTime ที่เราได้รับจากการแยกวิเคราะห์ตัวแปร my_date1
ด้านล่างนี้เป็นตัวอย่างการแยกวิเคราะห์วันที่ด้วยวิธี datetime.strptime()
สำหรับวิธีนี้ เราต้องระบุ รหัสรูปแบบ ตามรูปแบบวันที่เพื่อแยกวิเคราะห์วันที่ คุณสามารถอ่านเพิ่มเติมเกี่ยวกับโค้ดรูปแบบได้ที่ strftime() และ strptime() Behavior
# my_date2 = "01-07-2022" my_date2a = dt.datetime.strptime(my_date2, "%d-%m-%Y") print(type(my_date2a)) print(my_date2a) # Output: # <class 'datetime.datetime'> # 2022-07-03 00:00:00
มาดูตัวอย่างอื่นที่มีรูปแบบวันที่ที่แตกต่างกัน
# my_date3 = "01July2022" my_date3a = dt.datetime.strptime(my_date3, "%d%B%Y") print(type(my_date3a)) print(my_date3a) # Output: # <class 'datetime.datetime'> # 2022-07-01 00:00:00
การแยกวิเคราะห์วันที่ด้วยวิธี strptime()
คือการแทนที่วัน เดือน และปีด้วยโค้ดรูปแบบที่เกี่ยวข้อง ดังที่แสดงในตัวอย่างข้างต้น %d สำหรับวัน %m สำหรับหลักเดือน %B สำหรับชื่อเต็มของเดือน และ %Y สำหรับปีที่มีศตวรรษ
ตอนนี้มันอาจจะดูซับซ้อนมากหากคุณยังใหม่กับสิ่งนี้ แต่ฉันรับรองว่าคุณจะดีมากเมื่อคุณคุ้นเคยกับโค้ดรูปแบบแล้ว โปรดจำไว้ว่า คุณสามารถอ้างถึง strftime() และ strptime() Behavior ได้เสมอ 😉
การจัดรูปแบบวันที่และเวลา
หลังจากที่เราแยกวิเคราะห์วัตถุสตริงลงในวัตถุ DateTime แล้ว มันจะแสดงในรูปแบบ ISO หากต้องการให้อยู่ในรูปแบบอื่น เราต้องใช้วิธี datetime.strftime()
เพื่อจัดรูปแบบวันที่
# my_date3a: 2022-07-01 00:00:00 my_format_date = dt.datetime.strftime(my_date3a, "%B %d, %Y") print(my_format_date) # Output: # July 01, 2022
โปรดทราบว่าหลังจากที่เราจัดรูปแบบวันที่แล้ว วันที่จะกลายเป็นสตริง
หลังจากที่เราแยกสตริงลงในวัตถุ DateTime เราก็สามารถรับข้อมูลจากมันได้
2. แยกข้อมูลปี/เดือน/วัน
หมายเหตุ: ตัวอย่างด้านล่างใช้ตัวแปรจากตัวอย่างในส่วนแรก
หากต้องการรับข้อมูลปี เดือน และวัน เราเพียงแค่ต้องใช้แอตทริบิวต์ที่เกี่ยวข้องด้านล่างจากออบเจ็กต์ DateTime
datetime_object.year
datetime_object.month
datetime_object.day
# my_date3a: 2022-07-01 00:00:00 # Get Year Info my_date3a.year # Output: # 2022 # Get Month Info my_date3a.month # Output: # 7 # Get Day Info my_date3a.day # Output: # 1
ง่ายใช่มั้ย? 😄
อย่างไรก็ตาม เราไม่สามารถดึงข้อมูลด้านบนจากวันที่ที่จัดรูปแบบได้
# my_format_date = "July 01, 2022" my_format_date.month
มันจะส่งคืนข้อผิดพลาดของแอตทริบิวต์ เนื่องจากเมื่อเราจัดรูปแบบวันที่เป็นรูปแบบอื่น มันจะกลายเป็นวัตถุสตริงอีกครั้ง เราสามารถส่งคืนแอตทริบิวต์ DateTime จากวัตถุ DateTime เท่านั้น
print(type(my_date3a)) print(type(my_format_date)) Output: <class 'datetime.datetime'> <class 'str'>
โปรดทราบว่าผลคูณของ strftime() เป็นวัตถุสตริง ในขณะที่ผลคูณของ strptime() เป็นวัตถุ DateTime
3. คำนวณสัปดาห์โลกจากวันที่
หมายเหตุ: ในส่วนนี้ เราจะใช้ตัวแปรใหม่สำหรับตัวอย่าง
ขั้นแรก ฉันสร้างออบเจ็กต์สตริงใหม่สองออบเจ็กต์ที่มีวันที่ต่างกัน จากนั้นแยกวิเคราะห์ออบเจ็กต์ดังกล่าวเป็นออบเจ็กต์ DateTime
import datetime as dt my_date_str_1 = "2022-07-01" my_date_1 = dt.datetime.strptime(my_date_str_1, "%Y-%m-%d") print(my_date_1) my_date_str_2 = "2022-07-03" my_date_2 = dt.datetime.strptime(my_date_str_2, "%Y-%m-%d") print(my_date_2) # Output: # 2022-07-01 00:00:00 # 2022-07-03 00:00:00
เราจะใช้วิธี isocalendar()
เพื่อรับข้อมูลสัปดาห์โลกจากวัตถุ DateTime เนื่องจากวัตถุ DateTime ไม่มีแอตทริบิวต์สัปดาห์โลก
print(my_date_1.isocalendar()) print(my_date_2.isocalendar()) # Output: # datetime.IsoCalendarDate(year=2022, week=26, weekday=5) # datetime.IsoCalendarDate(year=2022, week=26, weekday=7)
เมธอด isocalendar()
จะส่งคืนทูเปิลที่มีปี ISO หมายเลขสัปดาห์ และวันทำงาน วันธรรมดาจะถูกส่งกลับเป็นตัวเลข เราสามารถคืนค่าด้วยดัชนีที่เกี่ยวข้อง
print("Date 1: 2022-07-01") print("Year:", my_date_1.isocalendar()[0]) print("World Week Number: ", my_date_1.isocalendar()[1]) print("Weekday: ", my_date_1.isocalendar()[2]) print("Date 2: 2022-07-03") print("Year:", my_date_2.isocalendar()[0]) print("World Week Number: ", my_date_2.isocalendar()[1]) print("Weekday: ", my_date_2.isocalendar()[2]) # Output: # Date 1: 2022-07-01 # Year: 2022 # World Week Number: 26 # Weekday: 5 # Date 2: 2022-07-03 # Year: 2022 # World Week Number: 26 # Weekday: 7
นั่นคือวิธีที่เราได้รับหมายเลขสัปดาห์ รวมถึงปีและวันในสัปดาห์ด้วย
4. คำนวณวันในสัปดาห์จากวันที่
หมายเหตุ: ตัวอย่างด้านล่างใช้ตัวแปรจากตัวอย่างในส่วนที่ 3
มีมากกว่าหนึ่งวิธีในการส่งคืนข้อมูลวันทำงานจากวันที่ วิธีหนึ่งคือผ่านทาง isocalendar()
ดังที่แสดงไว้ในส่วนก่อนหน้า อีกวิธีหนึ่งกำลังใช้วิธี weekday()
ที่แสดงด้านล่าง
print("Date 1: 2022-07-01") print("Weekday: ", my_date_1.weekday()) print("Date 2: 2022-07-03") print("Weekday: ", my_date_2.weekday()) # Output: # Date 1: 2022-07-01 # Weekday: 4 # Date 2: 2022-07-03 # Weekday: 6
2022–07–01 เป็นวันศุกร์ เมธอด isocalendar()
ไม่เป็นไปตามกฎดัชนีหลาม จริงๆ แล้ว ทั้ง isocalendar()
และ weekday()
วิธีการเริ่มนับในวันจันทร์ แต่ isocalendar()
ใช้ดัชนีที่เริ่มต้นจาก 1 ในขณะที่ weekday() เป็นฟังก์ชันหลามที่เริ่มต้นจาก 0 ทั้งสองวิธีที่กล่าวถึงจะส่งกลับวันในสัปดาห์เป็นตัวเลข มีอีกวิธีหนึ่งในการทำเช่นนั้น คุณเดาได้ไหม🤔?
มันคือวิธี strftime()
เราสามารถรับชื่อของวันในสัปดาห์ได้โดยการจัดรูปแบบวันที่ด้วยโค้ดรูปแบบที่เกี่ยวข้อง
date_weekday_1 = dt.datetime.strftime(my_date_1, "%a") print(date_weekday_1) date_weekday_2 = dt.datetime.strftime(my_date_2, "%a") print(date_weekday_2) # Output: # Fri # Sun
เราสามารถส่งคืนชื่อย่อของวันในสัปดาห์ได้โดยการจัดรูปแบบโดยใช้โค้ดรูปแบบ “%a” ดังที่แสดงในตัวอย่างด้านบน หรือส่งคืนชื่อเต็มของวันในสัปดาห์โดยใช้โค้ดรูปแบบ “%A” ดังที่แสดงในตัวอย่างด้านล่าง
date_weekday_1 = dt.datetime.strftime(my_date_1, "%A") print(date_weekday_1) date_weekday_2 = dt.datetime.strftime(my_date_2, "%A") print(date_weekday_2) # Output: # Friday # Sunday
เรายังสามารถคืนวันธรรมดาเป็นตัวเลขได้อีกด้วย
date_weekday_1 = dt.datetime.strftime(my_date_1, "%w") print(date_weekday_1) date_weekday_2 = dt.datetime.strftime(my_date_2, "%w") print(date_weekday_2) # Output: # 5 # 0
เรื่องน่ารู้คือ เมื่อคุณใช้วิธี strftime()
การนับจะเริ่มในวันอาทิตย์และดัชนีจะเริ่มต้นจาก 0 เช่นเดียวกับที่แสดงใน เอกสารประกอบ
เพื่อความเข้าใจที่ดีขึ้น ฉันได้รวมตารางเปรียบเทียบด้านล่างเพื่อแสดงความแตกต่างระหว่างวิธีการสองสามวิธีที่ส่งคืนวันธรรมดาเป็นตัวเลขจากวันที่ที่ฉันแสดงด้านบน
5. แปลงวัตถุ DateTime เป็นระยะเวลา
หมายเหตุ: ในส่วนนี้ เราจะใช้ตัวแปรใหม่สำหรับตัวอย่าง
เราได้ศึกษาวิธีการและคุณลักษณะต่างๆ เพื่อส่งคืนปี เดือน วัน หมายเลขสัปดาห์โลก และวันทำงานแล้ว หากคุณยังจำตัวอย่างชื่อรายงานที่ฉันให้ไว้ตอนต้นบทความนี้ได้ “รายงานการใช้ไฟฟ้าปี 2022_Q4_WW43.xlsx” ยังมีข้อมูลชิ้นหนึ่งที่เรายังไม่ได้รับ ซึ่งก็คือ ไตรมาส
หากต้องการรับไตรมาสนับจากวันที่ เราต้องใช้ไลบรารี pandas
ร่วมกับไลบรารี DateTime
import pandas as pd import datetime as dt # pandas.Timestamp.to_period date_1 = '2022-10-21' timestamp_1 = pd.Timestamp(date_1)
ขั้นแรก เราสร้างวันที่เป็นวัตถุสตริง จากนั้นแปลงเป็นการประทับเวลา หลังจากนั้นเราสามารถแปลงการประทับเวลาเป็นระยะเวลาได้
year_period = timestamp_1.to_period(freq='Y') month_period = timestamp_1.to_period(freq='M') week_period = timestamp_1.to_period(freq='W') quarter_period = timestamp_1.to_period(freq='Q') print("Year: ", year_period) print("Month: ", month_period) print("Week: ", week_period) print("Quarter: ", quarter_period) # Output: # Year: 2022 # Month: 2022-10 # Week: 2022-10-17/2022-10-23 # Quarter: 2022Q4
มันค่อนข้างง่ายใช่มั้ย?
ตาม "เอกสารอย่างเป็นทางการของ pandas" มีเอาต์พุตเพียง 4 ประเภทสำหรับเมธอด pandas.Timestamp.to_period()
ในส่วนก่อนหน้า เราจะแยกปี เดือน และสัปดาห์ออกจากกัน จากนั้นเมธอดนี้จะส่งคืนระยะเวลาที่ระบุของวันที่แทน เช่น ไตรมาสที่ 4 ปี 2022 หมายถึงไตรมาสที่ 4 ของปี 2022
ต้องมีอีกขั้นตอนหนึ่งในการเรียกข้อมูลเฉพาะ "ไตรมาสที่ 4" แทนที่จะเป็น "2022Q4" ตัวแปร quarter_period
เป็นวัตถุจุดในขณะนี้ ดังนั้น เราจำเป็นต้องแปลงมันเป็นวัตถุสตริง จากนั้นส่งคืนสองสตริงสุดท้ายเพื่อรับ “Q4”
print(str(quarter_period))[-2:]
นอกจากนั้น เราสามารถกำหนดฟังก์ชัน python เพื่อระบุไตรมาสของแต่ละเดือนได้ วิธีนี้ยังใช้ได้เมื่อองค์กรของคุณมีวิธีการคำนวณปีทางการเงินของตัวเองอีกด้วย เช่น ไตรมาสแรกอาจตกในเดือนพฤศจิกายน ธันวาคม และมกราคม
# Output: # Q4
ข้อมูลข้างต้นแสดงวิธีการส่งคืนไตรมาสเมื่อองค์กรของคุณไม่ปฏิบัติตามข้อกำหนดไตรมาสมาตรฐาน คุณสามารถแก้ไขเงื่อนไขตามคำจำกัดความไตรมาสขององค์กรของคุณ
6. คำนวณช่วงเวลา DataTime
หมายเหตุ: ในส่วนนี้ เราจะใช้ตัวแปรใหม่สำหรับตัวอย่าง
การคำนวณช่วง DateTime มีสองประเภท:
- คำนวณช่วงเวลาระหว่างวันที่สองวัน
- เพิ่ม/ลบช่วงเวลาถึงวันที่
มาดูกันทีละคน!
ก่อนหน้านั้น เรามาสร้างวันที่สำหรับตัวอย่างกันดีกว่า
import datetime as dt my_date1 = dt.datetime.fromisoformat("2022-07-01") my_date2 = dt.datetime.fromisoformat("2022-07-05")
คำนวณช่วงเวลาระหว่างวันที่สองวัน
การคำนวณช่วงเวลาระหว่างวันที่สองวันทำได้ง่ายมาก เราแค่ต้องการลบวันที่หนึ่งจากอีกวันที่หนึ่ง
print(my_date2 - my_date1) # Output: # datetime.timedelta(days=4)
ผลลัพธ์จะเป็น timedelta ซึ่งอ้างอิงถึงความแตกต่างระหว่างออบเจ็กต์ DateTime สองรายการ
เพิ่ม/ลบช่วงเวลาถึงวันที่
อีกตัวอย่างหนึ่งคือการเพิ่มหรือลบช่วงเวลาของวันที่
from datetime import timedelta print(my_date2 - timedelta(days=10)) print(my_date2 + timedelta(days=10)) print(my_date2 - timedelta(seconds=10)) print(my_date2 + timedelta(seconds=10)) # Output: # 2022-06-25 00:00:00 # 2022-07-15 00:00:00 # 2022-07-04 23:59:50 # 2022-07-05 00:00:10
เราจะใช้ "คลาส timedelta จากไลบรารี DateTime" สำหรับการดำเนินการนี้ คลาสนี้อนุญาตให้เราเพิ่ม/ลบวัน วินาที หรือไมโครวินาทีไปยัง/จากวันที่
บทสรุป
โดยสรุป มีการแสดงวิธีการแยกวิเคราะห์วัตถุสตริงลงในวัตถุ DateTime และการจัดรูปแบบวัตถุ DateTime เป็นรูปแบบเฉพาะ จากนั้นจะมีการหารือถึงวิธีรับปี เดือน วัน สัปดาห์โลก และวันธรรมดานับจากวันที่นั้น
วิธีการแปลงออบเจ็กต์ DateTime เป็นระยะเวลา เช่น ปี หนึ่งเดือนในปี และหนึ่งในสี่ของปีได้ถูกนำเสนอไว้ สำหรับองค์กรที่มีวิธีการคำนวณปีทางการเงิน สามารถใช้ใบแจ้งยอดเงื่อนไขเพื่อส่งคืนไตรมาสที่ถูกต้องได้
สุดท้ายนี้ มีการอธิบายการคำนวณสองประเภทสำหรับช่วง DateTime ซึ่งคำนวณช่วงเวลาระหว่างวันที่สองวันและเพิ่ม/ลบช่วงเวลาของวันที่
ด้วยวิธีการและตัวอย่างทั้งหมดที่ฉันได้แสดงไป คุณสามารถสร้างชื่อไฟล์ด้านล่างขึ้นใหม่พร้อมกับวันที่ของวันนี้ (26/10/2022) ได้หรือไม่ 😎 ใส่คำตอบของคุณในความคิดเห็นได้เลย!
- “รายงานการใช้ไฟฟ้าปี 2022_Q4_WW43.xlsx”
- “รายงานคำขอเครื่องมือ 20221021.csv”
คำตอบที่ด้านล่างของบทความ ลองด้วยตัวเองก่อนที่จะตรวจสอบคำตอบ! 😉
ฉันหวังว่าคุณจะสนุกกับการอ่านบทความนี้ และหวังว่าจะช่วยให้คุณเข้าใจเพิ่มเติมเกี่ยวกับวิธีจัดการกับวัตถุ DateTime ใน Python ขอบคุณ! 😊
เชื่อมต่ออยู่เสมอ
สมัครสมาชิกบน "YouTube"
หมายเหตุด้านข้าง
ใน เคล็ดลับการรายงานอัตโนมัติด้วย Python ฉันได้อธิบายเคล็ดลับบางประการเกี่ยวกับรายงานอัตโนมัติแล้ว ตรวจสอบออก!
อ้างอิง
- เอกสารประกอบโมดูล DateTime ของ Python
- เอกสาร pandas.Timestamp.to_ period
- พฤติกรรม strftime() และ strptime()
ขอขอบคุณและขอแสดงความยินดีที่อ่านจนจบ😊!
คำตอบ:
หวังว่าคุณจะเข้าใจถูกต้อง! 😊