ระบบอัตโนมัติด้วย Python

การจัดการกับวันที่ใน Python

บทความนี้เกี่ยวกับการจัดการที่เป็นไปได้ที่คุณสามารถทำได้กับตัวแปร DateTime

คุณประสบปัญหาเมื่อต้องจัดการกับวัตถุ DateTime หรือไม่? ก็ต้องยอมรับว่าทะเลาะกันบ่อย ฉันจำเป็นต้องค้นหาวิธีการที่เหมาะสมสำหรับกรณีการใช้งานของฉันอยู่เสมอ จากนั้น ฉันจึงตัดสินใจเขียนบทความนี้ เพื่อเป็นเอกสารสำหรับผู้อ่านที่รักและตัวฉันเอง

พื้นหลัง

เมื่อฉันกำลังพัฒนาเครื่องมือเพื่อเตรียมรายงานหรือรวมไฟล์ Excel โดยอัตโนมัติ ฉันจะต้องสามารถระบุข้อมูลจากชื่อไฟล์หรือโฟลเดอร์ได้ โดยปกติไฟล์ที่ระบบสร้างขึ้นหรือรายงานเป็นระยะๆ จะถูกตั้งชื่อตามรูปแบบที่ตายตัวและจะถูกจัดเก็บไว้ในโฟลเดอร์เดียวกัน

โดยปกติชื่อไฟล์จะเป็นการรวมกันของชื่อรายงาน วันที่หรือรอบระยะเวลาของรายงาน และนามสกุลไฟล์ ตัวอย่างเช่น รายงานเป็นระยะชื่อ “รายงานการใช้ไฟฟ้าปี 2022_Q4_WW43.xlsx”และรายงานรายวันชื่อ “รายงานคำขอเครื่องมือ 20221021.csv” ในการดึงไฟล์ที่ถูกต้อง เราจะต้องคำนวณวันที่หรือรอบระยะเวลาในชื่อไฟล์ตามเวลาที่เครื่องมือรายงานอัตโนมัติทำงาน

ด้วยเหตุนี้ บทความนี้จะมีโครงสร้างดังนี้:

  1. การแยกวิเคราะห์และการจัดรูปแบบ DateTime (strptimevs strftime)
  2. ดึงข้อมูลปี / เดือน / วัน
  3. คำนวณสัปดาห์โลกจากวันที่
  4. คำนวณวันสัปดาห์จากวันที่
  5. แปลงวัตถุ DateTime เป็นงวด
  6. คำนวณช่วงเวลาข้อมูล

มาเริ่มกันเลย!

การแยกวิเคราะห์ 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 มีสองประเภท:

  1. คำนวณช่วงเวลาระหว่างวันที่สองวัน
  2. เพิ่ม/ลบช่วงเวลาถึงวันที่

มาดูกันทีละคน!

ก่อนหน้านั้น เรามาสร้างวันที่สำหรับตัวอย่างกันดีกว่า

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 ฉันได้อธิบายเคล็ดลับบางประการเกี่ยวกับรายงานอัตโนมัติแล้ว ตรวจสอบออก!

อ้างอิง

  1. เอกสารประกอบโมดูล DateTime ของ Python
  2. เอกสาร pandas.Timestamp.to_ period
  3. พฤติกรรม strftime() และ strptime()

ขอขอบคุณและขอแสดงความยินดีที่อ่านจนจบ😊!

คำตอบ:

หวังว่าคุณจะเข้าใจถูกต้อง! 😊