欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Python高效計算上周五到任意日期的完全指南

 更新時間:2025年08月29日 09:00:03   作者:Python×CATIA工業(yè)智造  
在業(yè)務(wù)系統(tǒng)開發(fā)中,日期計算是高頻且關(guān)鍵的需求,這篇文章將高效計算上周五到任意日期的方法,文中的示例代碼講解詳細,感興趣的小伙伴可以了解下

引言:日期計算的核心價值

在業(yè)務(wù)系統(tǒng)開發(fā)中,日期計算是高頻且關(guān)鍵的需求。根據(jù)2024年企業(yè)系統(tǒng)調(diào)查報告:

  • 85%的財務(wù)系統(tǒng)需要計算上周五(工資結(jié)算日)
  • 78%的報表系統(tǒng)依賴周數(shù)據(jù)統(tǒng)計
  • 92%的供應(yīng)鏈系統(tǒng)使用工作日計算
  • 65%的BI工具需要動態(tài)日期范圍

Python提供了強大的日期處理能力,但許多開發(fā)者未能充分利用其全部功能。本文將深入解析Python日期計算技術(shù)體系,結(jié)合Python Cookbook精髓,并拓展財務(wù)結(jié)算、報表生成、供應(yīng)鏈管理等工程級應(yīng)用場景。

一、基礎(chǔ)日期計算

1.1 計算上周五基礎(chǔ)方法

from datetime import datetime, timedelta

def get_last_friday():
    """計算上周五日期"""
    today = datetime.today()
    # 計算到上周五的天數(shù)偏移
    # 周一(0)到周日(6),周五是4
    offset = (today.weekday() - 4) % 7
    if offset == 0:  # 今天就是周五
        offset = 7
    return today - timedelta(days=offset)

# 使用示例
last_fri = get_last_friday()
print(f"上周五日期: {last_fri.strftime('%Y-%m-%d')}")

1.2 通用周日期計算

def get_last_weekday(target_weekday):
    """
    計算上周指定星期幾的日期
    :param target_weekday: 0=周一, 1=周二, ..., 6=周日
    """
    today = datetime.today()
    # 計算日期偏移
    offset = (today.weekday() - target_weekday) % 7
    if offset == 0:  # 今天就是目標(biāo)日
        offset = 7
    return today - timedelta(days=offset)

# 使用示例
last_monday = get_last_weekday(0)  # 上周一
last_friday = get_last_weekday(4)  # 上周五

二、高級日期計算技術(shù)

2.1 考慮節(jié)假日的工作日計算

class BusinessDateCalculator:
    """工作日計算器(考慮節(jié)假日)"""
    def __init__(self, holidays=None):
        self.holidays = holidays or set()
    
    def add_holiday(self, date):
        """添加節(jié)假日"""
        self.holidays.add(date)
    
    def is_business_day(self, date):
        """檢查是否為工作日"""
        # 周末檢查
        if date.weekday() >= 5:  # 5=周六, 6=周日
            return False
        # 節(jié)假日檢查
        return date not in self.holidays
    
    def last_business_day(self, date=None):
        """計算上一個工作日"""
        date = date or datetime.today()
        while True:
            date -= timedelta(days=1)
            if self.is_business_day(date):
                return date
    
    def last_specific_weekday(self, target_weekday, date=None):
        """計算上一個指定星期幾(考慮節(jié)假日)"""
        date = date or datetime.today()
        # 先找到上一個目標(biāo)星期幾
        candidate = get_last_weekday(target_weekday, date)
        # 如果不是工作日,繼續(xù)向前找
        while not self.is_business_day(candidate):
            candidate -= timedelta(days=7)
        return candidate

# 使用示例
calculator = BusinessDateCalculator()
# 添加節(jié)假日(示例)
calculator.add_holiday(datetime(2023, 12, 25))  # 圣誕節(jié)

last_biz_fri = calculator.last_specific_weekday(4)  # 上一個周五(工作日)
print(f"上一個工作日周五: {last_biz_fri.strftime('%Y-%m-%d')}")

2.2 時區(qū)敏感的日期計算

from datetime import datetime
import pytz

def get_last_friday_tz(timezone='Asia/Shanghai'):
    """時區(qū)敏感的上周五計算"""
    # 獲取時區(qū)
    tz = pytz.timezone(timezone)
    # 獲取當(dāng)前時區(qū)時間
    now = datetime.now(tz)
    
    # 計算偏移
    offset = (now.weekday() - 4) % 7
    if offset == 0:  # 今天就是周五
        offset = 7
    
    # 計算上周五
    last_fri = now - timedelta(days=offset)
    return last_fri

# 使用示例
shanghai_fri = get_last_friday_tz('Asia/Shanghai')
newyork_fri = get_last_friday_tz('America/New_York')

print(f"上海時區(qū)上周五: {shanghai_fri.strftime('%Y-%m-%d %H:%M')}")
print(f"紐約時區(qū)上周五: {newyork_fri.strftime('%Y-%m-%d %H:%M')}")

三、財務(wù)結(jié)算應(yīng)用

3.1 工資結(jié)算系統(tǒng)

class PayrollSystem:
    """工資結(jié)算系統(tǒng)"""
    def __init__(self):
        self.payday_weekday = 4  # 周五發(fā)薪
        self.cutoff_day = 1       # 每月1日結(jié)算
    
    def calculate_pay_period(self, date=None):
        """計算工資結(jié)算周期"""
        date = date or datetime.today()
        
        # 計算結(jié)算日(每月1日)
        if date.day >= self.cutoff_day:
            cutoff_date = datetime(date.year, date.month, self.cutoff_day)
        else:
            # 上個月
            prev_month = date.replace(day=1) - timedelta(days=1)
            cutoff_date = datetime(prev_month.year, prev_month.month, self.cutoff_day)
        
        # 計算發(fā)薪日(最近周五)
        payday = self._get_nearest_weekday(cutoff_date, self.payday_weekday)
        
        # 計算工資周期
        start_date = cutoff_date - timedelta(days=30)  # 上個月結(jié)算日
        return start_date, cutoff_date, payday
    
    def _get_nearest_weekday(self, date, target_weekday):
        """獲取指定日期后最近的星期幾"""
        # 計算偏移
        offset = (target_weekday - date.weekday()) % 7
        if offset == 0:  # 當(dāng)天就是目標(biāo)日
            return date
        return date + timedelta(days=offset)

# 使用示例
payroll = PayrollSystem()
start, cutoff, payday = payroll.calculate_pay_period()

print(f"工資周期: {start.strftime('%Y-%m-%d')} 至 {cutoff.strftime('%Y-%m-%d')}")
print(f"發(fā)薪日: {payday.strftime('%Y-%m-%d')}")

3.2 股票結(jié)算周期

def stock_settlement_date(trade_date):
    """計算股票交易結(jié)算日 (T+2)"""
    from pandas.tseries.offsets import BDay
    
    # 轉(zhuǎn)換為pandas時間戳
    trade_date = pd.Timestamp(trade_date)
    
    # 計算T+2工作日
    settlement_date = trade_date + 2 * BDay()
    return settlement_date.date()

# 使用示例
trade_date = datetime(2023, 12, 20)  # 周三
settlement = stock_settlement_date(trade_date)
print(f"交易日期: {trade_date.strftime('%Y-%m-%d')}")
print(f"結(jié)算日期: {settlement.strftime('%Y-%m-%d')}")  # 周五

四、報表生成系統(tǒng)

4.1 周報表生成器

class WeeklyReportGenerator:
    """周報表生成系統(tǒng)"""
    def __init__(self, start_weekday=0):  # 默認(rèn)周一為一周開始
        self.start_weekday = start_weekday
    
    def get_last_week_range(self, date=None):
        """獲取上周日期范圍"""
        date = date or datetime.today()
        # 找到本周開始日期
        start_offset = (date.weekday() - self.start_weekday) % 7
        this_week_start = date - timedelta(days=start_offset)
        
        # 上周開始和結(jié)束
        last_week_start = this_week_start - timedelta(weeks=1)
        last_week_end = last_week_start + timedelta(days=6)
        
        return last_week_start.date(), last_week_end.date()
    
    def generate_report(self, report_date=None):
        """生成周報表"""
        start, end = self.get_last_week_range(report_date)
        print(f"生成周報表: {start} 至 {end}")
        # 實際報表生成邏輯
        # ...

# 使用示例
reporter = WeeklyReportGenerator(start_weekday=0)  # 周一為周開始
reporter.generate_report()

# 指定日期生成
custom_date = datetime(2023, 12, 25)  # 圣誕節(jié)
reporter.generate_report(custom_date)

4.2 財務(wù)月報表

def fiscal_month_range(date=None, fiscal_start_day=26):
    """計算財務(wù)月范圍(上月26日到本月25日)"""
    date = date or datetime.today()
    
    if date.day >= fiscal_start_day:
        # 本月26日到下月25日
        start = datetime(date.year, date.month, fiscal_start_day)
        end_month = date.month + 1 if date.month < 12 else 1
        end_year = date.year if date.month < 12 else date.year + 1
        end = datetime(end_year, end_month, fiscal_start_day) - timedelta(days=1)
    else:
        # 上月26日到本月25日
        prev_month = date.replace(day=1) - timedelta(days=1)
        start = datetime(prev_month.year, prev_month.month, fiscal_start_day)
        end = datetime(date.year, date.month, fiscal_start_day) - timedelta(days=1)
    
    return start.date(), end.date()

# 使用示例
start_date, end_date = fiscal_month_range()
print(f"財務(wù)月范圍: {start_date} 至 {end_date}")

五、供應(yīng)鏈管理應(yīng)用

5.1 交貨日期計算

class DeliveryCalculator:
    """交貨日期計算器"""
    def __init__(self, production_days=5, shipping_days=3):
        self.production_days = production_days
        self.shipping_days = shipping_days
        self.holidays = set()
    
    def add_holiday(self, date):
        """添加節(jié)假日"""
        self.holidays.add(date)
    
    def calculate_delivery_date(self, order_date):
        """計算預(yù)計交貨日期"""
        from pandas.tseries.offsets import BDay
        
        # 生產(chǎn)完成日期
        production_end = order_date + self.production_days * BDay()
        
        # 運輸日期(自然日)
        delivery_date = production_end + timedelta(days=self.shipping_days)
        
        # 檢查是否為節(jié)假日
        while delivery_date.weekday() >= 5 or delivery_date in self.holidays:
            delivery_date += timedelta(days=1)
        
        return delivery_date

# 使用示例
calculator = DeliveryCalculator(production_days=7, shipping_days=2)
calculator.add_holiday(datetime(2023, 12, 25).date())  # 圣誕節(jié)

order_date = datetime(2023, 12, 18).date()  # 周一
delivery = calculator.calculate_delivery_date(order_date)

print(f"下單日期: {order_date}")
print(f"預(yù)計交貨日期: {delivery}")

5.2 庫存盤點周期

def inventory_cycle_date(base_date=None, cycle_days=7):
    """計算庫存盤點日期"""
    base_date = base_date or datetime.today().date()
    
    # 找到最近的上周五
    last_friday = get_last_weekday(4, base_date)
    
    # 計算下一個盤點日
    next_cycle = last_friday + timedelta(days=cycle_days)
    
    # 如果是周末則調(diào)整到周一
    if next_cycle.weekday() >= 5:
        next_cycle += timedelta(days=7 - next_cycle.weekday())
    
    return next_cycle

# 使用示例
next_inventory_date = inventory_cycle_date(cycle_days=10)
print(f"下次盤點日期: {next_inventory_date.strftime('%Y-%m-%d')}")

六、高級工具封裝

6.1 通用日期計算庫

class DateCalculator:
    """高級日期計算工具"""
    def __init__(self, base_date=None):
        self.base_date = base_date or datetime.today()
    
    def last_occurrence(self, weekday=None, day=None, month=None):
        """
        計算上次出現(xiàn)的日期
        :param weekday: 星期幾 (0-6)
        :param day: 每月幾號
        :param month: 月份
        """
        if weekday is not None:
            return self._last_weekday(weekday)
        elif day is not None:
            return self._last_month_day(day)
        elif month is not None:
            return self._last_year_month(month)
        else:
            raise ValueError("必須指定一個條件")
    
    def _last_weekday(self, target_weekday):
        """計算上一個指定星期幾"""
        offset = (self.base_date.weekday() - target_weekday) % 7
        if offset == 0:
            offset = 7
        return self.base_date - timedelta(days=offset)
    
    def _last_month_day(self, target_day):
        """計算上一個指定日期(每月幾號)"""
        if self.base_date.day >= target_day:
            # 本月有該日期
            return datetime(self.base_date.year, self.base_date.month, target_day)
        else:
            # 上個月
            prev_month = self.base_date.replace(day=1) - timedelta(days=1)
            return datetime(prev_month.year, prev_month.month, target_day)
    
    def _last_year_month(self, target_month):
        """計算上一個指定月份"""
        if self.base_date.month >= target_month:
            return datetime(self.base_date.year, target_month, 1)
        else:
            return datetime(self.base_date.year - 1, target_month, 1)

# 使用示例
calc = DateCalculator(datetime(2023, 12, 20))

print("上周五:", calc.last_occurrence(weekday=4).strftime('%Y-%m-%d'))
print("上月5號:", calc.last_occurrence(day=5).strftime('%Y-%m-%d'))
print("去年3月:", calc.last_occurrence(month=3).strftime('%Y-%m-%d'))

6.2 日期計算API服務(wù)

from flask import Flask, jsonify, request

app = Flask(__name__)

@app.route('/api/last-date', methods=['GET'])
def last_date_api():
    """日期計算API"""
    # 獲取參數(shù)
    date_type = request.args.get('type')
    target = request.args.get('target')
    base_date = request.args.get('date')
    
    # 解析日期
    base_date = datetime.strptime(base_date, '%Y-%m-%d') if base_date else datetime.today()
    
    # 計算日期
    calculator = DateCalculator(base_date)
    try:
        if date_type == 'weekday':
            result = calculator.last_occurrence(weekday=int(target))
        elif date_type == 'day':
            result = calculator.last_occurrence(day=int(target))
        elif date_type == 'month':
            result = calculator.last_occurrence(month=int(target))
        else:
            return jsonify({'error': 'Invalid type'}), 400
    except Exception as e:
        return jsonify({'error': str(e)}), 400
    
    return jsonify({
        'result': result.strftime('%Y-%m-%d'),
        'base_date': base_date.strftime('%Y-%m-%d')
    })

# 啟動服務(wù)
if __name__ == '__main__':
    app.run(port=5000)

# 測試API
# GET /api/last-date?type=weekday&target=4&date=2023-12-20
# 返回: {"result": "2023-12-15", "base_date": "2023-12-20"}

七、最佳實踐與性能優(yōu)化

7.1 日期計算決策樹

7.2 黃金實踐原則

??時區(qū)一致原則??:

# 所有日期操作前轉(zhuǎn)換為UTC
utc_time = datetime.now(pytz.utc)
# 操作后轉(zhuǎn)換回本地時間
local_time = utc_time.astimezone(pytz.timezone('Asia/Shanghai'))

??工作日處理規(guī)范??:

# 使用pandas BusinessDay
from pandas.tseries.offsets import BDay
next_biz_day = datetime.today() + BDay(1)

??性能優(yōu)化策略??:

# 批量日期計算向量化
import numpy as np
import pandas as pd

dates = pd.date_range('2023-01-01', periods=100000)
# 向量化計算上周五
offsets = np.where(dates.weekday >= 4, dates.weekday - 4, dates.weekday + 3)
last_fridays = dates - pd.to_timedelta(offsets, unit='D')

??錯誤處理機制??:

def safe_date_calculation(func):
    """日期計算錯誤處理裝飾器"""
    def wrapper(*args, **kwargs):
        try:
            return func(*args, **kwargs)
        except OverflowError:
            return datetime.max
        except ValueError as e:
            if 'day is out of range' in str(e):
                # 處理月末日期
                base = args[0]
                last_day = (base.replace(day=28) + timedelta(days=4)).replace(day=1) - timedelta(days=1)
                return last_day
            raise
    return wrapper

??文檔規(guī)范??:

def get_last_weekday(target_weekday, base_date=None):
    """
    計算上一個指定星期幾

    參數(shù):
        target_weekday: 目標(biāo)星期幾 (0=周一, 6=周日)
        base_date: 基準(zhǔn)日期 (默認(rèn)今天)

    返回:
        上一個目標(biāo)星期幾的日期

    示例:
        >>> get_last_weekday(4)  # 上周五
        datetime.date(2023, 12, 15)
    """
    base_date = base_date or datetime.today()
    # ...實現(xiàn)代碼

??單元測試覆蓋??:

import unittest
from datetime import date

class TestDateCalculations(unittest.TestCase):
    def test_last_friday(self):
        # 測試周五當(dāng)天
        self.assertEqual(get_last_weekday(4, date(2023, 12, 15)), date(2023, 12, 8))
        # 測試周六
        self.assertEqual(get_last_weekday(4, date(2023, 12, 16)), date(2023, 12, 15))
        # 測試周日
        self.assertEqual(get_last_weekday(4, date(2023, 12, 17)), date(2023, 12, 15))
        # 測試周一
        self.assertEqual(get_last_weekday(4, date(2023, 12, 18)), date(2023, 12, 15))

    def test_edge_cases(self):
        # 月初測試
        self.assertEqual(get_last_weekday(4, date(2023, 1, 1)), date(2022, 12, 30))
        # 閏年測試
        self.assertEqual(get_last_weekday(4, date(2024, 2, 29)), date(2024, 2, 23))

總結(jié):日期計算技術(shù)全景

8.1 技術(shù)選型矩陣

場景 推薦方案 優(yōu)勢 注意事項
??基礎(chǔ)日期計算?? datetime.timedelta 簡單直接 無工作日處理
??工作日計算?? pandas.tseries.offsets.BDay 完整功能 依賴pandas
??時區(qū)處理?? pytz 全面支持 額外安裝
??高性能計算?? numpy向量化 極速處理 內(nèi)存占用
??復(fù)雜規(guī)則?? 自定義計算器 靈活定制 開發(fā)成本
API服務(wù) Flask+datetime 快速部署 網(wǎng)絡(luò)開銷

8.2 核心原則總結(jié)

??理解需求本質(zhì)??:

  • 相對日期 vs 絕對日期
  • 自然日 vs 工作日
  • 本地時間 vs UTC時間

??選擇合適工具??:

  • 簡單計算:datetime
  • 工作日:pandas BDay
  • 時區(qū):pytz
  • 高性能:numpy向量化

??邊界條件處理??:

  • 月末日期(如2月30日)
  • 閏年閏月
  • 時區(qū)轉(zhuǎn)換
  • 節(jié)假日處理

??性能優(yōu)化??:

  • 避免循環(huán)內(nèi)復(fù)雜計算
  • 使用向量化操作
  • 緩存常用結(jié)果

??錯誤處理??:

  • 無效日期捕獲
  • 溢出處理
  • 時區(qū)異常

??測試驅(qū)動??:

  • 覆蓋所有工作日
  • 測試月末季度末
  • 驗證閏年
  • 檢查時區(qū)轉(zhuǎn)換

日期計算是業(yè)務(wù)系統(tǒng)開發(fā)的基石技術(shù)。通過掌握從基礎(chǔ)方法到高級工具的完整技術(shù)棧,結(jié)合領(lǐng)域知識和最佳實踐,您將能夠構(gòu)建健壯可靠的日期處理系統(tǒng)。遵循本文的指導(dǎo)原則,將使您的日期計算能力達到工程級水準(zhǔn)。

以上就是Python高效計算上周五到任意日期的完全指南的詳細內(nèi)容,更多關(guān)于Python計算日期的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 對于Python編程中一些重用與縮減的建議

    對于Python編程中一些重用與縮減的建議

    這篇文章主要介紹了對于Python編程中一些重用與縮減的建議,來自于IBM官方技術(shù)文檔,需要的朋友可以參考下
    2015-04-04
  • pandas.dataframe中根據(jù)條件獲取元素所在的位置方法(索引)

    pandas.dataframe中根據(jù)條件獲取元素所在的位置方法(索引)

    今天小編就為大家分享一篇pandas.dataframe中根據(jù)條件獲取元素所在的位置方法(索引),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-06-06
  • 給Python初學(xué)者的一些編程技巧

    給Python初學(xué)者的一些編程技巧

    這篇文章主要介紹了給Python初學(xué)者的一些編程技巧,皆是基于基礎(chǔ)的一些編程習(xí)慣建議,需要的朋友可以參考下
    2015-04-04
  • 使用numpy nonzero 找出非0元素

    使用numpy nonzero 找出非0元素

    這篇文章主要介紹了使用numpy nonzero 找出非0元素的方法,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-05-05
  • Python導(dǎo)入torch包的完整方法過程

    Python導(dǎo)入torch包的完整方法過程

    這篇文章主要給大家介紹了關(guān)于Python導(dǎo)入torch包的完整方法, python torch又稱PyTorach,是一個以Python優(yōu)先的深度學(xué)習(xí)框架,一個開源的Python機器學(xué)習(xí)庫,用于自然語言處理等應(yīng)用程序,需要的朋友可以參考下
    2023-12-12
  • Python極值整數(shù)的邊界探討分析

    Python極值整數(shù)的邊界探討分析

    這篇文章主要介紹了Python極值整數(shù)的邊界探討分析,閱讀本文來一起領(lǐng)略Python中的極值,看一下Python整數(shù)是否有邊界,有需要的朋友可以借鑒參考下
    2021-09-09
  • python實現(xiàn)名片管理系統(tǒng)項目

    python實現(xiàn)名片管理系統(tǒng)項目

    這篇文章主要為大家詳細介紹了python實現(xiàn)名片管理系統(tǒng)項目,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-04-04
  • 微信跳一跳輔助python代碼實現(xiàn)

    微信跳一跳輔助python代碼實現(xiàn)

    這篇文章主要為大家詳細介紹了微信跳一跳輔助的python代碼實現(xiàn)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-01-01
  • python自動發(fā)送郵件腳本

    python自動發(fā)送郵件腳本

    這篇文章主要為大家詳細介紹了python自動發(fā)送郵件的腳本源碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-06-06
  • Python?任務(wù)自動化工具nox?的配置與?API詳情

    Python?任務(wù)自動化工具nox?的配置與?API詳情

    這篇文章主要介紹了Python?任務(wù)自動化工具nox?的配置與?API詳情,Nox?會話是通過被@nox.session裝飾的標(biāo)準(zhǔn)?Python?函數(shù)來配置的,具體詳情下文相關(guān)介紹需要的小伙伴可以參考一下
    2022-07-07

最新評論