Python'da hafta numarası nasıl alınır?


339

Python ile 16 Haziran (wk24) tarihinde hangi hafta sayısının mevcut olduğunu nasıl öğrenebilirim?


1
@Donal: Biri 16 Haziran'a, diğeri 26 Haziran'a bakar.
interjay

5
1. haftayı tanımlayın. İsocalendar () bunu yapmanın tek yolu değildir.
Mark Tolonen

3
Çıkış Not strftime("%U", d)farklı olabilir isocalendar(). Örneğin, yılı 2004 olarak değiştirirseniz, 24. strftime()hafta ve 25. hafta kullanırsınız isocalendar().
moooeeeep

Yanıtlar:


409

datetime.dateisocalendar()takvim haftasını içeren bir demet döndüren bir yöntemi vardır :

>>> import datetime
>>> datetime.date(2010, 6, 16).isocalendar()[1]
24

datetime.date.isocalendar () , belirtilen tarih örneği için ilgili sırayla yıl, haftanumarası ve hafta içi içeren bir tuple döndüren bir örnek yöntemidir.


7
Eğer ' [1]' açıkladıysanız ya da bilgiyi nerede arayacağınıza dair bir işaretçi verdiyseniz yardımcı olacaktır .
Jonathan Leffler

5
Sanırım en kolay strftime kullanarak hafta numarasını ayıklamak olduğunu, bugün en iyi ithalat datetime = datetime.now () hafta = bugün.strftime ("% W")
bipsa

7
Bu biraz geç. Ama makinemde date(2010, 1, 1).isocalendar()[1]geri dönüyor 53. Dokümanlar: "ISO 2004 ayının ilk haftasında bu yüzden Pazar 2004 4 Ocak Pazartesi 2003 29 Aralık ve uçlarında başlar böylece Örneğin, 2004, Perşembe günü başlar date(2003, 12, 29).isocalendar() == (2004, 1, 1)ve date(2004, 1, 4).isocalendar() == (2004, 1, 7)."
jclancy

17
isocalendar()harika, ama ne istediğinizden emin olun. Bugün mükemmel bir örnek. 01/01/2016 eşittir (2015, 53, 5). now.strftime("%W")ve çoğu zaman istenen şeye now.strftime("%U")eşittir 00. STRFTIME örnekleri
DaveL17

güzel bir, ben sadece yararlı olacağını düşünüyorum şimdi gün ekledi, ben için ne serching oldu: D
Vitaliy Terziev

124

Hafta numarasını doğrudan datetime öğesinden dize olarak alabilirsiniz.

>>> import datetime
>>> datetime.date(2010, 6, 16).strftime("%V")
'24'

Ayrıca, aşağıdaki strftimeparametreyi değiştirerek yılın hafta numarasının farklı "türlerini" alabilirsiniz :

%U- Sıfır dolgulu ondalık sayı olarak yılın hafta numarası (haftanın ilk günü Pazar) . İlk Pazardan önceki yeni yılda tüm günler 0. haftada kabul edilir. Örnekler: 00 , 01,…, 53

%W- Ondalık sayı olarak yılın hafta numarası ( haftanın ilk günü Pazartesi ). İlk Pazartesi'den önceki yeni yılda tüm günler 0 haftada kabul edilir. Örnekler: 00 , 01,…, 53

[...]

( Bazı dağıtımların Python 2.7'sine aktarılan Python 3.6'ya eklenmiştir) Kolaylık sağlamak için C89 standardının gerektirmediği birkaç ek yönerge dahil edilmiştir. Bu parametrelerin tümü ISO 8601 tarih değerlerine karşılık gelir. Bunlar, strftime()yöntemle birlikte kullanıldığında tüm platformlarda bulunmayabilir .

[...]

%V- ISO 8601 haftasını ondalık sayı olarak, Pazartesi gününün ilk günü olarak alır. 01.Hafta 4 Ocak'ı içeren haftadır. Örnekler: 01 , 02,…, 53

from: datetime - Temel tarih ve saat türleri - Python 3.7.3 belgeleri

Buradan öğrendim . Python 2.7.6'da benim için çalıştı


Ne anlatıyorsun, bazı Linux kılavuzları? Python 2.7.5 ve 3.3.2 Invalid format stringbu paterni söylüyor . Dokümanları da bahsetmiyor %V.
Vsevolod Golovanov

3
Maalesef bundan bahsetmedim, buradan aldım . Python 2.7.6'da benim için çalıştı.
jotacor

2
Mükemmel cevap! Tarihlerinizin '<YEAR> - <ISOWEEK>' temsili ile ilgileniyorsanız, %G-%Vbunun yerine kullanın %Y-%V. %G%Y
KenHBS

Çalışması için şöyle yazmak zorunda kaldım: datetime.datetime (2010, 6, 16) .strftime ("% V") veya bu datetime.datetime (2010, 6, 16) .date (). Strftime ("% V")
Einar

77

date.isocalendar()Cevap olacağına inanıyorum . Bu makalede , ISO 8601 Takvim'in arkasındaki matematik açıklanmaktadır. Python belgelerinin datetime sayfasının date.isocalendar () bölümüne bakın .

>>> dt = datetime.date(2010, 6, 16) 
>>> wk = dt.isocalendar()[1]
24

.isocalendar (), (yıl, hafta sayı, hafta gün) ile 3-demet döndürür. dt.isocalendar()[0]yılı dt.isocalendar()[1]döndürür, hafta sayısını dt.isocalendar()[2]döndürür, hafta gününü döndürür. Olabildiğince basit.


4
ISO haftalarının sezgisel olmayan özelliğini açıklayan bağlantı için +1.
Mark Ransom

27

İşte başka bir seçenek:

import time
from time import gmtime, strftime
d = time.strptime("16 Jun 2010", "%d %b %Y")
print(strftime("%U", d))

hangi baskı 24.

Bkz. Http://docs.python.org/library/datetime.html#strftime-and-strptime-behavior


9
veya haftalarınız Pazartesi günleri başlarsa% W.
ZeWaren

1
Bu yaklaşım, dize olarak gelen bir tarihi bölmek veya dönüştürmek istemediğiniz durumlarda daha iyidir ... dizeyi strptime'da olduğu gibi dize biçiminde geçirin ve biçimi ikinci argümanda belirtin. Güzel çözüm. Unutmayın: Hafta Pazartesi günleri başlarsa% W.
TheCuriousOne

22

Başkaları tarafından önerilen ISO haftası iyi bir hafta ancak ihtiyaçlarınızı karşılamayabilir. Her hafta, Pazartesi başında başlar ve yılın başında ve sonunda bazı ilginç anormalliklere yol açar.

Haftanın gününe bakılmaksızın, 1. haftanın her zaman 1 Ocak - 7 Ocak olduğunu belirten bir tanım kullanmayı tercih ederseniz, şöyle bir türev kullanın:

>>> testdate=datetime.datetime(2010,6,16)
>>> print(((testdate - datetime.datetime(testdate.year,1,1)).days // 7) + 1)
24

3
İsocalendar'ın yılın başında ve sonunda "bazı ilginç anormalliklere" sahip olduğunu söylemek biraz yetersiz kalıyor gibi görünüyor. isocalendar'ın sonuçları, 29 Aralık 2014, 00:00:00 gibi bazı tarihler için (ISO belirtimi altında gerçekten yanlış olmasa bile) çok yanıltıcıdır; bu, isocalendar'a göre 2015 ve hafta 1 hafta değerine sahiptir. aşağıdaki girişim).
Kevin

3
@Kevin, yanlış değil, sadece tanımları sizinkiyle uyuşmuyor. ISO iki şeye karar verdi: Birincisi Pazartesi'den Pazar'a tüm hafta aynı yıl, ikincisi günlerin çoğunu içeren yılın atanmış olması. Bu, yılın başlangıcında ve sonunda bitişik yıla geçen haftanın günlerine yol açar.
Mark Ransom

6
Kabul. Ancak çoğu insanın tanımına göre, 29 Aralık 2014 kesinlikle 2015 yılının 1. haftası olmayacak. Sadece bu olası karışıklık kaynağına dikkat çekmek istedim.
Kevin

Tam da aradığım şey buydu. Bunun nasıl yapılacağı hakkında değil, ISO ile ilgili bilgiler ve Pazartesi gününden başlayarak.
Amit Amola

19

Genellikle geçerli hafta numarasını almak için (Pazar gününden başlar):

from datetime import *
today = datetime.today()
print today.strftime("%U")

4
Strftime ('% U') dokümantasyonundan: "Ondalık sayı olarak yılın hafta numarası (haftanın ilk günü olarak Pazar). İlk Pazardan önceki yeni yılda tüm günler dikkate alınır 0. hafta olacak. "
Dolan Antenucci

14

Yılın anlık haftasının tamsayı değeri için şunu deneyin:

import datetime
datetime.datetime.utcnow().isocalendar()[1]

10

Hafta numaralandırması için birçok sistem vardır . Kod örnekleriyle birlikte verilen en yaygın sistemler şunlardır:

  • ISO : İlk hafta Pazartesi ile başlar ve 4 Ocak'ı içermelidir. ISO takvimi zaten Python'da uygulanmıştır:

    >>> from datetime import date
    >>> date(2014, 12, 29).isocalendar()[:2]
    (2015, 1)
  • Kuzey Amerika : İlk hafta Pazar ile başlar ve 1 Ocak'ı içermelidir. Aşağıdaki kod, Python'un Kuzey Amerika sistemi için ISO takvim uygulamasının değiştirilmiş sürümüdür:

    from datetime import date
    
    def week_from_date(date_object):
        date_ordinal = date_object.toordinal()
        year = date_object.year
        week = ((date_ordinal - _week1_start_ordinal(year)) // 7) + 1
        if week >= 52:
            if date_ordinal >= _week1_start_ordinal(year + 1):
                year += 1
                week = 1
        return year, week
    
    def _week1_start_ordinal(year):
        jan1 = date(year, 1, 1)
        jan1_ordinal = jan1.toordinal()
        jan1_weekday = jan1.weekday()
        week1_start_ordinal = jan1_ordinal - ((jan1_weekday + 1) % 7)
        return week1_start_ordinal
    >>> from datetime import date
    >>> week_from_date(date(2014, 12, 29))
    (2015, 1)
  • MMWR (CDC) : İlk hafta Pazar ile başlar ve 4 Ocak'ı içermelidir. Özellikle bu numaralandırma sistemi için epiweeks paketini oluşturdum (ISO sistemi için de destek var). İşte bir örnek:
    >>> from datetime import date
    >>> from epiweeks import Week
    >>> Week.fromdate(date(2014, 12, 29))
    (2014, 53)

8

Tahtada yalnızca isocalendar hafta numarasını kullanıyorsanız aşağıdakiler yeterli olmalıdır:

import datetime
week = date(year=2014, month=1, day=1).isocalendar()[1]

Bu, hafta numaramız için isocalendar tarafından döndürülen grubun ikinci üyesini alır.

Ancak, Gregoryen takvimi ile ilgilenen tarih işlevlerini kullanacaksanız, isocalendar tek başına çalışmaz! Aşağıdaki örneği alın:

import datetime
date = datetime.datetime.strptime("2014-1-1", "%Y-%W-%w")
week = date.isocalendar()[1]

Buradaki dize, 2014'teki ilk haftanın Pazartesi gününü tarihimiz olarak döndürmeyi söylüyor. Burada hafta numarasını almak için isocalendar kullandığımızda, aynı hafta numarasını geri almayı bekleriz, ama almayız. Bunun yerine bir hafta 2 alırız. Neden?

Gregoryen takvimindeki 1. Hafta Pazartesi içeren ilk haftadır. İzocalendar'daki 1. Hafta, Perşembe gününü içeren ilk haftadır. 2014'ün başındaki kısmi haftada bir Perşembe var, bu yüzden bu isocalendar tarafından 1. datehaftada ve 2. haftada.

Gregoryen haftasını almak istiyorsak, isocalendar'dan Gregoryen'e çevirmemiz gerekecek. İşte hile yapan basit bir işlev.

import datetime

def gregorian_week(date):
    # The isocalendar week for this date
    iso_week = date.isocalendar()[1]

    # The baseline Gregorian date for the beginning of our date's year
    base_greg = datetime.datetime.strptime('%d-1-1' % date.year, "%Y-%W-%w")

    # If the isocalendar week for this date is not 1, we need to 
    # decrement the iso_week by 1 to get the Gregorian week number
    return iso_week if base_greg.isocalendar()[1] == 1 else iso_week - 1

6

% W yönergesini aşağıdaki gibi deneyebilirsiniz:

d = datetime.datetime.strptime('2016-06-16','%Y-%m-%d')
print(datetime.datetime.strftime(d,'%W'))

'% W': Ondalık sayı olarak yılın hafta numarası (haftanın ilk günü olarak Pazartesi). İlk Pazartesi'den önceki yeni yılda tüm günler 0. haftada kabul edilir (00, 01, ..., 53)


2

isocalendar () bazı tarihler için yanlış yıl ve hafta sayısı değerlerini döndürür:

Python 2.7.3 (default, Feb 27 2014, 19:58:35) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import datetime as dt
>>> myDateTime = dt.datetime.strptime("20141229T000000.000Z",'%Y%m%dT%H%M%S.%fZ')
>>> yr,weekNumber,weekDay = myDateTime.isocalendar()
>>> print "Year is " + str(yr) + ", weekNumber is " + str(weekNumber)
Year is 2015, weekNumber is 1

Mark Ransom'un yaklaşımı ile karşılaştırın:

>>> yr = myDateTime.year
>>> weekNumber = ((myDateTime - dt.datetime(yr,1,1)).days/7) + 1
>>> print "Year is " + str(yr) + ", weekNumber is " + str(weekNumber)
Year is 2014, weekNumber is 52

3
İso8601 takvimi (örneğin, personel.science.uu.nl/~gent0113/calendar/isocalendar.htm ) ile ilgili bazı bağlantılara baktığımda, isocalendar () tarafından döndürülen yıl ve hafta sayısı değerlerinin "yanlış" olmadığını görüyorum. Örneğin ISO8601 uyarınca, 2004 yılı 29 Aralık 2003'te başladı. Bu nedenle, isocalendar (), 2015 Aralık 2014 için bir yılı iade etmede doğru olabilir, ancak birçok insanın amacı için bu oldukça yanıltıcı olacaktır. .
Kevin

2

Tartışmayı iki adımda özetliyorum:

  1. Ham biçimi bir datetimenesneye dönüştürün .
  2. Hafta sayısını hesaplamak için bir datetimenesnenin veya nesnenin işlevini kullanın date.

Isınmak

`` `Piton

from datetime import datetime, date, time
d = date(2005, 7, 14)
t = time(12, 30)
dt = datetime.combine(d, t)
print(dt)

`

1. adım

Bir datetimenesneyi manuel olarak oluşturmak için datetime.datetime(2017,5,3)veya öğesini kullanabiliriz datetime.datetime.now().

Ama gerçekte, genellikle mevcut bir dizeyi ayrıştırmamız gerekir. formatı belirtmeniz gereken strptimefonksiyonlar kullanabiliriz datetime.strptime('2017-5-3','%Y-%m-%d'). Farklı format kodlarının detaylarını resmi belgelerde bulabilirsiniz .

Alternatif olarak, daha uygun bir yol da dateparse modülünü kullanmaktır . Örnekler dateparser.parse('16 Jun 2010'), dateparser.parse('12/2/12')veyadateparser.parse('2017-5-3')

Yukarıdaki iki yaklaşım bir datetimenesne döndürecektir .

2. adım

datetimeAramak için elde edilen nesneyi kullanın strptime(format). Örneğin,

`` `Piton

dt = datetime.strptime('2017-01-1','%Y-%m-%d') # return a datetime object. This day is Sunday
print(dt.strftime("%W")) # '00' Monday as the 1st day of the week. All days in a new year preceding the 1st Monday are considered to be in week 0.
print(dt.strftime("%U")) # '01' Sunday as the 1st day of the week. All days in a new year preceding the 1st Sunday are considered to be in week 0.
print(dt.strftime("%V")) # '52' Monday as the 1st day of the week. Week 01 is the week containing Jan 4.

`

Hangi formatın kullanılacağına karar vermek çok zor. Daha iyi bir yol, bir datenesneyi çağırmaktır isocalendar(). Örneğin,

`` `Piton

dt = datetime.strptime('2017-01-1','%Y-%m-%d') # return a datetime object
d = dt.date() # convert to a date object. equivalent to d = date(2017,1,1), but date.strptime() don't have the parse function
year, week, weekday = d.isocalendar() 
print(year, week, weekday) # (2016,52,7) in the ISO standard

`

Gerçekte, date.isocalendar()özellikle "Noel-Yeni Yıl" alışveriş sezonunda haftalık bir rapor hazırlamak için kullanmanız daha olası olacaktır .


0
userInput = input ("Please enter project deadline date (dd/mm/yyyy/): ")

import datetime

currentDate = datetime.datetime.today()

testVar = datetime.datetime.strptime(userInput ,"%d/%b/%Y").date()

remainDays = testVar - currentDate.date()

remainWeeks = (remainDays.days / 7.0) + 1


print ("Please pay attention for deadline of project X in days and weeks are  : " ,(remainDays) , "and" ,(remainWeeks) , "Weeks ,\nSo  hurryup.............!!!") 

-1

Bir sürü cevap verildi, ancak bunlara eklemek istiyorum.

Bir yıl / hafta stili olarak görüntülenmesi için haftaya ihtiyacınız varsa (ör. 1953 - 2019'un 53. haftası, 2001 - 2020'nin 1. haftası vb.), Bunu yapabilirsiniz:

import datetime

year = datetime.datetime.now()
week_num = datetime.date(year.year, year.month, year.day).strftime("%V")
long_week_num = str(year.year)[0:2] + str(week_num)

İçinde bulunulan yıl ve hafta sürecek ve bu yazı yazılırsa long_week_num şöyle olacaktır:

>>> 2006

Neden date()sıfırdan bir tane oluşturmalı ? datetime.datetime()örneklerin .date()o iş için bir yöntemi vardır.
Martijn Pieters

Ancak, daha endişe verici bir şekilde, cevabınız cari yıl değil, yüzyılı seçiyor . Ve hafta numarası için dize biçimlendirmesi kullanacaksanız, neden yılı dahil etmek için bunu kullanmıyorsunuz?
Martijn Pieters
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.