Commit a4e9ca11 authored by Robert Sebille's avatar Robert Sebille
Browse files

Adaptation en vue de publication sur pip

parent 77ca65c9
[file_prefs]
final_new_line=true
ensure_convert_new_lines=false
strip_trailing_spaces=false
replace_tabs=true
[indentation]
indent_width=4
indent_type=0
indent_hard_tab_width=8
detect_indent=false
detect_indent_width=false
indent_mode=2
[project]
name=AaaaHorodatage
base_path=/home/robert/dev/python/AaaaHorodatage
[long line marker]
long_line_behaviour=1
long_line_column=80
[files]
current_page=0
[VTE]
last_dir=/home/robert/Nextcloud/dev/python/puissance4
......@@ -9,9 +9,13 @@ This program needs python 3 and modules aaaa.ahordat, aaaa.ahordattools.
__Below, in the same directory as this README.md file__
## Usage
### In a file.py:
from aaaa.ahordattools import AaaaHorodatageTools
from aaaa.ahordat import AaaaHorodatageTools
<your code>
### Démo
in python shel, eg:
from aaaa.demo import demo
demo()
### Init:
from aaaa.ahordattools import AaaaHorodatageTools
......
#!/usr/bin/env python3
# -*-coding:Utf-8 -*
"""Encoding and decoding module for timestamps of AaaaHorodatage class.
Timestamp format = [0-9]+AAAAZ+/-HH:MM where [0-9]+ = the number of
seconds from the epoch until the date entered, AAAA = the epoch of
the timestamp, and Z+/-HH:MM the UTC offset (e.g for CEST,
summertime: Z+02:00). The timezone and epoch are embedded.
Class attribute(s)
- epoch: class reference year of the timestamp (only for encoding).
Range: 1000 <= epoch <= 9999. Default 2000.
Several ranges and keyboard input are managed, but not exceptions.
"""
#########################################
# GNU General Public License, version 3 #
......@@ -49,6 +34,21 @@ import time
class AaaaHorodatage:
"""
Encoding and decoding module for timestamps of AaaaHorodatage class.
Timestamp format = [0-9]+AAAAZ+/-HH:MM where [0-9]+ = the number of
seconds from the epoch until the date entered, AAAA = the epoch of
the timestamp, and Z+/-HH:MM the UTC offset (e.g for CEST,
summertime: Z+02:00). The timezone and epoch are embedded.
Class attribute(s)
- epoch: class reference year of the timestamp (only for encoding).
Range: 1000 <= epoch <= 9999. Default 2000.
Several ranges and keyboard input are managed, but not exceptions.
"""
# année de référence (attribut de classe)
epoch = 2000
# Europe/Brussels summertime
......@@ -632,3 +632,368 @@ if __name__ == "__main__":
print("1: ", k.decode())
print("2: ", k.decode("dictionary"))
print("3: ", l.decode("dictionary", my_k))
class AaaaHorodatageTools(AaaaHorodatage):
"""
Tools for timestamps of AaaaHorodatage class, Child class of
AaaaHorodatage.
Timestamp format = [0-9]+AAAAZ+/-HH:MM where [0-9]+ = the number of
seconds from the epoch until the date entered, AAAA = the epoch of
the timestamp, and Z+/-HH:MM the UTC offset (e.g for CEST,
summertime: Z+02:00). The timezone and epoch are embedded.
Class attribute(s)
- epoch: class reference year of the timestamp (only for encoding).
Range: 1000 <= epoch <= 9999. Default 2000.
Several ranges and keyboard input are managed, but not exceptions.
"""
# For dev start #
# in AaaaHorodatage:
# année de référence (attribut de classe)
# epoch = 1900
# private
# attributs
# def _get_ljm(self, i):
# ljm = property(_get_ljm)
# methodes
# def _bissextile(self, an = 0):
# def _input_entier(self, annonce=""):
# def _calcul_encode(self):
# def _cal def _input_entier(self, annonce=""):cul_decode(self, typ):
# méthodes publiques
# classe (cls)
# def get_epoch(cls):
# get_epoch = classmethod(get_epoch)
# def set_epoch(cls, num):
# set_epoch = classmethod(set_epoch)
# instance (self)
# def encode(self, d=""):
# def decode(self, typ="string", t=0):
# For dev end
def __init__(self, ts=""):
AaaaHorodatage.__init__(self, ts)
# protected
#douglas = open("aaaa/42", "r")
#self._Aaaa42 = douglas.read()
#douglas.close()
def get_42(self):
douglas = open("aaaa/42", "r")
print(douglas.read())
douglas.close()
print("Non fatal error 42: existential error 101010.")
print("System not halted. L'histoire")
print(" con")
print(" ti")
print(" n")
print(" u")
print(" e")
print(" .")
print(" .")
print(" .\n")
print("|101010 101010 101010 101010 101010 101010 101010 101010 101010\
101010 101010 |\n")
#get_42 = property(_get_42)
# protected #
# attributs
# Special #
def copy(self):
tmp = AaaaHorodatageTools()
tmp.ts = self.ts
return tmp
def __eq__(self, ts_object):
"""== operator"""
aaaa = self.copy()
aaaa_posix = aaaa.convert_aaaa2posix()
ts_object_posix = ts_object.convert_aaaa2posix()
return aaaa_posix == ts_object_posix
def __ne__(self, ts_object):
"""!= operator"""
aaaa = self.copy()
aaaa_posix = aaaa.convert_aaaa2posix()
ts_object_posix = ts_object.convert_aaaa2posix()
return aaaa_posix != ts_object_posix
def __gt__(self, ts_object):
"""> operator"""
aaaa = self.copy()
aaaa_posix = aaaa.convert_aaaa2posix()
ts_object_posix = ts_object.convert_aaaa2posix()
return aaaa_posix > ts_object_posix
def __ge__(self, ts_object):
""">= operator"""
aaaa = self.copy()
aaaa_posix = aaaa.convert_aaaa2posix()
ts_object_posix = ts_object.convert_aaaa2posix()
return aaaa_posix >= ts_object_posix
def __lt__(self, ts_object):
"""< operator"""
aaaa = self.copy()
aaaa_posix = aaaa.convert_aaaa2posix()
ts_object_posix = ts_object.convert_aaaa2posix()
return aaaa_posix < ts_object_posix
def __le__(self, ts_object):
"""<= operator"""
aaaa = self.copy()
aaaa_posix = aaaa.convert_aaaa2posix()
ts_object_posix = ts_object.convert_aaaa2posix()
return aaaa_posix <= ts_object_posix
def __str__(self):
"""Return the string self.ts"""
return self.get_ts()
def __add__(self, seconds=0):
"""new_ts = ts_object + seconds.
Overload of plus operator.
self.ts will be updated
Tips:
- use dhms2second(d=0, h=0, m=0, s=0) method to
convert days + hours + minutes + seconds in seconds
- To add seconds to a new timestamp instance:
new_ts_object = ts_object.copy()
new_ts_object + seconds
"""
tmp = self.ts.split("Z")
ts_offset = tmp[1]
tmp = int(tmp[0])
ts_epoch = int(tmp % 10000)
ts_seconds = int(tmp / 10000)
ts_seconds += seconds
self.ts = str(ts_seconds) + str(ts_epoch) + "Z" + ts_offset
return self
def __sub__(self, *nb_seconds_or_ts_object):
"""new_ts = ts_object - *nb_seconds_or_ts_object
Overload of minus operator.
if *nb_seconds_or_ts_object is ts_object, call
self.ts.diffDays("string", *nb_seconds_or_ts_object.get_ts()),
see this method. self.ts is NOT updated.
if *nb_seconds_or_ts_object is a nb_seconds integer
update and return self.ts - *nb_seconds
self.ts seconds - seconds must be >= 0 (epoch-01-01)
Tips:
- use dhms2second(d=0, h=0, m=0, s=0) utility method
to convert days + hours + minutes + seconds in seconds
- To add seconds to a new timestamp instance:
new_ts_object = ts_object.copy()
new_ts_object - seconds
"""
if isinstance(nb_seconds_or_ts_object[0], AaaaHorodatageTools):
return nb_seconds_or_ts_object[0].diffDays("string", self.get_ts())
if isinstance(nb_seconds_or_ts_object[0], int):
seconds = nb_seconds_or_ts_object[0]
tmp = self.ts.split("Z")
ts_offset = tmp[1]
tmp = int(tmp[0])
ts_epoch = int(tmp % 10000)
ts_seconds = int(tmp / 10000)
if ts_seconds >= seconds:
ts_seconds -= seconds
else:
print("Fatal error 53: number of seconds to substract ", end="")
print("to big in __sub__(seconds=0). Substract < ", end="")
print(ts_epoch, "-01-01 (epoch of the timestamp)", sep="")
print("Program halted.")
sys.exit(53)
self.ts = str(ts_seconds) + str(ts_epoch) + "Z" + ts_offset
return self
# protected #
# méthodes
# méthodes publiques #
# class (cls)
# instance (self)
def diffDays(self, typ="string", ts2=0):
"""Difference between 2 timestamps in days, hours, minutes, seconds.
ts2 - self.ts1.
Usage: ts1_object.diffDays(<typ>, <ts2>)
Offset UTC timestamp 1 must match offset UTC timestamp 2
and epoch timestamp 1 must match epoch timestamp 2.
Return typ =
- "seconds": return the number of seconds.
- "string": return a string (+/-DDTHH:MM:SS). Default.
- "list": return a list (fixed order).
fixed order: sens_difference, day, hour, minutes, seconds.
- "dict" or "dictionary": return a dict (any order).
ts2 = 0 or none: keyboard input.
ts2 eg: ts2_object.get_ts()
"""
# if keyboard
if ts2 == 0:
ts2 = input("Decode timestamp 2: ")
# if arg
# to do
# Récupération des timestamp et test des offset utc
ts1_split = self.ts.split("Z")
ts2_split = ts2.split("Z")
if ts1_split[1] != ts2_split[1]:
print("Fatal error 51: offset UTC1 " + ts1_split[1] +
" does not match offset UTC2 " + ts2_split[1] +
"\nProgram halted.")
print("Consider to standardize the 2 timestamps to Z (+00:00)")
print(" using <instance>.tz2utc(timestamp1)")
print(" using <instance>.tz2utc(timestamp2)")
sys.exit(51)
# recup ts1, ts2
ts1 = int(ts1_split[0])
ts2 = int(ts2_split[0])
epoch1 = ts1 % 10000
epoch2 = ts2 % 10000
ts1 = int(ts1 / 10000)
ts2 = int(ts2 / 10000)
# test des epoch
if epoch1 != epoch2:
print("Fatal error 52: epoch1 " + str(epoch1) +
" does not match epoch2 " + str(epoch2) +
"\nProgram halted.")
print("Consider to standardize the 2 epochs")
print(" using <instance>.convert2epoch(timestamp1, epoch)")
print(" using <instance>.convert2epoch(timestamp2, epoch)")
sys.exit(52)
# ts2 > ts1 => sens diff = +, sinon -
sens_diff = "+"
if ts1 > ts2:
ts1, ts2 = ts2, ts1
sens_diff = "-"
dts = ts2 - ts1
secondes = dts % 60
minutes = int((dts / 60) % 60)
heures = int((dts / (60 * 60)) % 24)
jours = int(dts / (60 * 60 * 24))
if typ == "seconds":
if sens_diff == "-":
retour = -dts
else:
retour = dts
if typ == "string":
retour = (sens_diff + str(jours) + "T" + str(heures) + ":" +
str(minutes) + ":" + str(secondes))
if typ == "list":
retour = list()
retour.append(sens_diff)
retour.append(jours)
retour.append(heures)
retour.append(minutes)
retour.append(secondes)
if typ == "dict" or typ == "dictionary":
retour = dict()
retour["sensdiff"] = sens_diff
retour["days"] = jours
retour["hours"] = heures
retour["minutes"] = minutes
retour["seconds"] = secondes
return retour
def convert2epoch(self, epoch):
"""Convert an embedded epoch to an other
1000 <= epoch <= 9999
self.ts is updated
"""
ts_offset = self.ts.split("Z")
ts_offset = self.offset_string2seconds(ts_offset[1])
save_offset = self.get_utc_local_offset()
save_epoch = self.get_epoch()
ts = self.decode("list", self.ts)
self.set_epoch(epoch)
self.set_utc_local_offset(ts_offset)
ts = self.encode(ts)
self.set_epoch(save_epoch)
self.set_utc_local_offset(save_offset)
self.ts = ts
return self.ts
def dhms2seconds(self, d=0, h=0, m=0, s=0):
"""Convert days + hours + minutes + seconds in seconds"""
return d * self._get_nb_sec_par_jour() + h * 3600 + m * 60 + s
def convert_aaaa2posix(self):
"""Return a Posix timestamp (UTC) from an Aaaa timestamp"""
aaaa_ts = self.copy()
aaaa_ts.convert2epoch(1970)
aaaa_ts.tz2utc()
#self.ts = save_local_ts
tmp = aaaa_ts.get_ts().split("Z")
ts_sec = int(tmp[0])
ts_sec = int(ts_sec / 10000)
return ts_sec
def convert_posix2aaaa(self, posix_ts):
"""Return an Aaaa timestamp from a Posix timestamp
self.ts is updated
posix_ts will be considered at UTC time.
"""
self.ts = str(posix_ts) + "1970Z+00:00"
return self.ts
def set_ts_same_epoch_offset(self, ts_object):
"""Convert ts_object to same epoch and UTC offset
than self.ts
ts_object.ts is updated
"""
ts_epoch = self.get_ts_epoch()
tmp = self.get_ts()
tmp = tmp.split("Z")
ts_offset = tmp[1]
ts_object.tz2utc()
ts_object.utc2tz(ts_offset)
ts_object.convert2epoch(ts_epoch)
return ts_object
if __name__ == "__main__":
# at top, # from ahordat import AaaaHorodatage # to test module
h = AaaaHorodatageTools()
h.encode((2001, 1, 1, 10, 10, 10))
print(h.decode())
h2 = h + h.dhms2seconds(1, 2, 10, 20)
print(h2.get_ts())
print(h.decode(), " - ", h2.decode())
sys.exit()
k = AaaaHorodatageTools()
print(k.get_utc_local_offset())
print(k.get_utc_local_offset("string"))
myKCEST = k.encode([2001, 2, 20, 20, 15, 30])
print(myKCEST)
print(k.decode('string', myKCEST), "\n---")
print(k.convert2epoch(myKCEST, 1900))
#!/usr/bin/env python3
# -*-coding:Utf-8 -*
"""Tools for timestamps of AaaaHorodatage class, Child class of
AaaaHorodatage.
Timestamp format = [0-9]+AAAAZ+/-HH:MM where [0-9]+ = the number of
seconds from the epoch until the date entered, AAAA = the epoch of
the timestamp, and Z+/-HH:MM the UTC offset (e.g for CEST,
summertime: Z+02:00). The timezone and epoch are embedded.
Class attribute(s)
- epoch: class reference year of the timestamp (only for encoding).
Range: 1000 <= epoch <= 9999. Default 2000.
Several ranges and keyboard input are managed, but not exceptions.
Help and download:
https://gitlab.adullact.net/zenjo/AaaaHorodatage/tree/master
"""
#########################################
# GNU General Public License, version 3 #
############################################################################
# #
# This program is free software: you can redistribute it and/or modify #
# it under the terms of the GNU General Public License as published by #
# the Free Software Foundation, either version 3 of the License, or #
# (at your option) any later version. #
# #
# This program is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU General Public License for more details. #
# #
# You should have received a copy of the GNU General Public License #
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
# #
# Robert Sebille, Belgium, 2018 - #
# #
############################################################################
# As compliant as possible with the PEP8 #
# https://www.python.org/dev/peps/pep-0008/ #
#############################################
import os
import sys
import math
import time
# value to test module
# from ahordat import AaaaHorodatage
# value for production
from aaaa.ahordat import AaaaHorodatage
class AaaaHorodatageTools(AaaaHorodatage):
# For dev start #
# in AaaaHorodatage:
# année de référence (attribut de classe)
# epoch = 1900
# private
# attributs
# def _get_ljm(self, i):
# ljm = property(_get_ljm)
# methodes
# def _bissextile(self, an = 0):
# def _input_entier(self, annonce=""):
# def _calcul_encode(self):
# def _cal def _input_entier(self, annonce=""):cul_decode(self, typ):
# méthodes publiques
# classe (cls)
# def get_epoch(cls):
# get_epoch = classmethod(get_epoch)
# def set_epoch(cls, num):
# set_epoch = classmethod(set_epoch)
# instance (self)
# def encode(self, d=""):
# def decode(self, typ="string", t=0):
# For dev end
def __init__(self, ts=""):
AaaaHorodatage.__init__(self, ts)
# protected
#douglas = open("aaaa/42", "r")
#self._Aaaa42 = douglas.read()
#douglas.close()
def get_42(self):
douglas = open("aaaa/42", "r")
print(douglas.read())
douglas.close()
print("Non fatal error 42: existential error 101010.")
print("System not halted. L'histoire")
print(" con")
print(" ti")
print(" n")
print(" u")
print(" e")
print(" .")
print(" .")
print(" .\n")
print("|101010 101010 101010 101010 101010 101010 101010 101010 101010\
101010 101010 |\n")
#get_42 = property(_get_42)
# protected #
# attributs
# Special #
def copy(self):
tmp = AaaaHorodatageTools()
tmp.ts = self.ts
return tmp
def __eq__(self, ts_object):
"""== operator"""
aaaa = self.copy()
aaaa_posix = aaaa.convert_aaaa2posix()
ts_object_posix = ts_object.convert_aaaa2posix()
return aaaa_posix == ts_object_posix
def __ne__(self, ts_object):
"""!= operator"""
aaaa = self.copy()
aaaa_posix = aaaa.convert_aaaa2posix()
ts_object_posix = ts_object.convert_aaaa2posix()
return aaaa_posix != ts_object_posix
def __gt__(self, ts_object):
"""> operator"""
aaaa = self.copy()
aaaa_posix = aaaa.convert_aaaa2posix()
ts_object_posix = ts_object.convert_aaaa2posix()
return aaaa_posix > ts_object_posix
def __ge__(self, ts_object):
""">= operator"""
aaaa = self.copy()
aaaa_posix = aaaa.convert_aaaa2posix()
ts_object_posix = ts_object.convert_aaaa2posix()
return aaaa_posix >= ts_object_posix
def __lt__(self, ts_object):
"""< operator"""
aaaa = self.copy()
aaaa_posix = aaaa.convert_aaaa2posix()
ts_object_posix = ts_object.convert_aaaa2posix()
return aaaa_posix < ts_object_posix
def __le__(self, ts_object):
"""<= operator"""
aaaa = self.copy()
aaaa_posix = aaaa.convert_aaaa2posix()
ts_object_posix = ts_object.convert_aaaa2posix()
return aaaa_posix <= ts_object_posix
def __str__(self):
"""Return the string self.ts"""
return self.get_ts()
def __add__(self, seconds=0):
"""new_ts = ts_object + seconds.
Overload of plus operator.
self.ts will be updated
Tips:
- use dhms2second(d=0, h=0, m=0, s=0) method to
convert days + hours + minutes + seconds in seconds
- To add seconds to a new timestamp instance:
new_ts_object = ts_object.copy()
new_ts_object + seconds
"""