1 |
#!/usr/bin/env python |
#!/usr/bin/env python |
2 |
# |
# |
3 |
#Minë. Mundo Interactivo-Narrativo en Español [Tierra-Media] |
#Minë. Mundo Interactivo-Narrativo en Español [Tierra-Media] |
4 |
#Copyright (C) 2002 Pablo Ruiz Múzquiz |
#Copyright (C) 2002 Pablo Ruiz Múzquiz |
5 |
# |
# |
6 |
# |
# |
7 |
#This program is free software; you can redistribute it and/or modify |
#This program is free software; you can redistribute it and/or modify |
8 |
#it under the terms of the GNU General Public License as published by |
#it under the terms of the GNU General Public License as published by |
9 |
#the Free Software Foundation; either version 2 of the License, or |
#the Free Software Foundation; either version 2 of the License, or |
10 |
#(at your option) any later version. |
#(at your option) any later version. |
11 |
# |
# |
12 |
#This program is distributed in the hope that it will be useful, |
#This program is distributed in the hope that it will be useful, |
13 |
#but WITHOUT ANY WARRANTY; without even the implied warranty of |
#but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 |
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
15 |
#GNU General Public License for more details. |
#GNU General Public License for more details. |
16 |
# |
# |
17 |
#You should have received a copy of the GNU General Public License |
#You should have received a copy of the GNU General Public License |
18 |
#along with this program; if not, write to the Free Software |
#along with this program; if not, write to the Free Software |
19 |
#Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
#Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
20 |
# |
# |
21 |
# |
# |
22 |
#Fichero: fechahoramine.py |
#Fichero: fechahoramine.py |
23 |
|
|
24 |
"""Módulo para manejar fechas y horas del calendario de Minë. |
"""Módulo para manejar fechas y horas del calendario de Minë. |
25 |
|
|
26 |
Contiene dos clases: |
Contiene dos clases: |
27 |
- FechaHoraMine |
- FechaHoraMine |
28 |
- FechaHoraMineRel |
- FechaHoraMineRel |
29 |
""" |
""" |
30 |
|
|
31 |
from time import * |
from time import * |
32 |
|
|
33 |
class FechaHoraMine: |
class FechaHoraMine: |
34 |
"""Objeto que contiene una fecha y hora dentro de juego. |
"""Objeto que contiene una fecha y hora dentro de juego. |
35 |
|
|
36 |
Externamente el tiempo se identifica como el año, mes, dia, hora y segundo, desde el |
Externamente el tiempo se identifica como el año, mes, dia, hora y segundo, desde el |
37 |
inicio de la Tercera Edad (dia 1 del mes 1 del año 0, a las 0:000 horas). En Minë no se |
inicio de la Tercera Edad (dia 1 del mes 1 del año 0, a las 0:000 horas). En Minë no se |
38 |
cuentan los minutos. |
cuentan los minutos. |
39 |
|
|
40 |
Internamente almacena la información como un entero largo con el número de segundos |
Internamente almacena la información como un entero largo con el número de segundos |
41 |
transcurridos desde la Fecha R (la fecha usada para sincronizar el mundo de Minë con |
transcurridos desde la Fecha R (la fecha usada para sincronizar el mundo de Minë con |
42 |
el real). Tiene fórmulas para transformar en año, mes, dia, hora y segundo. |
el real). Tiene fórmulas para transformar en año, mes, dia, hora y segundo. |
43 |
|
|
44 |
La equivalencia con el tiempo real es 1 segundo Minë = 1 segundo real. A partir de ahí, |
La equivalencia con el tiempo real es 1 segundo Minë = 1 segundo real. A partir de ahí, |
45 |
las constantes SEGUNDOS_POR_HORA, etc. definen la cuenta del tiempo. |
las constantes SEGUNDOS_POR_HORA, etc. definen la cuenta del tiempo. |
46 |
|
|
47 |
Contiene los siguientes atributos: |
Contiene los siguientes atributos: |
48 |
- __anno (int): el año dentro de la Tercera Edad |
- __anno (int): el año dentro de la Tercera Edad |
49 |
- __mes (int): el número del mes |
- __mes (int): el número del mes |
50 |
- __dia (int): el número del día |
- __dia (int): el número del día |
51 |
- __hora (int): la hora del día |
- __hora (int): la hora del día |
52 |
- __segundo (int): el segundo dentro de la hora |
- __segundo (int): el segundo dentro de la hora |
53 |
- __segundos_totales (int): el número de segundos transcurridos desde la Fecha R |
- __segundos_totales (int): el número de segundos transcurridos desde la Fecha R |
54 |
|
|
55 |
Invariantes: |
Invariantes: |
56 |
__anno >= 0 (en realidad podría ser < 0, pero no consideraremos fechas anteriores a la T.E.) |
__anno >= 0 (en realidad podría ser < 0, pero no consideraremos fechas anteriores a la T.E.) |
57 |
__mes in range(1,MESES_POR_ANNO) |
__mes in range(1,MESES_POR_ANNO) |
58 |
__dia in range(1,DIAS_POR_MES) |
__dia in range(1,DIAS_POR_MES) |
59 |
__hora in range(0,HORAS_POR_DIA-1) |
__hora in range(0,HORAS_POR_DIA-1) |
60 |
__segundo in range(0,SEGUNDOS_POR_HORA-1) |
__segundo in range(0,SEGUNDOS_POR_HORA-1) |
61 |
""" |
""" |
62 |
|
|
63 |
# Los siguientes valores representan la correspondencia Tiempo Real - Tiempo Minë. |
# Los siguientes valores representan la correspondencia Tiempo Real - Tiempo Minë. |
64 |
# Pueden ser modificados libremente. |
# Pueden ser modificados libremente. |
65 |
|
|
66 |
FECHA_R_ANNO = 2500 # Fecha R = 1 del 1 del 2500 T.E., a las 0:000h |
FECHA_R_ANNO = 2500 # Fecha R = 1 del 1 del 2500 T.E., a las 0:000h |
67 |
FECHA_R_MES = 1 |
FECHA_R_MES = 1 |
68 |
FECHA_R_DIA = 1 |
FECHA_R_DIA = 1 |
69 |
FECHA_R_HORA = 0 |
FECHA_R_HORA = 0 |
70 |
FECHA_R_SEGUNDO = 0 |
FECHA_R_SEGUNDO = 0 |
71 |
|
|
72 |
FECHA_R_REAL_ANNO = 2002 # Fecha R real = 8 de Septiembre de 2002 D.C. a las 0:0:0h WET |
FECHA_R_REAL_ANNO = 2002 # Fecha R real = 8 de Septiembre de 2002 D.C. a las 0:0:0h WET |
73 |
FECHA_R_REAL_MES = 9 # (Western European Time, 1 hora más que GMT) |
FECHA_R_REAL_MES = 9 # (Western European Time, 1 hora más que GMT) |
74 |
FECHA_R_REAL_DIA = 8 |
FECHA_R_REAL_DIA = 8 |
75 |
FECHA_R_REAL_HORA = 0 |
FECHA_R_REAL_HORA = 0 |
76 |
FECHA_R_REAL_MINUTO = 0 |
FECHA_R_REAL_MINUTO = 0 |
77 |
FECHA_R_REAL_SEGUNDO = 0 |
FECHA_R_REAL_SEGUNDO = 0 |
78 |
|
|
79 |
MESES_POR_ANNO = 12 # 1 año Minë = 45 dias reales (3.888.000 segundos) |
MESES_POR_ANNO = 12 # 1 año Minë = 45 dias reales (3.888.000 segundos) |
80 |
DIAS_POR_MES = 30 # 1 mes Minë = 3,75 dias reales (324.000 segundos) |
DIAS_POR_MES = 30 # 1 mes Minë = 3,75 dias reales (324.000 segundos) |
81 |
HORAS_POR_DIA = 24 # 1 dia Minë = 3 horas reales (10.800 segundos) |
HORAS_POR_DIA = 24 # 1 dia Minë = 3 horas reales (10.800 segundos) |
82 |
SEGUNDOS_POR_HORA = 450 # 1 hora Minë = 7,5 minutos reales (450 segundos) |
SEGUNDOS_POR_HORA = 450 # 1 hora Minë = 7,5 minutos reales (450 segundos) |
83 |
|
|
84 |
# La siguiente lista es para identificar secciones dentro de un dia. El |
# La siguiente lista es para identificar secciones dentro de un dia. El |
85 |
# número indica la hora a la que empieza la sección. |
# número indica la hora a la que empieza la sección. |
86 |
|
|
87 |
SECCIONES = [ (0, "Noche cerrada"), |
SECCIONES = [ (0, "Noche cerrada"), |
88 |
(4, "Madrugada"), |
(4, "Madrugada"), |
89 |
(8, "Por la mañana"), |
(8, "Por la mañana"), |
90 |
(12, "Mediodia"), |
(12, "Mediodia"), |
91 |
(16, "Por la tarde"), |
(16, "Por la tarde"), |
92 |
(20, "Por la noche") ] |
(20, "Por la noche") ] |
93 |
|
|
94 |
# La siguiente lista contiene los nombres de los meses, van ordenados de 1 a |
# La siguiente lista contiene los nombres de los meses, van ordenados de 1 a |
95 |
# MESES_POR_ANNO. |
# MESES_POR_ANNO. |
96 |
|
|
97 |
NOMBRES_MES = [ "enero", |
NOMBRES_MES = [ "enero", |
98 |
"febrero", |
"febrero", |
99 |
"marzo", |
"marzo", |
100 |
"abril", |
"abril", |
101 |
"mayo", |
"mayo", |
102 |
"junio", |
"junio", |
103 |
"julio", |
"julio", |
104 |
"agosto", |
"agosto", |
105 |
"septiembre", |
"septiembre", |
106 |
"octubre", |
"octubre", |
107 |
"noviembre", |
"noviembre", |
108 |
"diciembre" ] |
"diciembre" ] |
109 |
|
|
110 |
# Los siguientes valores son usados internamente para los cálculos. Se obtienen |
# Los siguientes valores son usados internamente para los cálculos. Se obtienen |
111 |
# automáticamente. No tocar. |
# automáticamente. No tocar. |
112 |
|
|
113 |
FECHA_R_REAL_SEGUNDOS_TOTALES = -1 |
FECHA_R_REAL_SEGUNDOS_TOTALES = -1 |
114 |
SEGUNDOS_POR_ANNO = -1 |
SEGUNDOS_POR_ANNO = -1 |
115 |
SEGUNDOS_POR_MES = -1 |
SEGUNDOS_POR_MES = -1 |
116 |
SEGUNDOS_POR_DIA = -1 |
SEGUNDOS_POR_DIA = -1 |
117 |
|
|
118 |
def __init__(self, segundos_totales): |
def __init__(self, segundos_totales): |
119 |
"""Constructor a partir del número de segundos totales. |
"""Constructor a partir del número de segundos totales. |
120 |
|
|
121 |
Normalmente desde fuera no se usará este constructor, sino más bien los |
Normalmente desde fuera no se usará este constructor, sino más bien los |
122 |
métodos FechaHoraMine_crear() o FechaHoraMine_ahora(). |
métodos FechaHoraMine_crear() o FechaHoraMine_ahora(). |
123 |
""" |
""" |
124 |
self.__segundos_totales = segundos_totales |
self.__segundos_totales = segundos_totales |
125 |
self.__descomponer_segundos() |
self.__descomponer_segundos() |
126 |
|
|
127 |
|
|
128 |
def __repr__(self): |
def __repr__(self): |
129 |
"""Devuelve un string representando la instancia, de una forma evaluable.""" |
"""Devuelve un string representando la instancia, de una forma evaluable.""" |
130 |
return "%d" % self.__segundos_totales |
return "%d" % self.__segundos_totales |
131 |
|
|
132 |
|
|
133 |
def __str__(self): |
def __str__(self): |
134 |
"""Devuelve un string con la fecha en formato imprimible.""" |
"""Devuelve un string con la fecha en formato imprimible.""" |
135 |
return "%d de %s de %d T.E. %02d:%03d" % (self.dia(), |
return "%d de %s de %d T.E. %02d:%03d" % (self.dia(), |
136 |
self.nombre_mes(), |
self.nombre_mes(), |
137 |
self.anno(), |
self.anno(), |
138 |
self.hora(), |
self.hora(), |
139 |
self.segundo()) |
self.segundo()) |
140 |
|
|
141 |
def anno(self): |
def anno(self): |
142 |
return self.__anno |
return self.__anno |
143 |
|
|
144 |
|
|
145 |
def mes(self): |
def mes(self): |
146 |
return self.__mes |
return self.__mes |
147 |
|
|
148 |
|
|
149 |
def nombre_mes(self): |
def nombre_mes(self): |
150 |
return FechaHoraMine.NOMBRES_MES[self.__mes - 1] |
return FechaHoraMine.NOMBRES_MES[self.__mes - 1] |
151 |
|
|
152 |
|
|
153 |
def dia(self): |
def dia(self): |
154 |
return self.__dia |
return self.__dia |
155 |
|
|
156 |
|
|
157 |
def hora(self): |
def hora(self): |
158 |
return self.__hora |
return self.__hora |
159 |
|
|
160 |
|
|
161 |
def segundo(self): |
def segundo(self): |
162 |
return self.__segundo |
return self.__segundo |
163 |
|
|
164 |
|
|
165 |
def seccion(self): |
def seccion(self): |
166 |
"""Devuelve el índice de la sección del día en que estamos.""" |
"""Devuelve el índice de la sección del día en que estamos.""" |
167 |
for i in range(len(FechaHoraMine.SECCIONES)-1, -1, -1): |
for i in range(len(FechaHoraMine.SECCIONES)-1, -1, -1): |
168 |
seccion = FechaHoraMine.SECCIONES[i] |
seccion = FechaHoraMine.SECCIONES[i] |
169 |
if self.__hora >= seccion[0]: |
if self.__hora >= seccion[0]: |
170 |
return i |
return i |
171 |
|
|
172 |
|
|
173 |
def desc_seccion(self): |
def desc_seccion(self): |
174 |
"""Devuelve la descripción de la sección del día en que estamos.""" |
"""Devuelve la descripción de la sección del día en que estamos.""" |
175 |
for i in range(len(FechaHoraMine.SECCIONES)-1, -1, -1): |
for i in range(len(FechaHoraMine.SECCIONES)-1, -1, -1): |
176 |
seccion = FechaHoraMine.SECCIONES[i] |
seccion = FechaHoraMine.SECCIONES[i] |
177 |
if self.__hora >= seccion[0]: |
if self.__hora >= seccion[0]: |
178 |
return seccion[1] |
return seccion[1] |
179 |
|
|
180 |
|
|
181 |
def __descomponer_segundos(self): |
def __descomponer_segundos(self): |
182 |
"""Extrae los valores desglosados a partir de los segundos totales.""" |
"""Extrae los valores desglosados a partir de los segundos totales.""" |
183 |
|
|
184 |
self.__anno = (self.__segundos_totales / FechaHoraMine.SEGUNDOS_POR_ANNO) \ |
self.__anno = (self.__segundos_totales / FechaHoraMine.SEGUNDOS_POR_ANNO) \ |
185 |
+ FechaHoraMine.FECHA_R_ANNO |
+ FechaHoraMine.FECHA_R_ANNO |
186 |
|
|
187 |
resto = self.__segundos_totales % FechaHoraMine.SEGUNDOS_POR_ANNO |
resto = self.__segundos_totales % FechaHoraMine.SEGUNDOS_POR_ANNO |
188 |
|
|
189 |
self.__mes = (resto / FechaHoraMine.SEGUNDOS_POR_MES) \ |
self.__mes = (resto / FechaHoraMine.SEGUNDOS_POR_MES) \ |
190 |
+ FechaHoraMine.FECHA_R_MES |
+ FechaHoraMine.FECHA_R_MES |
191 |
|
|
192 |
resto = resto % FechaHoraMine.SEGUNDOS_POR_MES |
resto = resto % FechaHoraMine.SEGUNDOS_POR_MES |
193 |
|
|
194 |
self.__dia = (resto / FechaHoraMine.SEGUNDOS_POR_DIA) \ |
self.__dia = (resto / FechaHoraMine.SEGUNDOS_POR_DIA) \ |
195 |
+ FechaHoraMine.FECHA_R_DIA |
+ FechaHoraMine.FECHA_R_DIA |
196 |
|
|
197 |
resto = resto % FechaHoraMine.SEGUNDOS_POR_DIA |
resto = resto % FechaHoraMine.SEGUNDOS_POR_DIA |
198 |
|
|
199 |
self.__hora = (resto / FechaHoraMine.SEGUNDOS_POR_HORA) \ |
self.__hora = (resto / FechaHoraMine.SEGUNDOS_POR_HORA) \ |
200 |
+ FechaHoraMine.FECHA_R_HORA |
+ FechaHoraMine.FECHA_R_HORA |
201 |
|
|
202 |
self.__segundo = (resto % FechaHoraMine.SEGUNDOS_POR_HORA) \ |
self.__segundo = (resto % FechaHoraMine.SEGUNDOS_POR_HORA) \ |
203 |
+ FechaHoraMine.FECHA_R_SEGUNDO |
+ FechaHoraMine.FECHA_R_SEGUNDO |
204 |
|
|
205 |
|
|
206 |
def __cmp__(self, otra): |
def __cmp__(self, otra): |
207 |
"""Compara dos fechas. |
"""Compara dos fechas. |
208 |
|
|
209 |
Devuelve -1, 0 o 1 si la segunda fecha es menor, igual o mayor que esta. |
Devuelve -1, 0 o 1 si la segunda fecha es menor, igual o mayor que esta. |
210 |
""" |
""" |
211 |
if self.__segundos_totales < otra.__segundos_totales: |
if self.__segundos_totales < otra.__segundos_totales: |
212 |
return -1 |
return -1 |
213 |
elif self.__segundos_totales > otra.__segundos_totales: |
elif self.__segundos_totales > otra.__segundos_totales: |
214 |
return 1 |
return 1 |
215 |
else: |
else: |
216 |
return 0 |
return 0 |
217 |
|
|
218 |
|
|
219 |
def __sub__(self, otra): |
def __sub__(self, otra): |
220 |
"""Resta esta fecha menos la otra. |
"""Resta esta fecha menos la otra. |
221 |
|
|
222 |
Devuelve la diferencia como una FechaHoraMineRel. |
Devuelve la diferencia como una FechaHoraMineRel. |
223 |
""" |
""" |
224 |
if self >= otra: |
if self >= otra: |
225 |
signo = 1 |
signo = 1 |
226 |
mayor = self |
mayor = self |
227 |
menor = otra |
menor = otra |
228 |
else: |
else: |
229 |
signo = -1 |
signo = -1 |
230 |
mayor = otra |
mayor = otra |
231 |
menor = self |
menor = self |
232 |
|
|
233 |
return FechaHoraMineRel(signo, |
return FechaHoraMineRel(signo, |
234 |
mayor.__anno - menor.__anno, |
mayor.__anno - menor.__anno, |
235 |
mayor.__mes - menor.__mes, |
mayor.__mes - menor.__mes, |
236 |
mayor.__dia - menor.__dia, |
mayor.__dia - menor.__dia, |
237 |
mayor.__hora - menor.__hora, |
mayor.__hora - menor.__hora, |
238 |
mayor.__segundo - menor.__segundo) |
mayor.__segundo - menor.__segundo) |
239 |
|
|
240 |
|
|
241 |
def __add__(self, relativa): |
def __add__(self, relativa): |
242 |
"""Suma una fecha relativa a esta. |
"""Suma una fecha relativa a esta. |
243 |
|
|
244 |
Devuelve otra fecha normal. |
Devuelve otra fecha normal. |
245 |
""" |
""" |
246 |
if relativa.signo() >= 0: |
if relativa.signo() >= 0: |
247 |
return FechaHoraMine_crear(self.__anno + relativa.annos(), |
return FechaHoraMine_crear(self.__anno + relativa.annos(), |
248 |
self.__mes + relativa.meses(), |
self.__mes + relativa.meses(), |
249 |
self.__dia + relativa.dias(), |
self.__dia + relativa.dias(), |
250 |
self.__hora + relativa.horas(), |
self.__hora + relativa.horas(), |
251 |
self.__segundo + relativa.segundos()) |
self.__segundo + relativa.segundos()) |
252 |
else: |
else: |
253 |
return FechaHoraMine_crear(self.__anno - relativa.annos(), |
return FechaHoraMine_crear(self.__anno - relativa.annos(), |
254 |
self.__mes - relativa.meses(), |
self.__mes - relativa.meses(), |
255 |
self.__dia - relativa.dias(), |
self.__dia - relativa.dias(), |
256 |
self.__hora - relativa.horas(), |
self.__hora - relativa.horas(), |
257 |
self.__segundo - relativa.segundos()) |
self.__segundo - relativa.segundos()) |
258 |
|
|
259 |
|
|
260 |
|
|
261 |
def FechaHoraMine_ahora(): |
def FechaHoraMine_ahora(): |
262 |
"""Devuelve una FechaHoraMine correspondiente a la fecha y hora en este momento.""" |
"""Devuelve una FechaHoraMine correspondiente a la fecha y hora en este momento.""" |
263 |
return FechaHoraMine(int(time() + 0.5) - FechaHoraMine.FECHA_R_REAL_SEGUNDOS_TOTALES) |
return FechaHoraMine(int(time() + 0.5) - FechaHoraMine.FECHA_R_REAL_SEGUNDOS_TOTALES) |
264 |
|
|
265 |
|
|
266 |
def FechaHoraMine_crear(anno = FechaHoraMine.FECHA_R_ANNO, \ |
def FechaHoraMine_crear(anno = FechaHoraMine.FECHA_R_ANNO, \ |
267 |
mes = FechaHoraMine.FECHA_R_MES, \ |
mes = FechaHoraMine.FECHA_R_MES, \ |
268 |
dia = FechaHoraMine.FECHA_R_DIA, \ |
dia = FechaHoraMine.FECHA_R_DIA, \ |
269 |
hora = FechaHoraMine.FECHA_R_HORA, \ |
hora = FechaHoraMine.FECHA_R_HORA, \ |
270 |
segundo = FechaHoraMine.FECHA_R_SEGUNDO): |
segundo = FechaHoraMine.FECHA_R_SEGUNDO): |
271 |
"""Devuelve una FechaHoraMine correspondiente a los datos pasados.""" |
"""Devuelve una FechaHoraMine correspondiente a los datos pasados.""" |
272 |
segundos_totales = (anno - FechaHoraMine.FECHA_R_ANNO) * FechaHoraMine.SEGUNDOS_POR_ANNO \ |
segundos_totales = (anno - FechaHoraMine.FECHA_R_ANNO) * FechaHoraMine.SEGUNDOS_POR_ANNO \ |
273 |
+ (mes - FechaHoraMine.FECHA_R_MES) * FechaHoraMine.SEGUNDOS_POR_MES \ |
+ (mes - FechaHoraMine.FECHA_R_MES) * FechaHoraMine.SEGUNDOS_POR_MES \ |
274 |
+ (dia - FechaHoraMine.FECHA_R_DIA) * FechaHoraMine.SEGUNDOS_POR_DIA \ |
+ (dia - FechaHoraMine.FECHA_R_DIA) * FechaHoraMine.SEGUNDOS_POR_DIA \ |
275 |
+ (hora - FechaHoraMine.FECHA_R_HORA) * FechaHoraMine.SEGUNDOS_POR_HORA \ |
+ (hora - FechaHoraMine.FECHA_R_HORA) * FechaHoraMine.SEGUNDOS_POR_HORA \ |
276 |
+ (segundo - FechaHoraMine.FECHA_R_SEGUNDO) |
+ (segundo - FechaHoraMine.FECHA_R_SEGUNDO) |
277 |
return FechaHoraMine(segundos_totales) |
return FechaHoraMine(segundos_totales) |
278 |
|
|
279 |
|
|
280 |
|
|
281 |
class FechaHoraMineRel: |
class FechaHoraMineRel: |
282 |
"""Objeto que contiene LA DIFERENCIA entre dos fechas y horas dentro de juego. |
"""Objeto que contiene LA DIFERENCIA entre dos fechas y horas dentro de juego. |
283 |
|
|
284 |
Mientras que FechaHoraMine mide la distancia entre una fecha y el origen de la T.E., |
Mientras que FechaHoraMine mide la distancia entre una fecha y el origen de la T.E., |
285 |
esta clase mide la distancia entre dos fechas arbitrarias, medida en años, meses, |
esta clase mide la distancia entre dos fechas arbitrarias, medida en años, meses, |
286 |
horas y segundos. |
horas y segundos. |
287 |
|
|
288 |
La distancia puede ser positiva, o negativa, según si la fecha final es posterior o |
La distancia puede ser positiva, o negativa, según si la fecha final es posterior o |
289 |
anterior a la origen, respectivamente. El 0 se considera positivo. |
anterior a la origen, respectivamente. El 0 se considera positivo. |
290 |
|
|
291 |
Internamente NO guarda la conversión a número de segundos. Cuando haya años bisiestos |
Internamente NO guarda la conversión a número de segundos. Cuando haya años bisiestos |
292 |
y otras irregularidades, el número de segundos a que corresponde una FechaHoraMineRel |
y otras irregularidades, el número de segundos a que corresponde una FechaHoraMineRel |
293 |
es variable y depende de cuál sea la fecha origen. Por ejemplo, una diferencia de un |
es variable y depende de cuál sea la fecha origen. Por ejemplo, una diferencia de un |
294 |
mes no dura lo mismo en segundos si el mes origen tiene 30 días o si tiene 31. |
mes no dura lo mismo en segundos si el mes origen tiene 30 días o si tiene 31. |
295 |
|
|
296 |
Nótese que mientras en FechaHoraMine los meses van de 1 a MESES_POR_ANNO, en ésta |
Nótese que mientras en FechaHoraMine los meses van de 1 a MESES_POR_ANNO, en ésta |
297 |
clase van de 0 a MESES_POR_ANNO-1, dado que es una diferencia. Lo mismo con los dias. |
clase van de 0 a MESES_POR_ANNO-1, dado que es una diferencia. Lo mismo con los dias. |
298 |
|
|
299 |
Puede haber números fuera de rango, cuando provienen de una suma o resta de fechas. |
Puede haber números fuera de rango, cuando provienen de una suma o resta de fechas. |
300 |
Por ejemplo, si el año tiene 12 meses, la fecha relativa meses=14, equivale a |
Por ejemplo, si el año tiene 12 meses, la fecha relativa meses=14, equivale a |
301 |
annos=1,meses=2. Otro ejemplo: si el mes tiene 30 dias, la fecha relativa |
annos=1,meses=2. Otro ejemplo: si el mes tiene 30 dias, la fecha relativa |
302 |
meses=3,dias=-5 equivale a meses=2,dias=25. |
meses=3,dias=-5 equivale a meses=2,dias=25. |
303 |
|
|
304 |
Invariantes: |
Invariantes: |
305 |
__signo in [-1, 1] |
__signo in [-1, 1] |
306 |
__annos >= 0 |
__annos >= 0 |
307 |
""" |
""" |
308 |
|
|
309 |
def __init__(self, signo=1, annos=0, meses=0, dias=0, horas=0, segundos=0): |
def __init__(self, signo=1, annos=0, meses=0, dias=0, horas=0, segundos=0): |
310 |
"""Constructor a partir de los componentes. |
"""Constructor a partir de los componentes. |
311 |
|
|
312 |
Requiere: |
Requiere: |
313 |
signo in [-1, 1] |
signo in [-1, 1] |
314 |
annos >= 0 |
annos >= 0 |
315 |
""" |
""" |
316 |
self.__signo = signo |
self.__signo = signo |
317 |
self.__annos = annos |
self.__annos = annos |
318 |
self.__meses = meses |
self.__meses = meses |
319 |
self.__dias = dias |
self.__dias = dias |
320 |
self.__horas = horas |
self.__horas = horas |
321 |
self.__segundos = segundos |
self.__segundos = segundos |
322 |
|
|
323 |
|
|
324 |
def __repr__(self): |
def __repr__(self): |
325 |
"""Devuelve un string representando la instancia, de una forma evaluable.""" |
"""Devuelve un string representando la instancia, de una forma evaluable.""" |
326 |
return "%s%04d/%02d/%02d %02d:%03d" % (((self.__signo < 0) and "(-)" or ""), |
return "%s%04d/%02d/%02d %02d:%03d" % (((self.__signo < 0) and "(-)" or ""), |
327 |
self.__annos, self.__meses, self.__dias, |
self.__annos, self.__meses, self.__dias, |
328 |
self.__horas, self.__segundos) |
self.__horas, self.__segundos) |
329 |
|
|
330 |
|
|
331 |
def __str__(self): |
def __str__(self): |
332 |
"""Devuelve un string con la fecha en formato imprimible.""" |
"""Devuelve un string con la fecha en formato imprimible.""" |
333 |
return "%s%04d/%02d/%02d %02d:%03d" % (((self.__signo < 0) and "(-)" or ""), |
return "%s%04d/%02d/%02d %02d:%03d" % (((self.__signo < 0) and "(-)" or ""), |
334 |
self.__annos, self.__meses, self.__dias, |
self.__annos, self.__meses, self.__dias, |
335 |
self.__horas, self.__segundos) |
self.__horas, self.__segundos) |
336 |
|
|
337 |
def signo(self): |
def signo(self): |
338 |
return self.__signo |
return self.__signo |
339 |
|
|
340 |
|
|
341 |
def annos(self): |
def annos(self): |
342 |
return self.__annos |
return self.__annos |
343 |
|
|
344 |
|
|
345 |
def meses(self): |
def meses(self): |
346 |
return self.__meses |
return self.__meses |
347 |
|
|
348 |
|
|
349 |
def dias(self): |
def dias(self): |
350 |
return self.__dias |
return self.__dias |
351 |
|
|
352 |
|
|
353 |
def horas(self): |
def horas(self): |
354 |
return self.__horas |
return self.__horas |
355 |
|
|
356 |
|
|
357 |
def segundos(self): |
def segundos(self): |
358 |
return self.__segundos |
return self.__segundos |
359 |
|
|
360 |
|
|
361 |
def inverso(self): |
def inverso(self): |
362 |
"""Devuelve el mismo intervalo con el signo invertido.""" |
"""Devuelve el mismo intervalo con el signo invertido.""" |
363 |
if otra.signo() >= 0: |
if otra.signo() >= 0: |
364 |
signo_inverso = -1 |
signo_inverso = -1 |
365 |
else: |
else: |
366 |
signo_inverso = 1 |
signo_inverso = 1 |
367 |
|
|
368 |
return FechaHoraMineRel(signo_inverso, |
return FechaHoraMineRel(signo_inverso, |
369 |
self.annos(), |
self.annos(), |
370 |
self.meses(), |
self.meses(), |
371 |
self.dias(), |
self.dias(), |
372 |
self.horas(), |
self.horas(), |
373 |
self.segundos()) |
self.segundos()) |
374 |
|
|
375 |
|
|
376 |
def abs(self): |
def abs(self): |
377 |
"""Devuelve el mismo intervalo eliminando el signo.""" |
"""Devuelve el mismo intervalo eliminando el signo.""" |
378 |
return FechaHoraMineRel(1, |
return FechaHoraMineRel(1, |
379 |
self.annos(), |
self.annos(), |
380 |
self.meses(), |
self.meses(), |
381 |
self.dias(), |
self.dias(), |
382 |
self.horas(), |
self.horas(), |
383 |
self.segundos()) |
self.segundos()) |
384 |
|
|
385 |
|
|
386 |
def __cmp__(self, otra): |
def __cmp__(self, otra): |
387 |
"""Compara dos intervalos de fechas. |
"""Compara dos intervalos de fechas. |
388 |
|
|
389 |
Devuelve -1, 0 o 1 si el segundo intervalo es más, igual o menos largo que éste. |
Devuelve -1, 0 o 1 si el segundo intervalo es más, igual o menos largo que éste. |
390 |
""" |
""" |
391 |
# Esto lo tengo que revisar un poco, no sé si funciona bien en todos los casos. |
# Esto lo tengo que revisar un poco, no sé si funciona bien en todos los casos. |
392 |
if self.signo() > otra.signo(): |
if self.signo() > otra.signo(): |
393 |
return 1 |
return 1 |
394 |
elif self.signo() < otra.signo(): |
elif self.signo() < otra.signo(): |
395 |
return -1 |
return -1 |
396 |
else: |
else: |
397 |
if self.anno() > otra.anno(): |
if self.anno() > otra.anno(): |
398 |
return 1 |
return 1 |
399 |
elif self.anno() < otra.anno(): |
elif self.anno() < otra.anno(): |
400 |
return -1 |
return -1 |
401 |
else: |
else: |
402 |
if self.mes() > otra.mes(): |
if self.mes() > otra.mes(): |
403 |
return 1 |
return 1 |
404 |
elif self.mes() < otra.mes(): |
elif self.mes() < otra.mes(): |
405 |
return -1 |
return -1 |
406 |
else: |
else: |
407 |
if self.dia() > otra.dia(): |
if self.dia() > otra.dia(): |
408 |
return 1 |
return 1 |
409 |
elif self.dia() < otra.dia(): |
elif self.dia() < otra.dia(): |
410 |
return -1 |
return -1 |
411 |
else: |
else: |
412 |
if self.hora() > otra.hora(): |
if self.hora() > otra.hora(): |
413 |
return 1 |
return 1 |
414 |
elif self.hora() < otra.hora(): |
elif self.hora() < otra.hora(): |
415 |
return -1 |
return -1 |
416 |
else: |
else: |
417 |
if self.segundo() > otra.segundo(): |
if self.segundo() > otra.segundo(): |
418 |
return 1 |
return 1 |
419 |
elif self.segundo() < otra.segundo(): |
elif self.segundo() < otra.segundo(): |
420 |
return -1 |
return -1 |
421 |
else: |
else: |
422 |
return 0 |
return 0 |
423 |
|
|
424 |
|
|
425 |
def __sub__(self, otra): |
def __sub__(self, otra): |
426 |
"""Resta este intervalo menos el otro. |
"""Resta este intervalo menos el otro. |
427 |
|
|
428 |
Devuelve la diferencia como una FechaHoraMineRel. |
Devuelve la diferencia como una FechaHoraMineRel. |
429 |
""" |
""" |
430 |
# Restar es lo mismo que sumar el inverso. |
# Restar es lo mismo que sumar el inverso. |
431 |
return self + otra.inverso() |
return self + otra.inverso() |
432 |
|
|
433 |
|
|
434 |
def __add__(self, otra): |
def __add__(self, otra): |
435 |
"""Suma un intervalo a este. |
"""Suma un intervalo a este. |
436 |
|
|
437 |
Devuelve otra fecha relativa. |
Devuelve otra fecha relativa. |
438 |
""" |
""" |
439 |
if self.signo() == otra.signo(): |
if self.signo() == otra.signo(): |
440 |
signo = self.signo() |
signo = self.signo() |
441 |
else: |
else: |
442 |
if self.abs().signo() >= otra.abs().signo(): |
if self.abs().signo() >= otra.abs().signo(): |
443 |
signo = self.signo() |
signo = self.signo() |
444 |
else: |
else: |
445 |
signo = otra.signo() |
signo = otra.signo() |
446 |
|
|
447 |
if self.signo() == otra.signo(): |
if self.signo() == otra.signo(): |
448 |
return FechaHoraRelativa(signo, |
return FechaHoraRelativa(signo, |
449 |
self.anno() + otra.anno(), |
self.anno() + otra.anno(), |
450 |
self.mes() + otra.mes(), |
self.mes() + otra.mes(), |
451 |
self.dia() + otra.dia(), |
self.dia() + otra.dia(), |
452 |
self.hora() + otra.hora(), |
self.hora() + otra.hora(), |
453 |
self.segundo() + otra.segundo()) |
self.segundo() + otra.segundo()) |
454 |
else: |
else: |
455 |
return FechaHoraRelativa(signo, |
return FechaHoraRelativa(signo, |
456 |
self.anno() - otra.anno(), |
self.anno() - otra.anno(), |
457 |
self.mes() - otra.mes(), |
self.mes() - otra.mes(), |
458 |
self.dia() - otra.dia(), |
self.dia() - otra.dia(), |
459 |
self.hora() - otra.hora(), |
self.hora() - otra.hora(), |
460 |
self.segundo() - otra.segundo()) |
self.segundo() - otra.segundo()) |
461 |
|
|
462 |
|
|
463 |
|
|
464 |
# ------------------------------------ |
# ------------------------------------ |
465 |
# Código de inicialización del módulo. |
# Código de inicialización del módulo. |
466 |
# ------------------------------------ |
# ------------------------------------ |
467 |
|
|
468 |
# Este valor representa el número de segundos entre la Fecha R de Unix y la Fecha R real |
# Este valor representa el número de segundos entre la Fecha R de Unix y la Fecha R real |
469 |
# de Minë. mktime() convierte una tupla de valores, en el número de segundos desde la |
# de Minë. mktime() convierte una tupla de valores, en el número de segundos desde la |
470 |
# Fecha R de Unix. El número devuelto es float, así que lo convertimos a int redondeando. |
# Fecha R de Unix. El número devuelto es float, así que lo convertimos a int redondeando. |
471 |
|
|
472 |
FechaHoraMine.FECHA_R_REAL_SEGUNDOS_TOTALES = int(mktime((FechaHoraMine.FECHA_R_REAL_ANNO, |
FechaHoraMine.FECHA_R_REAL_SEGUNDOS_TOTALES = int(mktime((FechaHoraMine.FECHA_R_REAL_ANNO, |
473 |
FechaHoraMine.FECHA_R_REAL_MES, |
FechaHoraMine.FECHA_R_REAL_MES, |
474 |
FechaHoraMine.FECHA_R_REAL_DIA, |
FechaHoraMine.FECHA_R_REAL_DIA, |
475 |
FechaHoraMine.FECHA_R_REAL_HORA, |
FechaHoraMine.FECHA_R_REAL_HORA, |
476 |
FechaHoraMine.FECHA_R_REAL_MINUTO, |
FechaHoraMine.FECHA_R_REAL_MINUTO, |
477 |
FechaHoraMine.FECHA_R_REAL_SEGUNDO, |
FechaHoraMine.FECHA_R_REAL_SEGUNDO, |
478 |
-1, -1, -1)) + 0.5) |
-1, -1, -1)) + 0.5) |
479 |
|
|
480 |
# Los siguientes valores son simplemente para acelerar los cálculos internos |
# Los siguientes valores son simplemente para acelerar los cálculos internos |
481 |
|
|
482 |
FechaHoraMine.SEGUNDOS_POR_DIA = FechaHoraMine.SEGUNDOS_POR_HORA * \ |
FechaHoraMine.SEGUNDOS_POR_DIA = FechaHoraMine.SEGUNDOS_POR_HORA * \ |
483 |
FechaHoraMine.HORAS_POR_DIA |
FechaHoraMine.HORAS_POR_DIA |
484 |
|
|
485 |
FechaHoraMine.SEGUNDOS_POR_MES = FechaHoraMine.SEGUNDOS_POR_DIA * \ |
FechaHoraMine.SEGUNDOS_POR_MES = FechaHoraMine.SEGUNDOS_POR_DIA * \ |
486 |
FechaHoraMine.DIAS_POR_MES |
FechaHoraMine.DIAS_POR_MES |
487 |
|
|
488 |
FechaHoraMine.SEGUNDOS_POR_ANNO = FechaHoraMine.SEGUNDOS_POR_MES * \ |
FechaHoraMine.SEGUNDOS_POR_ANNO = FechaHoraMine.SEGUNDOS_POR_MES * \ |
489 |
FechaHoraMine.MESES_POR_ANNO |
FechaHoraMine.MESES_POR_ANNO |
490 |
|
|
491 |
# ----------------------------------------- |
# ----------------------------------------- |
492 |
# Código para pruebas unitarias del módulo. |
# Código para pruebas unitarias del módulo. |
493 |
# ----------------------------------------- |
# ----------------------------------------- |
494 |
|
|
495 |
if (__name__ == '__main__'): |
if (__name__ == '__main__'): |
496 |
a = FechaHoraMine_crear(anno=2500, mes=8, dia=14) |
a = FechaHoraMine_crear(anno=2500, mes=8, dia=14) |
497 |
b = FechaHoraMine_crear(anno=2500, mes=9, dia=10) |
b = FechaHoraMine_crear(anno=2500, mes=9, dia=10) |
498 |
c = FechaHoraMine_crear(anno=2502, mes=5, dia=20) |
c = FechaHoraMine_crear(anno=2502, mes=5, dia=20) |
499 |
|
|
500 |
print "De [%s]\n a [%s]\n va [%s]" % (str(a), str(b), str(b - a)) |
print "De [%s]\n a [%s]\n va [%s]" % (str(a), str(b), str(b - a)) |
501 |
print "De [%s]\n a [%s]\n va [%s]" % (str(c), str(a), str(a - c)) |
print "De [%s]\n a [%s]\n va [%s]" % (str(c), str(a), str(a - c)) |
502 |
|
|
503 |
r = FechaHoraMineRel(signo=1, annos=4, meses=1, dias=40) |
r = FechaHoraMineRel(signo=1, annos=4, meses=1, dias=40) |
504 |
|
|
505 |
print "[%s]\n mas [%s]\n es [%s]" % (str(a), str(r), str(a + r)) |
print "[%s]\n mas [%s]\n es [%s]" % (str(a), str(r), str(a + r)) |
506 |
|
|
507 |
while 1: |
while 1: |
508 |
ahora = FechaHoraMine_ahora() |
ahora = FechaHoraMine_ahora() |
509 |
print "%s (%s)" % (ahora, ahora.desc_seccion()) |
print "%s (%s)" % (ahora, ahora.desc_seccion()) |
510 |
sleep(1) |
sleep(1) |
511 |
|
|