Commit 9c526839 authored by Robert Sebille's avatar Robert Sebille
Browse files

Cleaning returns and changes of objects. Capture of server UTC time with time module

parent 96fb8d00
......@@ -7,19 +7,23 @@ AaaaHorodatage
5: *offset must be a string or an integer in set_utc_local_offset(*offset).
6: *offset out of range in set_utc_local_offset(*offset).
-43200 >= *offset <= +50400 or '-12:00' >= *offset <= '+14:00'.
7: missing *new_offset argument in utc2ts(ts, *new_offset).
8: *new_offset must be a string or an integer in utc2ts(ts, *new_offset).
9: *new_offset out of range in utc2ts(ts, *new_offset).
7: missing *new_offset argument in utc2z(ts, *new_offset).
8: *new_offset must be a string or an integer in utc2tz(ts, *new_offset).
9: *new_offset out of range in utc2tz(ts, *new_offset).
-43200 >= *new_offset <= +50400 or '-12:00' >= *new_offset <= '+14:00'.
10: timestamp less than epoch in tz2utc(ts).
53: number of seconds to substract to big in __sub__(seconds=0).
Substraction < <ts_epoch>-01-01 epoch of the timestamp. Program halted.")
54: aaaa_ts must be an UTC timestamp in convert_utc2posix(aaaa_ts).
11: timestamp less than epoch in utc2tz(ts)
12: I can only convert an UTC timestamp. In utc2tz (*new_offset).
AaaaHorodatageTools
51 : offset UTC timestamp 1 does not match offset UTC timestamp 2 in diffTs
52 : epoch timestamp 1 does not match epoch timestamp 2 in diffDays
53: number of seconds to substract to big in __sub__(seconds=0).
Substraction < <ts_epoch>-01-01 epoch of the timestamp. Program halted.")
54: aaaa_ts must be an UTC timestamp in convert_utc2posix(aaaa_ts).
others
42: existential error 101010. System halted.
......@@ -12,78 +12,89 @@ __Below, in the same directory as this README.md file__
from aaaa.ahordattools import AaaaHorodatageTools
<your code>
### Code:
>>> from aaaa.ahordattools import AaaaHorodatageTools
>>> <new instance> = AaaaHorodatageTools()
### Init:
from aaaa.ahordattools import AaaaHorodatageTools
new_ts_object = AaaaHorodatageTools()
or
>>> <new instance> = AaaaHorodatageTools(AaaaHorodatage)
>>> <your code>
new_ts_object = AaaaHorodatageTools(AaaaTimestamp)
or
new_ts_object = AaaaHorodatageTools("server")
... your code ...
Exemples:
- <new instance\> = _AaaaHorodatageTools()_ will done 2000Z+02:00 = 2000-01-01T00:00:00+02:00, embedded epoch = 2000, (Default).
- <new instance\> = _AaaaHorodatageTools("9782823001970Z+00:00")_ will done 9782823001970Z+00:00 = 2000-12-31T17:05:00+00:00, embedded epoch = 1970.
- _new_ts_object_ = _AaaaHorodatageTools()_ will create 2000Z+02:00 = 2000-01-01T00:00:00+02:00, embedded epoch = 2000, (Default).
- _new_ts_object_ = _AaaaHorodatageTools("server")_ will create ts_object with time server UTC.
### Modifiers
An AaaaHordatage instance has two public attibutes:
_self.ts_ (its timestamp) and _self.utc_local_offset_ (its UTC offset in seconds).
An AaaaHordatage instance has one public instance attibutes: _self.ts_ (its timestamp).
Some methods, i call modifiers, can change this attributes; they will be documented with _update self.ts, self.utc_local_offset_
Some methods, i call modifiers, can change this attribute; they will be documented with _update self.ts_.
### Generate timestamps
encode(d="", utc=False) # possible inputs:
update self.ts
update and return self.ts
d="": keyboard input
d= list, tuple or dictionary.
utc=False: Local UTC offset encoding (see "Setting your timezone")
utc=True: UTC encoding
decode("typ", ts) typ = "string", "list", "dict" ou "dictionary"
ts = timestamp: I will use ts.
ts = none or "": I will use self.ts.
decode("typ", ts="")
return typ = "string", "list", "dict" ou "dictionary"
ts = timestamp (e.g.: ts_object.get_ts()): use ts.
ts = none or "": use self.ts.
NB: encode year > 9999 with an epoch = 1000 can causes long calculations.
## ts_object
### timestamps copy
Shallow copy, but it's enough, here.
new_ts_object = ts_object.copy()
### Harmonize epoch and UTC offset
Convert ts_object_to_harmonize to same epoch and UTC offset than ts_object
ts_object.set_ts_same_epoch_offset(ts_object_to_harmonize)
ts_object_to_harmonize.ts is updated
## Timezones
### Setting your timezone
Your local timezone is stored in _utc_local_offset_ attribute
Your local timezone is stored in _utc_local_offset_ class attribute
Default is +7200 seconds, that is to say +02:00; Europe/Brussels summertime
_utc_local_offset_ range: -43200 >= _utc_seconds_ <= +50400
Timestamps embbed their own UTC offset, then this attribute is just for encoding timestamp.
You can use public methods to get or set it.
get_utc_local_offset(typ="")
typ="": default, seconds (integer); typ="string": "+/-HH:MM"
get_utc_local_offset(typ="") # instance method
typ="": default, seconds (integer); typ="string": "+/-HH:MM"
Return _utc_local_offset
set_utc_local_offset(*offset)
update self.utc_local_offset /!\ NOT self.ts /!\
set_utc_local_offset(*offset) # class method
work with encode(). Default +02:00
-43200 >= *offset <= +50400 or '-12:00' >= *offset <= '+14:00'
Play attention, with __set_utc_local_offset(*offset)__. It's update _self.utc_local_offset_ only
To update _self.ts_ with the new _self.utc_local_offset_, you must re-encode the date. Example:
h = AaaaHorodatageTools()
myDate = (2020, 2, 23, 45, 30, 40)
myTs = h.encode(myDate)
h.set_utc_local_offset(-14400) # update self.utc_local_offset to -04:00
myTs = h.encode(myDate) # update self.ts
Get the embedded UTC offset (the UTC offset embedded in self.ts)
To update _self.ts_ and _self.utc_local_offset_ in the same time, see _tz2utc(ts)_ and _utc2tz(ts, *new_offset)_
get_utc_ts_offset(typ=""):
typ="": default, seconds (integer); typ="string": "+/-HH:MM"
return the embedded UTC offset
### Converting timezone
You can use methods to convert timestamp from utc to a specific timezone and from a specific timezone to utc.
tz2utc(ts)
update self.ts, self.utc_local_offset
ts = timestamp: I will use ts.
ts = none or "": I will use self.ts.
tz2utc()
update and return self.ts
utc2tz(ts, *new_offset)
update self.ts, self.utc_local_offset
ts = timestamp: I will use ts, self.ts is updated with ts.
ts = "": I will use self.ts. It will be updated.
utc2tz(*new_offset)
update and return self.ts
-43200 >= *new_offset <= +50400 or
'-12:00' >= *new_offset <= '+14:00'.
......@@ -109,51 +120,82 @@ The epoch attribute is used for encoding timestamps only. For decoding, the scri
You can use this class methods to get or set it.
get_epoch()
set_epoch(num) # 1000 <= epoch <= 9999
set_epoch(num) # 1000 <= epoch <= 9999, return epoch
### Converting epoch
You can change and adapt the embedded epoch of a timestamp.
convert2epoch(self, ts, epoch)
update self.ts
convert2epoch(epoch)
update and return self.ts
Convert an embedded epoch to an other.
1000 <= epoch <= 9999.
## Operations
Operations relate to timestamps of the same UTC offset and at the same epoch only.
diffDays(self, typ="string", ts1=0, ts2=0) # return ts2 - ts1 in days, hours, minutes, seconds.
### diffDays
_See &laquo; - operator &raquo; too_
ts1_object.diffDays(typ="string", ts2=0)
return ts2 - self.ts1 in days, hours, minutes, seconds.
Offset UTC timestamp 1 must match offset UTC timestamp 2 and epoch timestamp 1 must match epoch timestamp 2.
Return typ =
- "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).
ts1 = 0: keyboard input.
ts2 = 0 or none: keyboard input.
ts1 and ts2 = none: keyboard inputs
ts2 eg: ts2_object.get_ts()
Tips with _ts1_object.diffDays(typ="string", ts2=0)_
I want diffDays between ts1_object, epoch 2000 and offset +02:00, and ts2_object, epoch 1900 and offset +08:00, but not update ts2_object.
Consider this tips:
ts3_object = ts2_object.copy()
ts1_object.set_ts_same_epoch_offset(ts_object3)
diff_ts2_ts1 = ts1_object.diffDays("string", ts3_object.get_ts())
del ts3_object
### + operator
+ operator: new_ts = ts + nb_seconds
update new_ts.ts and new_ts.utc_local_offset
Add nb_seconds at timestamp to new_timestamp
Tips: use dhms2second(d=0, h=0, m=0, s=0) utility method
update and return self.ts + nb_seconds
Add nb_seconds at timestamp
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
### - operator
- operator: new_ts = ts - nb_seconds
update new_ts.ts and new_ts.utc_local_offset
new_ts seconds must be >= 0 (epoch-01-01)
Add nb_seconds at timestamp to new_timestamp
Tips: use dhms2second(d=0, h=0, m=0, s=0) utility method
- operator: new_ts = ts_object - *nb_seconds_or_ts_object
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)
if *nb_seconds_or_ts_object is ts_object, call
self.ts.diffDays("string", *nb_seconds_or_ts_object.get_ts())
self.ts is NOT updated.
_See this method above_
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
### Conversion to and from Posix
convert_aaaa_utc2posix(aaaa_ts)
ts_object.convert_aaaa_utc2posix(aaaa_ts)
Return a Posix timestamp from an Aaaa timestamp
aaaa_ts must be at UTC.
Aaaa timestamp must be at UTC.
convert_posix2aaaa_utc(posix_ts):
ts_object.convert_posix2aaaa_utc(posix_ts):
Return an Aaaa timestamp from a Posix timestamp
update self.ts
posix_ts will be considered at UTC time.
## Help:
......
......@@ -44,13 +44,15 @@
import os
import sys
import math
from datetime import *
import time
class AaaaHorodatage:
# année de référence (attribut de classe)
epoch = 2000
# Europe/Brussels summertime
utc_local_offset = 7200
def __init__(self, ts=""):
# protected
......@@ -59,13 +61,9 @@ class AaaaHorodatage:
self._nb_sec_par_jour = 86400
# public
if ts == "":
self.utc_local_offset = 7200 # Europe/Brussels summertime
# defined with _ljm and utc_local_offset
self.ts = self.encode((self.get_epoch(), 1, 1, 0, 0, 0))
else:
self.ts = ts
tmp = self.ts.split("Z")
self.set_utc_local_offset(self.offset_string2seconds(tmp[1]))
if ts == "server":
self.ts = str(math.trunc(time.time())) + "1970Z+00:00"
# protected #
# attributs
......@@ -163,7 +161,7 @@ class AaaaHorodatage:
# On ajoute l'offset UTC (local ou Z) sous forme de chaine
self.ts = str(ts) + "Z" + self.get_utc_local_offset("string")
if utc:
self.ts = self.tz2utc(self.ts)
self.tz2utc()
# print (annee, " bissextile = ", self.bis)
# print (self.ts, " est l'horodatage pour le ", self.jour, "/", \
......@@ -297,38 +295,7 @@ class AaaaHorodatage:
set_epoch = classmethod(set_epoch)
# instance (self)
def get_ts(self):
"""Return the current timestamp"""
return self.ts
def get_ts_epoch(self):
"""Return the epoch of the timestamp
Don't confuse with the class attribute epoch
you can get or set with class methods
get_epoch() and set_epoch(num)
"""
retour = self.ts.split("Z")
retour = int(retour[0])
retour = int(retour % 10000)
return retour
def get_utc_local_offset(self, typ=""):
"""Get the local UTC offset set by the
set_utc_local_offset method.
Return:
- Number of seconds (default)
- String (+/-HH:MM) if typ = "string"
"""
retour = self.utc_local_offset
if typ == "string":
retour = self._offset_seconds2string(self.utc_local_offset)
return retour
def set_utc_local_offset(self, *offset):
def set_utc_local_offset(cls, *offset):
"""Set the local UTC offset.
Avalaible inputs:
......@@ -357,7 +324,40 @@ class AaaaHorodatage:
print(" -43200 >= *offset <= +50400")
print("or '-12:00' >= *offset <= '+14:00'.")
sys.exit(6)
self.utc_local_offset = offset_candidate
cls.utc_local_offset = offset_candidate
set_utc_local_offset = classmethod(set_utc_local_offset)
# instance (self)
def get_utc_local_offset(self, typ=""):
"""Get the local UTC offset set by the
set_utc_local_offset method.
Return:
- Number of seconds (default)
- String (+/-HH:MM) if typ = "string"
"""
retour = self.utc_local_offset
if typ == "string":
retour = self._offset_seconds2string(self.utc_local_offset)
return retour
def get_ts(self):
"""Return the current timestamp"""
return self.ts
def get_ts_epoch(self):
"""Return the epoch of the timestamp
Don't confuse with the class attribute epoch
you can get or set with class methods
get_epoch() and set_epoch(num)
"""
retour = self.ts.split("Z")
retour = int(retour[0])
retour = int(retour % 10000)
return retour
def encode(self, d="", utc=False):
"""Request input of seconds, minutes, hour, year, month
......@@ -488,6 +488,7 @@ class AaaaHorodatage:
"""
if ts == "":
ts = self.ts
# retour
return self._calcul_decode(typ, ts)
......@@ -508,16 +509,13 @@ class AaaaHorodatage:
"""
return self._offset_string2seconds(offset_string)
def tz2utc(self, ts=""):
def tz2utc(self):
"""Convert the timestamp ts to an UTC.
ts = timestamp: I will use ts.
ts = none or "": I will use self.ts.
self.ts, self.utc_local_offset will be updated.
self.ts will be updated.
"""
if ts == "":
ts = self.ts
ts = self.ts
ts_list = self.decode("list", ts)
# ts_tmp_list[3] = heure, ts_tmp_list[4] = minutes
tmp = ts.split("Z")
......@@ -532,21 +530,18 @@ class AaaaHorodatage:
").", sep="")
sys.exit(10)
self.utc_local_offset = 0
self.ts = str(ts_sec) + str(epoch) + "Z+00:00"
return self.ts
def utc2tz(self, ts="", *new_offset):
def utc2tz(self, *new_offset):
"""Convert a timestamp UTC to an other timezone.
Avalaible inputs:
*new_offset:
- Number of seconds (-43200 >= *new_offset <= +50400)
- String (+/-HH:MM) ("-12:00" >= *new_offset <= "+14:00")
ts = timestamp: I will use ts.
ts = "": I will use self.ts.
self.ts, self.utc_local_offset will be updated.
self.ts will be updated.
"""
if len(new_offset) < 1:
......@@ -568,16 +563,17 @@ class AaaaHorodatage:
print("or '-12:00' >= *new_offset <= '+14:00'.")
sys.exit(9)
if ts == "":
ts = self.ts
ts_list = self.decode("list", ts)
# ts_tmp_list[3] = heure, ts_tmp_list[4] = minutes
ts = self.ts
tmp = ts.split("Z")
ts_offset = self.offset_string2seconds(tmp[1])
if ts_offset != 0:
print("Fatal error 12: I can only convert an UTC timestamp.")
print("In utc2tz (*new_offset).")
sys.exit(12)
ts_sec = int(tmp[0])
ts_epoch = int(ts_sec % 10000)
ts_sec = int(ts_sec / 10000)
ts_sec += offset
self.utc_local_offset = offset
self.ts = str(ts_sec) + str(ts_epoch) + "Z" +\
self._offset_seconds2string(offset)
......
......@@ -15,6 +15,9 @@
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 #
......@@ -43,6 +46,7 @@
import os
import sys
import math
import time
# value to test module
# from ahordat import AaaaHorodatage
# value for production
......@@ -78,9 +82,9 @@ class AaaaHorodatageTools(AaaaHorodatage):
def __init__(self, ts=""):
AaaaHorodatage.__init__(self, ts)
# protected
douglas = open("aaaa/42", "r")
self._Aaaa42 = douglas.read()
douglas.close()
#douglas = open("aaaa/42", "r")
#self._Aaaa42 = douglas.read()
#douglas.close()
# protected #
# attributs
......@@ -92,20 +96,28 @@ class AaaaHorodatageTools(AaaaHorodatage):
Aaaa42 = property(_get_Aaaa42)
# Special #
def copy(self):
tmp = AaaaHorodatageTools()
tmp.ts = self.ts
return tmp
def __str__(self):
"""Return the string self.ts"""
return self.get_ts()
def __add__(self, seconds=0):
"""Add seconds to self.ts and return a new timestamp
with the result. Overload of plus operator.
"""Add seconds to self.ts and return self.ts.
Overload of plus operator.
new_timestamp.ts and new_timestamp.utc_local_offset
will be updated. Not self.ts, neither
self.utc_local_offset
self.ts will be updated
Tips: use dhms2second(d=0, h=0, m=0, s=0) method to
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]
......@@ -113,50 +125,60 @@ class AaaaHorodatageTools(AaaaHorodatage):
ts_epoch = int(tmp % 10000)
ts_seconds = int(tmp / 10000)
ts_seconds += seconds
aaaa = AaaaHorodatageTools()
aaaa.ts = str(ts_seconds) + str(ts_epoch) + "Z" + ts_offset
aaaa.set_utc_local_offset(self.offset_string2seconds(ts_offset))
return aaaa
self.ts = str(ts_seconds) + str(ts_epoch) + "Z" + ts_offset
return self.ts
def __sub__(self, seconds=0):
"""Subtract seconds from self.ts and return a new
timestamp with the result. Overload of minus operator.
def __sub__(self, *nb_seconds_or_ts_object):
"""new_ts = ts_object - *nb_seconds_or_ts_object
Overload of minus operator.
new_timestamp.ts and new_timestamp.utc_local_offset
will be updated. Not self.ts, neither
self.utc_local_offset
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.
Tips: use dhms2second(d=0, h=0, m=0, s=0) method to
convert days + hours + minutes + seconds in seconds
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
"""
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)\nProgram halted.",
sep="")
sys.exit(53)
aaaa = AaaaHorodatageTools()
aaaa.ts = str(ts_seconds) + str(ts_epoch) + "Z" + ts_offset
aaaa.set_utc_local_offset(self.offset_string2seconds(ts_offset))
return aaaa
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.ts
# protected #
# méthodes
# méthodes publiques #
# class (cls)
# instance (self)
def diffDays(self, typ="string", ts1=0, ts2=0):
def diffDays(self, typ="string", ts2=0):
"""Difference between 2 timestamps in days, hours, minutes, seconds.
ts2 - ts1.
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.
......@@ -165,21 +187,18 @@ class AaaaHorodatageTools(AaaaHorodatage):
- "list": return a list (fixed order).
fixed order: sens_difference, day, hour, minutes, seconds.
- "dict" or "dictionary": return a dict (any order).
ts1 = 0: keyboard input.
ts2 = 0 or none: keyboard input.
ts1 and ts2 = none: keyboard inputs
ts2 eg: ts2_object.get_ts()
"""
# if keyboard
if ts1 == 0:
ts1 = input("Decode timestamp 1: ")
if ts2 == 0:
ts2 = input("Decode timestamp 2: ")
# if arg
# to do
# Récupération des timestamp et test des offset utc
ts1_split = ts1.split("Z")
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] +
......@@ -238,20 +257,23 @@ class AaaaHorodatageTools(AaaaHorodatage):
return retour
def convert2epoch(self, ts, epoch):
def convert2epoch(self, epoch):
"""Convert an embedded epoch to an other
1000 <= epoch <= 9999
self.ts is updated
"""
ts = self.decode(<