2010-04-08 246 views
203

¿Cómo saber qué número de semana es el año actual el 16 de junio (wk24) con Python?¿Cómo obtener el número de semana en Python?

+1

@Donal: Se busca el 16 de Junio ​​el otro en el 26 de junio – interjay

+4

Definir la semana 1. isocalendar() no es la única manera de hacerlo. –

+1

Tenga en cuenta que la salida de 'strftime ("% U ", d)' puede diferir de la 'isocalendar()'. Por ejemplo, si cambia el año 2004, obtendrá la semana 24 usando 'strftime()' y la semana 25 usando 'isocalendar()'. – moooeeeep

Respuesta

254

datetime.date tiene un método isocalendar(), que devuelve una tupla que contiene la semana del calendario:

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

datetime.date.isocalendar() es una instancia método de devolver una tupla que contiene años, WeekNumber y día de la semana en orden respectivo para la instancia de fecha dada.

+5

Ayudaría si explicara el '' [1] '', o le diera un puntero a donde buscar la información. –

+2

Supongo que lo más fácil es extraer el número de la semana usando strftime, mejor import datetime today = datetime.now() week = today.strftime ("% W") – bipsa

+6

Esto es un poco tarde. Pero en mi máquina, 'date (2010, 1, 1) .isocalendar() [1]' devuelve '53'.De los documentos: "Por ejemplo, 2004 comienza un jueves, por lo que la primera semana del año ISO 2004 comienza el lunes 29 de diciembre de 2003 y finaliza el domingo 4 de enero de 2004, por lo que' fecha (2003, 12, 29) .isocalendar() == (2004, 1, 1) 'y' fecha (2004, 1, 4) .isocalendar() == (2004, 1, 7) '." – jclancy

60

Creo que date.isocalendar() va a ser la respuesta. This article explica las matemáticas detrás del calendario ISO 8601. Consulte la parte de date.isocalendar() del datetime page de la documentación de Python.

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

.isocalendar() devuelve un 3-tupla (en qué año, sem num, día de semana). dt.isocalendar()[0] devuelve el año, dt.isocalendar()[1] devuelve el número de semana, dt.isocalendar()[2] devuelve el día de la semana. Simple como puede ser.

+2

+1 para el enlace que explica la naturaleza no intuitiva de las semanas ISO. –

25

Aquí hay otra opción:

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

que imprime 24.

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

+1

+1 para obtener más información en la URL –

+7

o% W si las semanas comienzan los lunes. – ZeWaren

+0

Este enfoque es mejor en los casos en que no desea dividir o convertir una fecha que viene como una cadena ... simplemente pase la cadena en strptime en formato de cadena como está y especifique el formato en el segundo argumento. Buena solución. Recuerde:% W si la semana comienza los lunes. – MANU

13

La semana ISO sugerido por otros es una buena, pero puede que no se ajuste a sus necesidades. Se supone que cada semana comienza con un lunes, lo que conduce a algunas anomalías interesantes al principio y al final del año.

Si prefiere utilizar una definición que dice la semana 1 es siempre 1 de enero hasta el 7 de enero independientemente del día de la semana, utilizar una derivación de esta manera:

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

Decir que isocalendar tiene "algunas anomalías interesantes" en el principio y fin de año parece ser un poco insuficiente. Los resultados de isocalendar son muy engañosos (incluso si no son incorrectos según la especificación ISO) para algunos valores de fecha y hora, como el 29 de diciembre de 2014, 00:00:00, que según isocalendar tiene un valor anual de 2015 y una semanaNúmero 1 (ver mi entrada a continuación). – Kevin

+3

@Kevin, no está mal, es solo que sus definiciones no coinciden con las tuyas. ISO decidió dos cosas: primero que toda la semana de lunes a domingo sería en el mismo año, segundo que el año que contiene la mayoría de los días sería el asignado. Esto lleva a días de la semana al comienzo y al final del año que avanzan al año siguiente. –

+4

De acuerdo. Pero según la definición de la mayoría de la gente, el 29 de diciembre de 2014 definitivamente no será la semana 1 del año 2015. Solo quería llamar la atención sobre esta posible fuente de confusión. – Kevin

15

general para obtener la corriente número de la semana (aperturas de domingo):

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

De la documentación de strftime ('% U'): "Número de semana del año (domingo como el primer día de la semana) como un número decimal [00,53]. Todos los días del año nuevo anterior al primer domingo son se considera que está en la semana 0 ". –

2

isocalendar() devuelve año y WeekNumber valores incorrectos para algunas fechas:

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 

Comparar con enfoque de 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 
+2

Al mirar algunos enlaces sobre el calendario iso8601 (p. Ej., Http://www.staff.science.uu.nl/~gent0113/calendar/isocalendar.htm), veo que los valores de year y weeknumber devueltos por isocalendar() son no es "incorrecto" como tal. Bajo ISO8601, por ejemplo, el año 2004 comenzó el 29 de diciembre de 2003. Entonces isocalendar() puede ser correcto al devolver un año de 2015 para el 29 de diciembre de 2014, pero para los propósitos de muchas personas, esto va a ser bastante engañoso. . – Kevin

45

que pueda obtener el número de la semana directamente de fecha y hora como cadena.

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

También usted puede conseguir "tipos" diferentes del número de semana del año cambiando el parámetro strftime para:

% T - número de semana del año en curso, comenzando con el primer domingo como el primer día de la primera semana.

% V - El número de la semana ISO 8601 del año actual (01 a 53), donde semana 1 es la primera semana que tiene al menos 4 días en el año actual, y con el lunes como el primer día de la semana.

% W - número de semana del año actual, comenzando con el primer lunes como el primer día de la primera semana.

Lo tengo de here. Se trabajó para mí en Python 2.7.6

+0

¿Qué está citando, algún manual de Linux? Python 2.7.5 y 3.3.2 dicen 'cadena de formato inválida' para este patrón. Sus documentos tampoco mencionan '% V'. –

+2

Lo siento, no lo mencioné, lo recibí de [aquí] (http://www.tutorialspoint.com/python/time_strftime.htm). Me funcionó en Python 2.7.6. – jotacor

12

Para el valor entero de la semana instantánea del año intento:

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

Si sólo está utilizando el número de la semana isocalendar en todos los ámbitos de la siguiente debería ser suficiente :

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

Esto recupera el segundo miembro de la tupla devuelta por isocalendar por nuestro número de semanas.

Sin embargo, si va a utilizar las funciones de fecha que se tratan en el calendario gregoriano, isocalendar solo no funcionará. Tomemos el siguiente ejemplo:

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

La cadena dice aquí para volver el lunes de la primera semana de 2014, como nuestra fecha. Cuando usemos isocalendar para recuperar el número de la semana aquí, esperaríamos recuperar el mismo número de semana, pero no lo hacemos. En cambio, obtenemos un número de semana de 2. ¿Por qué?

La semana 1 en el calendario gregoriano es la primera semana que contiene un lunes. La semana 1 en el isocalendar es la primera semana que contiene un jueves. La semana parcial a principios de 2014 contiene un jueves, por lo que esta es la semana 1 por el isocalendar y hace date semana 2.

Si queremos obtener la semana gregoriana, tendremos que convertir del isocalendar al Gregoriano. Aquí hay una función simple que hace el truco.

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 
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.............!!!") 
6

Usted puede intentar% directiva W de la siguiente manera:

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

'% W': Número de la semana del año (lunes como el primer día de la semana) como un número decimal . Todos los días en un nuevo año anterior al primer lunes se consideran en la semana 0. (00, 01, ..., 53)

2

resumo la discusión de dos pasos:

  1. convertir el crudo formatear a un objeto datetime.
  2. Utilice la función de un objeto datetime o un objeto date para calcular el número de semana.

Calentar

`` `python

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

` ``

primera etapa

Para generar manualmente un objeto datetime, podemos utilizar datetime.datetime(2017,5,3) o datetime.datetime.now().

Pero en realidad, normalmente necesitamos analizar una cadena existente. podemos usar la función strptime, como datetime.strptime('2017-5-3','%Y-%m-%d') en la que debe especificar el formato. El detalle del código de formato diferente se puede encontrar en el official documentation.

Alternativamente, una forma más conveniente es usar el módulo dateparse. Los ejemplos son dateparser.parse('16 Jun 2010'), dateparser.parse('12/2/12') o dateparser.parse('2017-5-3')

Los dos enfoques anteriores devolverán un objeto datetime.

segundo paso

Usar la datetime objeto obtenido a llamar strptime(format). Por ejemplo,

`` `python

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. 

` ``

Es muy difícil decidir qué formato utilizar. Una mejor manera es obtener un objeto date para llamar al isocalendar(). Por ejemplo,

`` `python

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 

` ``

En realidad, usted será más probable que utilice date.isocalendar() para preparar un informe semanal, especialmente en la "Navidad-Año Nuevo "temporada de compras".

2

Para la fecha de hoy:

import datetime as date 
weeknumber = date.today().isocalendar()[1] 
Cuestiones relacionadas