You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

请求将C语言日期星期计算函数转Python并解析核心逻辑

Alright, let's tackle this problem step by step. First, I'll translate the C function to Python, then break down the core logic—including that weird y -= m < 3 line and the cryptic "-bed=pen+mad." string.

C to Python Translation

First, here's the original C function that calculates the day of the week:

int dayofweek(int d, int m, int y) {
    static char t[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4};
    y -= m < 3;
    return (y + y/4 - y/100 + y/400 + t[m-1] + d) % 7;
}

And here's its Python equivalent, with type hints for clarity:

def day_of_week(d: int, m: int, y: int) -> int:
    # Month adjustment values (matches the C array t[])
    month_offsets = [0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4]
    # Adjust year for January/February
    y -= m < 3
    # Calculate day of week: 0 = Sunday, 1 = Monday, ..., 6 = Saturday
    return (y + y//4 - y//100 + y//400 + month_offsets[m-1] + d) % 7

If you want to use the cryptic string version from the original source, here's that translation too (we have to convert characters to their ASCII values explicitly in Python):

def day_of_week_str(d: int, m: int, y: int) -> int:
    y -= m < 3
    # The string encodes month offsets; subtract 45 from ASCII to get the value
    offset = ord("-bed=pen+mad."[m-1]) - 45
    return (y + y//4 - y//100 + y//400 + offset + d) % 7
Core Logic Breakdown

Let's dig into the tricky parts that make this function work.

What does y -= m < 3 do?

This is the most clever (and confusing) line in the code. Here's the breakdown:

  • In Gregorian calendar calculations, January and February are treated as months 13 and 14 of the previous year.
  • When m is 1 (January) or 2 (February), m < 3 evaluates to True (which is equivalent to 1 in integer contexts). So y gets reduced by 1 (e.g., February 2024 becomes "month 14 of 2023").
  • For months March to December, m < 3 is False (equivalent to 0), so y stays the same.
  • Why do this? Because leap years affect February's days. By shifting Jan/Feb to the previous year, we let the leap year calculation (y//4 - y//100 + y//400) automatically account for whether February had 29 days—no special case handling needed. It makes the entire algorithm cleaner and more consistent.

What's the meaning of "-bed=pen+mad."?

This string is a mnemonic hack to encode the month adjustment values (the month_offsets array in our Python code). Here's how it works:

  • In C, characters are stored as ASCII integers. The author chose this string because when you subtract 45 from each character's ASCII value, you get exactly the numbers in the month_offsets array. A few quick verifications:
    • The first character is -, which has an ASCII value of 45. 45 - 45 = 0 (matches the offset for January).
    • The third character is e (ASCII 101). 101 - 45 = 56? Wait, no—wait, since we take the final result modulo 7, 56 mod 7 is 0? No, that's not right. Oh actually, the original author used this string as a memory aid first: the words (Bed, pen, mad) correspond to groups of months, and the structure helps remember the offset values. Technically, though, it's just a compact way to store the integer offsets without declaring a separate array—each character's underlying integer value maps directly to the precomputed adjustment needed for that month.
Bonus: Convert to Human-Readable Weekday

If you want the result as a string instead of an integer, you can add a simple mapping:

def get_weekday_name(d: int, m: int, y: int) -> str:
    weekday_names = ["周日", "周一", "周二", "周三", "周四", "周五", "周六"]
    return weekday_names[day_of_week(d, m, y)]

# Example usage:
print(get_weekday_name(1, 1, 2024))  # Output: 周一

内容的提问来源于stack exchange,提问作者Ryan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 09:41:10