Thread: [Pymoul-svn] SF.net SVN: pymoul: [32] pymoul/trunk/src/moul/time
Status: Alpha
Brought to you by:
tiran
From: <ti...@us...> - 2007-01-16 11:13:44
|
Revision: 32 http://pymoul.svn.sourceforge.net/pymoul/?rev=32&view=rev Author: tiran Date: 2007-01-16 03:13:44 -0800 (Tue, 16 Jan 2007) Log Message: ----------- * Created CavernTime calculator class Modified Paths: -------------- pymoul/trunk/src/moul/time/cavern.py pymoul/trunk/src/moul/time/tests/__init__.py Added Paths: ----------- pymoul/trunk/src/moul/time/tests/test_cavern.py Modified: pymoul/trunk/src/moul/time/cavern.py =================================================================== --- pymoul/trunk/src/moul/time/cavern.py 2007-01-16 00:03:34 UTC (rev 31) +++ pymoul/trunk/src/moul/time/cavern.py 2007-01-16 11:13:44 UTC (rev 32) @@ -56,3 +56,107 @@ CAVERN_TZ_NAME = 'US/Mountain' # MDT / MST CAVERN_TZ = timezone(CAVERN_TZ_NAME) +def diffTD(td1, td2): + """Difference of two timedelta objects -> int + + >>> type(diffTD(timedelta(0, 3600), timedelta(0, -3600))) + <type 'int'> + >>> diffTD(timedelta(0, 3600), timedelta(0, -3600)) + 7200 + >>> diffTD(timedelta(0, 3600), timedelta(0, 3600)) + 0 + >>> diffTD(timedelta(0, -3600), timedelta(0, -3600)) + 0 + >>> diffTD(timedelta(0, -7200), timedelta(0, -3600)) + -3600 + >>> diffTD(timedelta(0, -3600), timedelta(0, -7200)) + 3600 + >>> diffTD(timedelta(0, 3600, 1), timedelta(0, -3600)) + Traceback (most recent call last): + ... + ValueError: Can't handle microseconds + """ + if td1.microseconds or td2.microseconds: + raise ValueError("Can't handle microseconds") + return (td1.seconds + 86400 * td1.days) - (td2.seconds + 86400 * td2.days) + +def td2int(td): + """timedelta to int + >>> td2int(timedelta(0, 3600)) + 3600 + >>> td2int(timedelta(0, -3600)) + -3600 + """ + return td.seconds + 86400 * td.days + +class CavernTime(object): + """Cavern time calculator + + Calculates the cavern time and local time based on a given local time + zone. Call a CavernTime object: + + utc + datetime -- Current time in UTC as <datetime> object + cavern + datetime -- Current time in cavern TZ as <datetime> object + tz -- Cavern time zone object + utcoffset -- (hours, fraction) offset from UTC + cavern + datetime -- Current time in local TZ as <datetime> object + tz -- Local time zone object + utcoffset -- (hours, fraction) offset from UTC + + >>> ct = CavernTime(local="Europe/Berlin") + >>> result = ct() + >>> 'utc' in result, 'local' in result, 'cavern' in result + (True, True, True) + >>> coff = result['cavern']['utcoffset'] + >>> coff == (-7, 0.0) or coff == (-8, 0.0) or coff + True + >>> loff = result['local']['utcoffset'] + >>> loff == (1, 0.0) or loff == (2, 0.0) or loff + True + """ + _timezones = TIMEZONE_NAMES + _cavern = CAVERN_TZ + _local = None + + def __init__(self, local): + self.setLocal(local) + + def setLocal(self, local): + """Set local time zone + """ + self._local = timezone(local) + + @property + def timezones(self): + """Available time zones as strings + """ + return self._timezones + + @staticmethod + def _utcnow(): + """Get current time in UTC + """ + return UTC.localize(datetime.utcnow()) + + @staticmethod + def _normalize(tz, utc_dt=None): + """Normalize a datetime object with UTC tz using another tz + """ + if utc_dt is None: + utc_dt = self._utcnow() + return tz.normalize(utc_dt.astimezone(tz)) + + def __call__(self): + now = self._utcnow() + result = {} + for id, tz in (('cavern', self._cavern), ('local', self._local)): + info = result.setdefault(id, {}) + utcoffset = td2int(tz.utcoffset(now)) + info['tz'] = tz + info['utcoffset'] = int(utcoffset/3600), float((utcoffset%3600)/3600.0) + info['datetime'] = self._normalize(tz, now) + result['utc'] = {'datetime' : now} + return result Modified: pymoul/trunk/src/moul/time/tests/__init__.py =================================================================== --- pymoul/trunk/src/moul/time/tests/__init__.py 2007-01-16 00:03:34 UTC (rev 31) +++ pymoul/trunk/src/moul/time/tests/__init__.py 2007-01-16 11:13:44 UTC (rev 32) @@ -1,2 +1,2 @@ -# testing package - +# testing package + Added: pymoul/trunk/src/moul/time/tests/test_cavern.py =================================================================== --- pymoul/trunk/src/moul/time/tests/test_cavern.py (rev 0) +++ pymoul/trunk/src/moul/time/tests/test_cavern.py 2007-01-16 11:13:44 UTC (rev 32) @@ -0,0 +1,30 @@ +# pyMoul - Python interface to Myst Online URU Live +# Copyright (C) 2007 Christian Heimes <christian (at) cheimes (dot) de> + +# 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 2 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, write to the Free Software Foundation, Inc., 59 +# Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +"""moul.time.cavern unit tests +""" +import os +import unittest +from doctest import DocTestSuite + +def test_suite(): + return unittest.TestSuite(( + DocTestSuite('moul.time.cavern'), + )) + +if __name__ == '__main__': + unittest.main(defaultTest="test_suite") Property changes on: pymoul/trunk/src/moul/time/tests/test_cavern.py ___________________________________________________________________ Name: svn:eol-style + native This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ti...@us...> - 2007-02-12 16:06:48
|
Revision: 160 http://pymoul.svn.sourceforge.net/pymoul/?rev=160&view=rev Author: tiran Date: 2007-02-12 08:06:42 -0800 (Mon, 12 Feb 2007) Log Message: ----------- Finished D'ni time calculation Modified Paths: -------------- pymoul/trunk/src/moul/time/dni.py Added Paths: ----------- pymoul/trunk/src/moul/time/utils.py Modified: pymoul/trunk/src/moul/time/dni.py =================================================================== --- pymoul/trunk/src/moul/time/dni.py 2007-02-12 13:36:09 UTC (rev 159) +++ pymoul/trunk/src/moul/time/dni.py 2007-02-12 16:06:42 UTC (rev 160) @@ -21,20 +21,43 @@ official sources say that: 00:00:00:00, Leefo 1, 9654 DE = 10:35:18 UTC, April 21, 1998 CE + >>> LEEFO_1_TABLE = [ -... datetime(1998, 4, 21, 10, 35, 18, 0, UTC), -... datetime(1999, 4, 21, 16, 24, 3, 0, UTC), -... datetime(2000, 4, 20, 22, 12, 48, 0, UTC), -... datetime(2001, 4, 21, 4, 1, 33, 0, UTC), -... datetime(2002, 4, 21, 9, 50, 18, 0, UTC), -... datetime(2003, 4, 21, 15, 39, 3, 0, UTC), +... datetime(1998, 4, 21, 10, 35, 18, 0, tzinfo=UTC), +... datetime(1999, 4, 21, 16, 24, 3, 0, tzinfo=UTC), +... datetime(2000, 4, 20, 22, 12, 48, 0, tzinfo=UTC), +... datetime(2001, 4, 21, 4, 1, 33, 0, tzinfo=UTC), +... datetime(2002, 4, 21, 9, 50, 18, 0, tzinfo=UTC), +... datetime(2003, 4, 21, 15, 39, 3, 0, tzinfo=UTC), ... ] +>>> def compareDT(dt1, dt2): +... delta = td2sec(dt1 - dt2) +... # smaller than 5 seconds +... if abs(delta) < 5: +... return True +... else: +... return delta + >>> dni = DniTime() >>> dni.fromUTC(LEEFO_1_TABLE[1]) >>> dni.get() -(9655, 0, 0, 0, 0, 0, 0) +(9655, 1, 1, 0, 0, 0, 0) +>>> str(dni) +'00:00:00:00, Leefo 1, 9655' +>>> compareDT(dni.toUTC(), LEEFO_1_TABLE[1]) +True +>>> other = datetime(2007, 2, 12, 13, 55, 10, 0, tzinfo=UTC) +>>> dni.fromUTC(other) +>>> dni.get() +(9662, 9, 4, 4, 21, 24, 21) +>>> str(dni) +'04:21:24:21, Leevotar 4, 9662' + +>>> compareDT(dni.toUTC(), other) +True + """ __author__ = "Christian Heimes" __version__ = "$Id$" @@ -43,6 +66,7 @@ from datetime import datetime from operator import mul from pytz import utc as UTC +from time import mktime import sys from moul.time.utils import td2sec @@ -79,12 +103,16 @@ ) # 00:00:00:00, Leefo 1, 9654 DE -BASE = datetime(1998, 4, 21, 10, 35, 18, 0, UTC) +BASE = datetime(1998, 4, 21, 10, 35, 18, 0, tzinfo=UTC) +# timestamp 0 - start of unix time +UNIX_0 = datetime(1970, 1, 1, 0, 0, 0, 0, tzinfo=UTC) +BASE_SEC = td2sec(BASE-UNIX_0) # WTF? datetime has no totimestamp() method BASE_HAHR = 9654 +BASE_YEAR = 1998 SECONDS_PER_HAHR = 31556925 PRORAHN_PER_HAHR = 22656250 -FACTOR_SH = float(SECONDS_PER_HAHR) / float(PRORAHN_PER_HAHR) -FACTOR_HS = float(PRORAHN_PER_HAHR) / float(SECONDS_PER_HAHR) +FACTOR_SP = float(SECONDS_PER_HAHR) / float(PRORAHN_PER_HAHR) +FACTOR_PS = float(PRORAHN_PER_HAHR) / float(SECONDS_PER_HAHR) def valueCheck(typ, minv, maxv): """Value and type checking decorator @@ -157,14 +185,25 @@ if utc_dt is None: utc_dt = utcnow() sec = td2sec(utc_dt - BASE) - prorahn = sec * FACTOR_HS + prorahn = int(sec * FACTOR_PS) self.set(hahr=BASE_HAHR, prorahn=prorahn) def toUTC(self): """Convert to UTC datetime value """ - raise NotImplementedError + hahr_sec = (self.hahr - BASE_HAHR) * SECONDS_PER_HAHR + prorahn_sec = int(self._prorahn * FACTOR_SP) + sec = hahr_sec + BASE_SEC + prorahn_sec + return UTC.localize(datetime.utcfromtimestamp(sec)) + def __str__(self): + """00:00:00:00, Leefo 1, 9654 + """ + return ("%02i:%02i:%02i:%02i, %s %i, %i" % ( + self.gahrtahvo, self.tahvo, self.gorahn, self.prorahn, + self.getVaileeName(), self.yahr, self.hahr + )) + def _getHahr(self): return self._hahr @valueCheck(int, 0, sys.maxint) @@ -173,42 +212,42 @@ hahr = property(_getHahr, _setHahr) def _getVailee(self): - return self._prorahn // 2265625 + return ((self._prorahn // 2265625) % 10) +1 @valueCheck(int, 0, 10) def _setVailee(self, value): self._addProrahn(value * 2265625) vailee = property(_getVailee, _setVailee) def getVaileeName(self): - return VAILEETEE[self.vailee] + return VAILEETEE[self.vailee-1] def _getYahr(self): - return self._prorahn // 78125 + return ((self._prorahn // 78125) % 29) +1 @valueCheck(int, 0, 29) def _setYahr(self, value): self._addProrahn(value * 78125) yahr = property(_getYahr, _setYahr) def _getBell(self): - return self.gahrtahvo // 5 + return (self.gahrtahvo // 5) % 25 bell = property(_getBell) def _getGahrtahvo(self): - return self._prorahn // 15625 + return (self._prorahn // 15625) % 5 @valueCheck(int, 0, 5) def _setGahrtahvo(self, value): self._addProrahn(value * 15625) gahrtahvo = property(_getGahrtahvo, _setGahrtahvo) def _getTahvo(self): - return self._prorahn // 625 + return (self._prorahn // 625) % 25 @valueCheck(int, 0, 25) def _setTahvo(self, value): self._addProrahn(value * 625) tahvo = property(_getTahvo, _setTahvo) def _getGorahn(self): - return self._prorahn // 25 + return (self._prorahn // 25) % 25 @valueCheck(int, 0, 25) def _setGorahn(self, value): self._addProrahn(value * 25) @@ -222,7 +261,9 @@ prorahn = property(_getProrahn, _setProrahn) def _addProrahn(self, value): - self._prorahn += int(value) - addhahr = self._prorahn // PRORAHN_PER_HAHR + value = int(value) + addhahr = value // PRORAHN_PER_HAHR if addhahr: self._hahr += addhahr + value = value - (addhahr * PRORAHN_PER_HAHR) + self._prorahn = value Added: pymoul/trunk/src/moul/time/utils.py =================================================================== --- pymoul/trunk/src/moul/time/utils.py (rev 0) +++ pymoul/trunk/src/moul/time/utils.py 2007-02-12 16:06:42 UTC (rev 160) @@ -0,0 +1,74 @@ +# pyMoul - Python interface to Myst Online URU Live +# Copyright (C) 2007 Christian Heimes <christian (at) cheimes (dot) de> + +# 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 2 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, write to the Free Software Foundation, Inc., 59 +# Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +"""pyMoul cavern time tool +""" +__author__ = "Christian Heimes" +__version__ = "$Id: cavern.py 124 2007-02-02 17:45:42Z tiran $" +__revision__ = "$Revision: 124 $" + +from datetime import datetime +from pytz import utc as UTC + + +def diffTD(td1, td2): + """Difference of two time delta objects -> int + + >>> from datetime import timedelta + >>> type(diffTD(timedelta(0, 3600), timedelta(0, -3600))) + <type 'int'> + >>> diffTD(timedelta(0, 3600), timedelta(0, -3600)) + 7200 + >>> diffTD(timedelta(0, 3600), timedelta(0, 3600)) + 0 + >>> diffTD(timedelta(0, -3600), timedelta(0, -3600)) + 0 + >>> diffTD(timedelta(0, -7200), timedelta(0, -3600)) + -3600 + >>> diffTD(timedelta(0, -3600), timedelta(0, -7200)) + 3600 + >>> diffTD(timedelta(0, 3600, 1), timedelta(0, -3600)) + Traceback (most recent call last): + ... + ValueError: Can't handle microseconds + """ + if td1.microseconds or td2.microseconds: + raise ValueError("Can't handle microseconds") + return (td1.seconds + 86400 * td1.days) - (td2.seconds + 86400 * td2.days) + +def td2sec(td): + """timedelta to seconds + + >>> from datetime import timedelta + >>> td2sec(timedelta(0, 3600)) + 3600 + >>> td2sec(timedelta(0, -3600)) + -3600 + """ + return td.seconds + 86400 * td.days + +def utcnow(): + """Get current time in UTC + """ + return UTC.localize(datetime.utcnow()) + +def normalizeTZ(tz, utc_dt=None): + """Normalize a datetime object with UTC tz using another tz + """ + if utc_dt is None: + utc_dt = utcnow() + return tz.normalize(utc_dt.astimezone(tz)) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ti...@us...> - 2007-03-08 12:57:43
|
Revision: 243 http://pymoul.svn.sourceforge.net/pymoul/?rev=243&view=rev Author: tiran Date: 2007-03-08 04:57:43 -0800 (Thu, 08 Mar 2007) Log Message: ----------- Added unit tests for gira More implementation details Modified Paths: -------------- pymoul/trunk/src/moul/time/edergira.py Added Paths: ----------- pymoul/trunk/src/moul/time/tests/test_edergira.py Modified: pymoul/trunk/src/moul/time/edergira.py =================================================================== --- pymoul/trunk/src/moul/time/edergira.py 2007-03-08 02:42:59 UTC (rev 242) +++ pymoul/trunk/src/moul/time/edergira.py 2007-03-08 12:57:43 UTC (rev 243) @@ -18,12 +18,19 @@ """pyMoul Ede Gira day cycle Based on BrettM's information + +>>> from pytz import timezone +>>> MST = timezone('MST') +>>> sunset = datetime(2007, 3, 8, 4, 30, 0, tzinfo=MST) +>>> egdc = EderGiraDayCalculator() +>>> eg = egdc.getDayInfo(sunset) +>>> eg.state, eg.light, eg.hour +(<dusk>, 0.75, 7.25) """ __author__ = "Christian Heimes" __version__ = "$Id" __revision__ = "$Revision" - from datetime import datetime from datetime import timedelta @@ -31,11 +38,136 @@ from moul.time.utils import td2sec from moul.time.utils import utcnow -delta = timedelta(days=0, hours=10, minutes=0) # 10h -base_dt = datetime(2007, 3, 8, 9, 15, 0) # noon +class Invariant(object): + __slots__ = ('_var',) + def __new__(cls, var): + self = object.__new__(cls) + if not isinstance(var, basestring): + raise TypeError(type(var)) + self._var = var + return self + + def __repr__(self): + return '<%s>' % self._var + + def __str__(self): + return str(self._var) + + def __unicode__(self): + return unicode(self._var) + +NIGHT = Invariant('night') +DAWN = Invariant('dawn') +DAY = Invariant('day') +DUSK = Invariant('dusk') + +class EderGiraDayCalculator(object): + """Eder Gira day cycle calculator + """ + def __init__(self): + self._basedt = datetime(2007, 3, 8, 4, 15, 0, tzinfo=UTC) # midnight + self._hours = 10 + self._delta = timedelta(days=0, hours=self._hours) + self._deltasec = self._hours * 3600 + + def getLastMidnight(self, dt=None): + """Get last midnight in relation to dt (or now) + """ + if dt is None: + dt = utcnow() + cycles = td2sec(dt - self._basedt) / self._deltasec + return self._basedt + (int(cycles) * self._delta) + + def getDayInfo(self, dt=None): + """Get day info object for dt (or now) + """ + if dt is None: + dt = utcnow() + sec = td2sec(dt - self._basedt) + return EderGiraDay(round(sec / 3600.0, 2) % self._hours) + class EderGiraDay(object): - """Eder Gira day cycle class + """An Eder Gira day representation + + >>> eg = EderGiraDay(1.25) + >>> eg.state, eg.light, eg.hour + (<night>, 0.0, 1.25) + >>> int(eg) + 1 + >>> float(eg) + 1.25 + + >>> eg = EderGiraDay(2.5) + >>> eg.state, eg.light, eg.hour + (<dawn>, 0.5, 2.5) + + >>> eg = EderGiraDay(5.0) + >>> eg.state, eg.light, eg.hour + (<day>, 1.0, 5.0) + + >>> eg = EderGiraDay(7.875) + >>> eg.state, eg.light, eg.hour + (<dusk>, 0.13, 7.875) + + >>> eg = EderGiraDay(9.5) + >>> eg.state, eg.light, eg.hour + (<night>, 0.0, 9.5) + + >>> eg = EderGiraDay(10.0) + Traceback (most recent call last): + ... + ValueError: 10.0 """ - def __init__(self): - pass + def __init__(self, eghour): + if not 0 <= eghour < 10: + raise ValueError(eghour) + self._eghour = eghour + + @property + def state(self): + """State: night, dawn, day, dusk + """ + eg = self._eghour + if eg < 2.0: + return NIGHT + elif 2.0 <= eg < 3.0: + return DAWN + elif 3.0 <= eg < 7.0: + return DAY + elif 7.0 <= eg < 8.0: + return DUSK + elif 8.0 <= eg < 10: + return NIGHT + else: + raise ValueError(eg) + + @property + def light(self): + """Light level between 0.0 and 1.0 + """ + state = self.state + if state is NIGHT: + return 0.0 + elif state is DAWN: + level = self._eghour % 1 + return round(level, 2) + elif state is DAY: + return 1.0 + elif state is DUSK: + level = self._eghour % 1 + return round(1-level, 2) + else: + raise ValueError(state) + + @property + def hour(self): + """Hour between 0.00 and 9.99 + """ + return self._eghour + + def __int__(self): + return int(self._eghour) + + def __float__(self): + return float(self._eghour) Added: pymoul/trunk/src/moul/time/tests/test_edergira.py =================================================================== --- pymoul/trunk/src/moul/time/tests/test_edergira.py (rev 0) +++ pymoul/trunk/src/moul/time/tests/test_edergira.py 2007-03-08 12:57:43 UTC (rev 243) @@ -0,0 +1,37 @@ +# pyMoul - Python interface to Myst Online URU Live +# Copyright (C) 2007 Christian Heimes <christian (at) cheimes (dot) de> + +# 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 2 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, write to the Free Software Foundation, Inc., 59 +# Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +"""moul.time.edergira unit tests +""" +__author__ = "Christian Heimes" +__version__ = "$Id: test_dni.py 122 2007-02-02 17:34:06Z tiran $" +__revision__ = "$Revision: 122 $" + +import os +import unittest +from doctest import DocTestSuite + +import moul.time.edergira + + +def test_suite(): + return unittest.TestSuite(( + DocTestSuite('moul.time.edergira'), + )) + +if __name__ == '__main__': + unittest.main(defaultTest="test_suite") Property changes on: pymoul/trunk/src/moul/time/tests/test_edergira.py ___________________________________________________________________ Name: svn:keywords + 'Id Revision' Name: svn:eol-style + native This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |