Gérer les "années et mois" en Python

J'ai écrit une classe pour gérer "des années et des mois" en Python, mais plus tard j'ai réalisé que je pouvais utiliser dateutil, alors j'ai fait un service commémoratif. Je l'ai écrit avec élan et il n'y a pas de test, alors utilisez-le à vos risques et périls.

la mise en oeuvre

import re
from datetime import date


class ym:
    """Type de données qui gère l'année et le mois"""

    def __init__(self, y: int, m: int = None):
        if type(y) is date:
            y, m = y.year, y.month
        if not (0 <= y <= 10000 and 1 <= m <= 12):
            raise ValueError()
        self.x = y * 12 + m - 1

    @classmethod
    def current(cls):
        return cls(date.today())

    @classmethod
    def parse(cls, s: str):
        matched = re.match(r"^(\d+)-(\d+)$", s)
        if not matched:
            raise ValueError()
        return cls(int(matched[1]), int(matched[2]))

    @property
    def y(self):
        return self.x // 12

    @property
    def m(self):
        return self.x % 12 + 1

    def to(self, y, m=None) -> list:
        target = y if type(y) is self.__class__ else self.__class__(y, m)
        return [self + i for i in range(target - self)] if self < target else []

    def __repr__(self):
        cls = self.__class__
        return f"{cls.__module__}.{cls.__name__}({self.y}, {self.m})"

    def __str__(self):
        return f"{self.y:04d}-{self.m:02d}"

    def __add__(self, n: int):
        if type(n) is int:
            return self.__class__((self.x + n) // 12, (self.x + n) % 12 + 1)
        raise TypeError()

    def __sub__(self, n):
        if type(n) is int:
            return self + (-1 * n)
        if type(n) is self.__class__:
            return self.x - n.x
        raise TypeError()

    def __eq__(self, other):
        return self.x == other.x

    def __ne__(self, other):
        return self.x != other.x

    def __lt__(self, other):
        return self.x < other.x

    def __gt__(self, other):
        return self.x > other.x

exemple

Créez une instance en spécifiant l'année et le mois

ym(2020, 4)  #=> ym(2020, 4)

Créer une instance à partir du mois en cours

ym.current()  #=> ym(2020, 7)

Créer une instance à partir d'une chaîne

ym.parse("2020-04")  #=> ym(2020, 4)

Créer une instance à partir d'un objet de date

from datetime import date

ym.parse(date.today())  #=> ym(2020, 7)
from datetime import datetime

dt = dateime.now()
ym.parse(dt.date())  #=> ym(2020, 7)

Obtenez année, mois

current = ym.current()  #=> ym(2020, 7)
current.y  #=> 2020
current.m  #=> 7

Addition et soustraction

ym(2020, 04) + 10  #=> ym(2021, 2)
ym(2020, 04) - 10  #=> ym(2019, 6)

Différence année / mois

ym(2020, 7) - ym(2020, 4)  #=> 3

Calcul de comparaison

ym(2020, 7) < ym(2020, 4)  #=> False
ym(2020, 7) > ym(2020, 4)  #=> True
ym(2020, 7) == ym(2020, 4)  #=> False

Acquisition de portée

ym(2020, 4).to(2020, 7)  #=> [ym(2020, 4), ym(2020, 5), ym(2020, 6)]
current = ym.current()  #=> ym(2020, 7)
current.to(current + 6)  #=> [ym(2020, 7), ym(2020, 8), ym(2020, 9), ym(2020, 10), ym(2020, 11), ym(2020, 12)]

Recommended Posts

Gérer les "années et mois" en Python
[python] Calcul des mois et des années de différence de date / heure
Jusqu'à traiter de python dans Atom
Conseils pour gérer les binaires en Python
Encodage de caractères lors du traitement de fichiers en Python 3
[Python] Traitement de plusieurs erreurs d'appel dans ray.init
Programmation avec Python et Tkinter
Chiffrement et déchiffrement avec Python
Grattage au sélénium en Python
Python et matériel - Utilisation de RS232C avec Python -
Grattage avec chromedriver en python
Débogage avec pdb en Python
Précautions lors du traitement du type ROS MultiArray en Python
Gérer les sons en Python
Grattage avec du sélénium en Python
Calculer la différence entre Pose et Transform avec ROS en Python
Grattage avec Tor en Python
Tweet avec image en Python
Combiné avec ordinal en Python
Pile et file d'attente en Python
Démarrer le calcul numérique avec Python (avec Homebrew et pip)
Sortie japonaise lors de l'utilisation de python dans Visual Studio
python avec pyenv et venv
Unittest et CI en Python
Fonctionne avec Python et R
Prise en compte du moment où vous pouvez faire du bon travail en 10 ans avec Python3 et Scala3.
Veriloggen et cocotb sont utilisés pour concevoir et tester Verilog en Python uniquement.
Jouez avec les archives de Mastodon dans les réponses et les favoris de Python 2 Count
Installez CaboCha dans l'environnement Ubuntu et appelez-le avec Python.
Comment se connecter à AtCoder avec Python et soumettre automatiquement
Communiquez avec FX-5204PS avec Python et PyUSB
Reconnaissance des nombres dans les images avec Python
Briller la vie avec Python et OpenCV
Paquets qui gèrent le MIDI avec Python midi et pretty_midi
Robot fonctionnant avec Arduino et python
Tester avec des nombres aléatoires en Python
Installez Python 2.7.9 et Python 3.4.x avec pip.
Différence entre list () et [] en Python
Réseau neuronal avec OpenCV 3 et Python 3
Modulation et démodulation AM avec python
Différence entre == et est en python
Scraping avec Node, Ruby et Python
Afficher les photos en Python et html
GOTO en Python avec Sublime Text 3
Travailler avec LibreOffice en Python: import
Algorithme de tri et implémentation en Python
Scraping avec Selenium en Python (Basic)
Analyse CSS avec cssutils en Python
Grattage avec Python, Selenium et Chromedriver
Grattage avec Python et belle soupe
À propos de Python et Cython dtype
Numer0n avec des objets fabriqués avec Python
Ouvrez UTF-8 avec BOM en Python
Affectations et modifications des objets Python
Encodage et décodage JSON avec python
Utiliser rospy avec virtualenv dans Python3
Vérifiez et déplacez le répertoire en Python
Introduction à Hadoop et MapReduce avec Python
[GUI en Python] PyQt5-Glisser-déposer-
Chiffrement avec Python: IND-CCA2 et RSA-OAEP