Nhận ngày từ số tuần


89

Xin vui lòng có gì sai với mã của tôi:

import datetime
d = "2013-W26"
r = datetime.datetime.strptime(d, "%Y-W%W")
print(r)

Hiển thị "2013-01-01 00:00:00", Cảm ơn.

Câu trả lời:


175

Số tuần không đủ để tạo ngày; bạn cũng cần một ngày trong tuần. Thêm mặc định:

import datetime
d = "2013-W26"
r = datetime.datetime.strptime(d + '-1', "%Y-W%W-%w")
print(r)

Mẫu -1-%wyêu cầu trình phân tích cú pháp chọn thứ Hai trong tuần đó. Kết quả này cho ra:

2013-07-01 00:00:00

%Wsử dụng thứ Hai là ngày đầu tiên trong tuần. Mặc dù bạn có thể chọn ngày trong tuần của riêng mình, nhưng bạn có thể nhận được kết quả không mong đợi nếu đi chệch hướng đó.

Xem phần strftime()strptime()hành vi trong tài liệu, chú thích 4:

Khi được sử dụng với strptime()phương pháp, %U%Wchỉ được sử dụng trong tính toán khi ngày trong tuần và năm được chỉ định.

Lưu ý, nếu số tuần của bạn là ngày theo tuần ISO , bạn sẽ muốn sử dụng %G-W%V-%uthay thế! Các lệnh đó yêu cầu Python 3.6 hoặc mới hơn.


1
Tôi ước tôi có thể cho bạn nhiều hơn 1 phiếu bầu ... Tôi đã đập đầu suy nghĩ tại sao nó không hoạt động.
Islam Q.

2
Không hoạt động. datetime.datetime.strptime ("2018-W0-0", "% YW% W-% w") == datetime.datetime.strptime ("2018-W1-0", "% YW% W-% w") -> "2018-01-07 00:00:00". Tuần thứ nhất và thứ hai của năm 2018 có cùng ngày khai giảng.
ozw1z5rd

2
@ ozw1z5rd: đó là bởi vì không có tuần 0 trong năm 2018. Tuần 0 là một phần của tuần trước ngày Thứ Hai đầu tiên của năm; năm 2018, thứ Hai đầu tiên là ngày 1 tháng Giêng. Nói cách khác, chuỗi đầu vào của bạn là vấn đề ở đây, không phải kỹ thuật và Python đã sửa lỗi để diễn giải W0 thành W1 thay thế.
Martijn Pieters

@ ozw1z5rd: Nếu đây là vấn đề đối với ứng dụng của bạn, bạn sẽ cần đề phòng trường hợp đặc biệt trong những năm như vậy; if d.endswith('-W0') and r.day == 7: raise ValueError('Invalid date string, No week 0 in {}'.format(r.year))
Martijn Pieters

1
@darda: Python 3.6 đã hỗ trợ định nghĩa tuần ISO 8601, sử dụng %G(năm cho phần lớn hơn trong tuần) và %Vtrong trường hợp đó.
Martijn Pieters

27

Để hoàn thành các câu trả lời khác - nếu bạn đang sử dụng số tuần ISO , thì chuỗi này phù hợp (để lấy thứ Hai của số tuần ISO nhất định):

import datetime
d = '2013-W26'
r = datetime.datetime.strptime(d + '-1', '%G-W%V-%u')
print(r)

%G, %V, %uĐược chứng nhận ISO tương đương của %Y, %W, %w, vì vậy kết quả đầu ra này:

2013-06-24 00:00:00

Có sẵn trong Python 3.6+; từ tài liệu .


13

Trong Python 3.8 có tiện ích datetime.date.fromisocalendar:

>>> from datetime import date
>>> date.fromisocalendar(2020, 1, 1)  # (year, week, day of week)
datetime.date(2019, 12, 30, 0, 0)

Trong các phiên bản Python cũ hơn (3.7-), phép tính có thể sử dụng thông tin từ đó datetime.date.isocalendarđể tìm ra tuần tuân thủ ISO8601 tuần:

from datetime import date, timedelta

def monday_of_calenderweek(year, week):
    first = date(year, 1, 1)
    base = 1 if first.isocalendar()[1] == 1 else 8
    return first + timedelta(days=base - first.isocalendar()[2] + 7 * (week - 1))

Cả hai hoạt động cũng với datetime.datetime.


6
import datetime
res = datetime.datetime.strptime("2018 W30 w1", "%Y %W w%w")
print res

Thêm 1 như ngày trong tuần sẽ mang lại bắt đầu tuần hiện tại chính xác. Thêm thời gian (ngày = 6) sẽ cho bạn kết thúc tuần.

datetime.datetime(2018, 7, 23)

@Senthikumar C sẽ giống như bên dướires = datetime.datetime.strptime("2018 W30 w1", "%Y W%W w%w")
MD Alauddin Al-Amin

1

Trong trường hợp bạn có số tuần trong năm, chỉ cần thêm số tuần vào ngày đầu tiên của năm.

>>> import datetime
>>> from dateutil.relativedelta import relativedelta

>>> week = 40
>>> year = 2019
>>> date = datetime.date(year,1,1)+relativedelta(weeks=+week)
>>> date
datetime.date(2019, 10, 8)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.