Pythonで週番号を取得する方法は?


337

Pythonを使用して、6月16日(wk24)の現在の年が何週目かを調べる方法は?


1
@Donal:1つは6月16日、もう1つは6月26
。– interjay

5
1週目を定義します。isocalendar()はそれを行う唯一の方法ではありません。
Mark Tolonen、2010

3
の出力はとstrftime("%U", d)は異なる場合があることに注意してくださいisocalendar()。たとえば、年を2004年に変更すると、24週目はを使用してstrftime()、25週目はを使用して取得されますisocalendar()
moooeeeep

回答:


408

datetime.dateには、isocalendar()暦週を含むタプルを返すメソッドがあります。

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

datetime.date.isocalendar()は、指定された日付インスタンスのそれぞれの順序で年、週番号、曜日を含むタプルを返すインスタンスメソッドです。


7
' [1]' を説明したり、情報を探す場所を指定したりすると、役に立ちます。
ジョナサンレフラー

5
strftimeを使用して週番号を抽出するのが最も簡単だと思います。ベストインポート日時time = datetime.now()week = today.strftime( "%W")
bipsa

7
これは少し遅れました。しかし、私のマシンでdate(2010, 1, 1).isocalendar()[1]は、が返されます53。ドキュメントから:「ISOの2004年の最初の週はそうすることを、2004年1月4日(日曜日 ) に2003年12月29日(月曜日 ) と端に始まるので、例えば、2004年には、木曜日に始まるdate(2003, 12, 29).isocalendar() == (2004, 1, 1)date(2004, 1, 4).isocalendar() == (2004, 1, 7)。」
jclancy 2015

17
isocalendar()素晴らしいですが、それがあなたが望むものであることを確認してください。今日は完璧な例です。2016/01/01はに等しい(2015, 53, 5)now.strftime("%W")そして、now.strftime("%U")等しい00たかっれているものが多いです。 STRFTIMEの例
DaveL17

いいもの、私はそれが役立つだろうと思う今日を追加しました。それは私が求めていたものでした:D
Vitaliy Terziev

123

日付から直接、週番号を文字列として取得できます。

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

また、次のstrftimeパラメータを変更して、年の週番号のさまざまな「タイプ」を取得できます。

%U- その年の週番号(日は週の最初の日)ゼロが埋め込まれた10進数としての、。新年の最初の日曜日の前のすべての日は週に0例であると考えられている:00、01、...、53

%W -その年の週番号(-10進数として週の最初の日が月曜日)。最初の月曜日の前の新しい年のすべての日は週に0例であると考えられている:00、01、...、53

[...]

Python 3.6で追加され、一部のディストリビューションのPython 2.7にバックポートされました。れました)便宜上、C89標準では不要ないくつかの追加のディレクティブが含まれています。これらのパラメーターはすべてISO 8601の日付値に対応しています。これらをで使用すると、すべてのプラットフォームで使用できない場合があります。strftime()メソッドで。

[...]

%V- ISO 8601の週の週の最初の日と月曜日と10進数。01週は、1月4日を含む週です。例:01、02、…、53

から: datetime —基本的な日付と時刻のタイプ— Python 3.7.3ドキュメント

私はそれをここから知りました。Python 2.7.6ではうまくいきました


あなたは何を引用していますか、いくつかのLinuxマニュアル?Python 2.7.5と3.3.2はInvalid format stringこのパターンに従っています。彼らのドキュメントは%Vどちらも言及していません。
Vsevolod Golovanov 2015年

3
申し訳ありませんが、ここには記載していません。Python 2.7.6で動作しました。
jotacor 2015年

2
正解です。日付の「<YEAR>-<ISOWEEK>」表現に関心がある場合は、の%G-%V代わりにを使用してください%Y-%V%GISOに相当する年です%Y
KenHBS

これを機能させるには、datetime.datetime(2010、6、16).strftime( "%V")またはこのdatetime.datetime(2010、6、16).date()。strftimeのように記述する必要がありました。 ( "%V")
Einar

77

date.isocalendar()答えになると思います。この記事では、ISO 8601カレンダーの背後にある数学について説明します。Pythonドキュメントのdatetimeページのdate.isocalendar()の部分を確認してください。

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

.isocalendar()は、(年、週番号、週日)の3タプルを返します。dt.isocalendar()[0]年をdt.isocalendar()[1]返し、週番号をdt.isocalendar()[2]返し、曜日を返します。できる限りシンプル。


4
ISO週間の非直感的な性質を説明するリンクの+1。
Mark Ransom

27

別のオプションを次に示します。

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

印刷する 24ます。

参照:http : //docs.python.org/library/datetime.html#strftime-and-strptime-behavior


9
週が月曜日に始まる場合は%W。
ZeWaren 2014

1
このアプローチは、文字列として提供される日付を分割または変換したくない場合に適しています... strptimeの文字列をそのまま文字列形式で渡して、2番目の引数で形式を指定します。良い解決策。覚えておいてください:週が月曜日に始まる場合は%W。
TheCuriousOne 2017

22

他の人から提案されたISO週間は良いものですが、ニーズに合わないかもしれません。それは、毎週が月曜日から始まることを前提としています。これにより、年の初めと終わりにいくつかの興味深い異常が生じます。

週に関係なく、週1が常に1月1日から1月7日であるという定義を使用する場合は、次のような派生を使用します。

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

3
イソカレンダが年の初めと終わりに「いくつかの興味深い異常」を持っていると言うことは少し控えめなようです。isocalendarの結果は、2014年12月29日00:00:00のようないくつかの日時値に対して非常に誤解を招く可能性があります(ISO仕様では実際には正しくない場合でも)。以下の私のエントリ)。
ケビン

3
@ケビン、それは間違いではありません、それは彼らの定義があなたのものと一致しないというだけです。ISOは2つのことを決定しました。1つ目は、月曜日から日曜日までの週全体が同じ年であること、2つ目は、ほとんどの日が含まれる年が割り当てられることです。これにより、翌年の初めと終わりの曜日が隣接する年に移動します。
Mark Ransom 2014

6
同意した。しかし、ほとんどの人の定義では、2014年12月29日は2015年の第1週ではないことは間違いありません。この潜在的な混乱の原因に注意を向けたかっただけです。
ケビン

これはまさに私が探していたものです。これを行う方法についてではなく、ISOに関する情報と月曜日のものから始めます。
アミットアモラ

19

通常、現在の週番号を取得するには(日曜日から開始):

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

4
strftime( '%U')のドキュメントから:「10進数としての年の週数(週の最初の日は日曜日)[00,53]。最初の日曜日の前の新年のすべての日が考慮されます第0週になる予定です。」
Dolan Antenucci、2011

14

年の瞬間の週の整数値については、次のことを試してください。

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

10

週番号付けに多くのシステムがあります。以下は、単純にコード例を示した最も一般的なシステムです。

  • ISO:最初の週は月曜日から始まり、1月4日が含まれている必要があります。ISOカレンダーはすでにPythonに実装されています。

    >>> from datetime import date
    >>> date(2014, 12, 29).isocalendar()[:2]
    (2015, 1)
  • 北米:最初の週は日曜日から始まり、1月1日が含まれている必要があります。次のコードは、北米のシステム用に変更したPythonのISOカレンダー実装です。

    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):最初の週は日曜日から始まり、1月4日が含まれている必要があります。このナンバリングシステム用に特別にepiweeksパッケージを作成しました(ISOシステムもサポートしています)。次に例を示します。
    >>> from datetime import date
    >>> from epiweeks import Week
    >>> Week.fromdate(date(2014, 12, 29))
    (2014, 53)

8

全体でisocalendarの週番号のみを使用している場合は、以下で十分です。

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

これは、私たちの週番号に対してisocalendarによって返されたタプルの2番目のメンバーを取得します。

ただし、グレゴリオ暦を扱う日付関数を使用する場合は、イソカレンダだけでは機能しません。次の例を見てください。

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

ここの文字列は、2014年の最初の週の月曜日を日付として返すことを示しています。ここでisocalendarを使用して週番号を取得する場合、同じ週番号を取得すると予想されますが、そうではありません。代わりに、週番号は2になります。なぜですか。

グレゴリオ暦の第1週は、月曜日を含む最初の週です。イソカレンダの第1週は、木曜日を含む最初の週です。2014年の初めの部分的な週には木曜日が含まれるため、これはイソカレンダによる第1週であり、date第2週になります。

グレゴリオ暦の週を取得したい場合は、イソカレンダからグレゴリオ暦に変換する必要があります。これは、トリックを実行する単純な関数です。

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ディレクティブを試すことができます。

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

'%W':10進数としての年間通算週番号(月曜日を週の最初の日とする)。最初の月曜日に先立つ新年のすべての日は、0週目と見なされます。(00、01、...、53)


2

isocalendar()は、一部の日付に対して誤った年と週番号の値を返します。

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のアプローチと比較してください。

>>> 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
iso8601カレンダーに関するいくつかのリンク(たとえば、staff.science.uu.nl /~gent0113/calendar/ isocalendar.htm)を見ると、isocalendar()によって返される年と週番号の値は、そのように「正しくない」ことがわかります。たとえば、ISO8601では、2004年は2003年12月29日に始まりました。そのため、isocalendar()は2015年をDec.29 2014に返すのに正しいかもしれませんが、多くの人の目的のために、これはかなり誤解を招くでしょう。 。
ケビン

2

議論を2つのステップに要約します。

  1. 未加工の形式を datetimeオブジェクトにます。
  2. datetimeオブジェクトまたはオブジェクトの関数を使用してdate、週番号を計算します。

準備し始める

`` `パイソン

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

「」

第一歩

datetimeオブジェクトを手動で生成するには、datetime.datetime(2017,5,3)またはdatetime.datetime.now()

しかし実際には、通常、既存の文字列を解析する必要があります。形式を指定する必要があるstrptime関数などを使用できdatetime.strptime('2017-5-3','%Y-%m-%d')ます。さまざまなフォーマットコードの詳細については、公式ドキュメントをご覧ください

または、より便利な方法は、dateparseモジュールを使用することです。例はdateparser.parse('16 Jun 2010')dateparser.parse('12/2/12')またはdateparser.parse('2017-5-3')

上記の2つのアプローチは、 datetimeオブジェクトます。

第2ステップ

取得したdatetimeオブジェクトを使用し て呼び出すstrptime(format)。例えば、

`` `パイソン

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.

「」

使用するフォーマットを決定するのは非常に難しいです。より良い方法は、dateオブジェクトを呼び出すことですisocalendar()です。例えば、

`` `パイソン

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

「」

実際にはdate.isocalendar()、特に「クリスマス-ニューイヤー」のショッピングシーズンでは、週次レポートの作成に使用する可能性が高くなります。


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

多くの回答が与えられましたが、idはそれらに追加したいです。

年/週スタイルで表示する週が必要な場合(例:1953-2019の週53、2001-2020の週1など)、これを行うことができます:

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)

それは現在の年と週を取り、これを書いている日のlong_week_numは次のようになります:

>>> 2006

date()ゼロから作成する理由 datetime.datetime()インスタンスには.date()そのジョブのメソッドがあります。
Martijn Pieters

ただし、もっと心配なのは、答えが現在の年ではなく世紀を選ぶということです。そして、週番号に文字列フォーマットを使用する場合は、それを使用して年を含めるのはなぜですか?
Martijn Pieters
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.