La méthode Python datetime.isocalendar()
renvoie un n-uplet (ISO_year, ISO_week_number, ISO_weekday)
pour l'objet datetime
donné. Y a-t-il une fonction inverse correspondante? Si non, y a-t-il un moyen facile de calculer une date donnée par année, numéro de semaine et jour de la semaine?Quelle est la meilleure façon de trouver l'inverse de datetime.isocalendar()?
Répondre
J'ai récemment pour résoudre moi-même ce problème, et est venu avec cette solution:
import datetime
def iso_year_start(iso_year):
"The gregorian calendar date of the first day of the given ISO year"
fourth_jan = datetime.date(iso_year, 1, 4)
delta = datetime.timedelta(fourth_jan.isoweekday()-1)
return fourth_jan - delta
def iso_to_gregorian(iso_year, iso_week, iso_day):
"Gregorian calendar date for the given ISO year, week and day"
year_start = iso_year_start(iso_year)
return year_start + datetime.timedelta(days=iso_day-1, weeks=iso_week-1)
Quelques cas de test:
>>> iso = datetime.date(2005, 1, 1).isocalendar()
>>> iso
(2004, 53, 6)
>>> iso_to_gregorian(*iso)
datetime.date(2005, 1, 1)
>>> iso = datetime.date(2010, 1, 4).isocalendar()
>>> iso
(2010, 1, 1)
>>> iso_to_gregorian(*iso)
datetime.date(2010, 1, 4)
>>> iso = datetime.date(2010, 1, 3).isocalendar()
>>> iso
(2009, 53, 7)
>>> iso_to_gregorian(*iso)
datetime.date(2010, 1, 3)
EDIT: ignorez ceci, les cas de bord sont une douleur. Aller avec la solution de Ben.
Ok, regardant de plus près je remarqué que strptime
a %W
et %w
paramètres, donc les travaux suivants:
def fromisocalendar(y,w,d):
return datetime.strptime("%04dW%02d-%d"%(y,w-1,d), "%YW%W-%w")
Quelques gotchas: Le numéro de la semaine ISO commence à 1
, tandis que %W
commence à 0
. Le jour de la semaine ISO commence à 1
(lundi), qui est le même que celui %w
, donc dimanche devrait probablement être 0
, pas 7
...
Quelle version utilisez-vous?, Je testais sur 2.4.2 et ne fonctionnait pas pour moi, trouvé http://bugs.python.org/issue1045381 mais dit que c'est fait sur 2.3 –
J'utilise 2.5. 2,% W fonctionne, pas sûr de% U. – Tom
Cela ressemble à ce que vous avez répondu. Pourquoi ne pas accepter votre réponse? –
Notez que% W est la semaine # (0-53) qui N'EST PAS LA MÊME que la semaine ISO (1-53). Il y aura des cas limites où% W ne fonctionnera pas.
import datetime
def iso_to_gregorian(iso_year, iso_week, iso_day):
"Gregorian calendar date for the given ISO year, week and day"
fourth_jan = datetime.date(iso_year, 1, 4)
_, fourth_jan_week, fourth_jan_day = fourth_jan.isocalendar()
return fourth_jan + datetime.timedelta(days=iso_day-fourth_jan_day, weeks=iso_week-fourth_jan_week)
Cela a été adapté de @ BenJames est très bien répondre. Vous n'avez pas besoin de connaître le premier jour de l'année. Il suffit de connaître un exemple de date qui correspond certainement à la même année ISO, ainsi que la semaine et le jour du calendrier ISO de cette date.
Le 4 janvier est simplement un exemple, car, comme Ben l'a souligné, le 4 janvier appartient toujours à la même année ISO et à l'année grégorienne, et c'est le premier jour de l'année à le faire. Comme les semaines sont toutes de la même longueur, vous pouvez simplement soustraire les jours et les semaines entre l'ISO de la date que vous voulez, et l'ISO de la date que vous connaissez dans les deux formes, et ajouter ce nombre de jours et semaines. (Peu importe si ces chiffres sont positifs ou négatifs, vous pouvez donc choisir un autre « jour fixe », comme le 28 décembre.)
Modifier
Je corrigeais cela parce que, comme cela a été souligné par @ obligeamment JoSo, le premier jour de l'année grégorienne qui appartient également à l'année ISO est le 4 janvier et non le 5 janvier. Comme l'indique l'explication, peu importe la date choisie comme point de référence, mais choisir le 4 janvier rend ce choix moins «magique».
Pourriez-vous s'il vous plaît me dire, si cela fonctionne vraiment sans faille dans chaque situation? – Geeocode
@GeorgeSolymosi J'ai utilisé la bibliothèque de tests d'hypothèses Python pour rechercher des objets 'datetime' valides pour lesquels cette fonction n'est pas l'inverse de' isocalendar'. Il n'a pas trouvé de/See https://github.com/jwg4/qual/blob/master/qual/tests/test_iso.py Ce n'est pas une garantie bien sûr - je serais intéressé à entendre parler de bugs. Si vous travaillez selon la logique du code, vous pourriez ou non être convaincu qu'il fait la bonne chose. – jwg
c'est plus compliqué que nécessaire. Regardez la réponse de Ben ou ou sur Wikipedia. Le 4 janvier fera également l'affaire et se situe toujours dans la première semaine ISO de son année ISO. –
À partir de Python 3.6, datetime.strptime()
soutiendra les %G
, %V
et %u
directives, de sorte que vous pouvez simplement faire datetime.strptime('2015 1 2', '%G %V %u').date()
. Voir: https://hg.python.org/cpython/rev/acdebfbfbdcf
À partir de Python 3.6 (actuellement in development), vous pouvez utiliser les nouveaux %G
, %u
et %V
directives.Voir issue 12006 et updated documentation:
%G
ISO 8601 année avec le siècle représentant l'année qui contient la plus grande partie de la semaine ISO (%V
).
%u
ISO 8601 jour en nombre décimal où 1 est lundi.
%V
ISO 8601 semaine sous forme de nombre décimal avec lundi comme premier jour de la semaine. Semaine 01 est la semaine contenant Jan 4.
d'une chaîne à l'année, Semaine n ° et le numéro de la semaine, il est facile d'analyser les sortir à une date avec:
from datetime import date
date.strptime('2002 01 1', '%G %V %u')
ou en fonction de entrées entières:
from datetime import date
def date_from_isoweek(iso_year, iso_weeknumber, iso_weekday):
return date.strptime(
'{:04d} {:02d} {:d}'.format(iso_year, iso_weeknumber, iso_weekday)
'%G %V %u')
Pour les prochaines personnes qui viennent ici, une seule définition plus courte, la version, la bonne solution de Ben:
def iso_to_gregorian(iso_year, iso_week, iso_day):
jan4 = datetime.date(iso_year, 1, 4)
start = jan4 - datetime.timedelta(days=jan4.isoweekday()-1)
return start + datetime.timedelta(weeks=iso_week-1, days=iso_day-1)
- 1. Quelle est la meilleure façon de trouver à quelle bibliothèque une fonction peut appartenir?
- 2. Quelle est la meilleure façon de formater C# dans WordPress?
- 3. Quelle est la meilleure façon de déboguer un écrasement explorer.exe?
- 4. Quelle est la meilleure façon de trouver et de remplacer le code "! = Null" avec andand?
- 5. Quelle est la meilleure façon de lire les données CSV?
- 6. Quelle est la meilleure façon de diviser deux objets TimeSpan?
- 7. Quelle est la meilleure façon de rafraîchir un indice Nutch?
- 8. Quelle est la meilleure façon de gunzip fichiers avec Perl?
- 9. Quelle est la meilleure façon de tester les services WCF?
- 10. Quelle est la meilleure façon de localiser un IEnumerable?
- 11. Quelle est la meilleure façon de démarrer avec Open Source?
- 12. Quelle est la meilleure façon de trier par date?
- 13. Quelle est la meilleure façon d'effacer un tableau de chaînes?
- 14. Quelle est la meilleure façon d'exposer l'API de mon serveur?
- 15. Quelle est la meilleure façon de chiffrer un clob?
- 16. Quelle est la meilleure façon de vider un répertoire?
- 17. Quelle est la meilleure façon de structurer un projet?
- 18. Quelle est la meilleure façon de dupliquer fork() dans Windows?
- 19. Quelle est la meilleure façon de commencer à utiliser Mylyn?
- 20. Quelle est la meilleure façon de ReadLine par Expression Tree?
- 21. Quelle est la meilleure façon de lire GetResponseStream()?
- 22. Quelle est la meilleure façon de différencier Crystal Reports?
- 23. Quelle est la meilleure façon de créer des déploiements ClickOnce
- 24. Quelle est la meilleure façon de gérer les exceptions ObjectDataSource?
- 25. Quelle est la meilleure façon de commencer avec NHibernate?
- 26. Quelle est la meilleure façon de faire ce programme Java?
- 27. Quelle est la meilleure façon de déboguer un Oracle SP?
- 28. quelle est la meilleure façon de marquer un texte?
- 29. Quelle est la meilleure façon d'automatiser le remplacement de texte?
- 30. Quelle est la meilleure façon de trouver le type correspondant le plus proche d'un type existant?
Pouvez-vous clarifier la signification du 4 janvier? Existe-t-il une description de la norme de calendrier ISO quelque part? – Tom
Tom: à partir de la définition ISO formelle de la semaine 1 (la semaine contenant le premier jeudi de l'année), il s'ensuit que le 4 janvier est le dernier jour que la semaine 1 peut commencer. –
http://en.wikipedia.org/wiki/ISO_week_date – Tom