Dapatkan tanggal dari nomor minggu


91

Tolong apa yang salah dengan kode saya:

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

Tampilkan "2013-01-01 00:00:00", Terima kasih.

Jawaban:


182

Nomor minggu tidak cukup untuk menghasilkan tanggal; Anda juga membutuhkan satu hari dalam seminggu. Tambahkan default:

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

The -1dan -%wpola menceritakan parser untuk memilih Senin di minggu itu. Output ini:

2013-07-01 00:00:00

%Wmenggunakan hari Senin sebagai hari pertama dalam seminggu. Meskipun Anda dapat memilih hari kerja Anda sendiri, Anda mungkin mendapatkan hasil yang tidak terduga jika Anda menyimpang dari itu.

Lihat bagian strftime()dan strptime()perilaku dalam dokumentasi, catatan kaki 4:

Saat digunakan dengan strptime()metode, %Udan %Whanya digunakan dalam perhitungan saat hari dalam seminggu dan tahun ditentukan.

Perhatikan, jika nomor minggu Anda adalah tanggal minggu ISO , Anda akan ingin menggunakan %G-W%V-%usebagai gantinya! Arahan tersebut membutuhkan Python 3.6 atau yang lebih baru.


2
Tidak bekerja. datetime.datetime.strptime ("2018-W0-0", "% YW% W-% w") == datetime.datetime.strptime ("2018-W1-0", "% YW% W-% w") -> "2018-01-07 00:00:00". Minggu pertama dan kedua tahun 2018 memiliki tanggal mulai yang sama.
ozw1z5rd

2
@ ozw1z5rd: itu karena tidak ada minggu 0 di 2018. Minggu 0 adalah minggu parsial sebelum Senin pertama tahun ini; pada tahun 2018 hari Senin pertama adalah tanggal 1 Januari. Dengan kata lain, string input Anda adalah masalahnya di sini, bukan tekniknya, dan Python telah melakukan koreksi kesalahan untuk menafsirkan W0 sebagai W1.
Martijn Pieters

@ ozw1z5rd: Jika ini adalah masalah untuk aplikasi Anda, Anda perlu kasus khusus tahun seperti itu; if d.endswith('-W0') and r.day == 7: raise ValueError('Invalid date string, No week 0 in {}'.format(r.year))
Martijn Pieters

Ada ide bagaimana menangani nomor minggu tanpa bantalan? (misalnya 2020-w1, 2020-w52)
Michael

@MichaelH .: Saya tidak yakin apa yang Anda tanyakan.
Martijn Pieters

30

Untuk melengkapi jawaban lainnya - jika Anda menggunakan angka minggu ISO , string ini sesuai (untuk mendapatkan hari Senin dari angka minggu ISO tertentu):

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

%G, %V, %uISO setara dari %Y, %W, %w, sehingga output ini:

2013-06-24 00:00:00

Tersedia dengan Python 3.6+; dari dokumen .


14

Di Python 3.8 ada yang berguna datetime.date.fromisocalendar :

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

Dalam versi Python yang lebih lama (3.7-), penghitungan dapat menggunakan informasi dari datetime.date.isocalendar untuk mengetahui minggu minggu yang sesuai dengan ISO8601:

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))

Keduanya bekerja juga dengan datetime.datetime.


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

Menambahkan 1 sebagai hari kerja akan menghasilkan awal minggu ini yang tepat. Menambahkan timedelta (hari = 6) akan memberi Anda akhir pekan.

datetime.datetime(2018, 7, 23)

@Senthikumar C yang seharusnya seperti di bawah inires = datetime.datetime.strptime("2018 W30 w1", "%Y W%W w%w")
MD Alauddin Al-Amin

Jawaban yang diterima bermasalah dengan tanggal 2021-01-04, dikatakan bahwa itu milik tahun 2020
ignacio.munizaga

1

Jika Anda memiliki jumlah minggu tahunan, tambahkan saja jumlah minggu pada hari pertama dalam setahun.

>>> 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)

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.