Interface ( DateTime : DateTimeDelta : RelativeDateTime : Constants : Functions ) : Arithmetic : Submodules ( ISO : ARPA : Feasts : Parser : NIST ) : Examples : C API : Structure : Download & Installation : Support : Copyright : History : Home | Version 1.3.0 |
These types were created to provide a consistent way of transferring date and time data between Python and databases. Apart from handling date before the Unix epoch (1.1.1970) they also correctly work with dates beyond the Unix time limit (currently with Unix time value being encoded using 32bit integers, the limit is reached in 2038) and thus is Year 2000 and Year 2038 safe.
After some discussions on the db-sig list about what the date type DateTime should be capable of doing and what not, we decided to use the following internal format:
The Epoch used by the module is January 1st of the year 1 at midnight (0:00:00.00) in the Gregorian calendar. This date corresponds to absolute day 1 and absolute time 0. Dates before the Epoch are handled by extrapolating the calendars using negative years as basis (the year 1 BCE corresponds to the year 0, 2 BCE is represented as year -1 and so on).
For the purpose of storing absolute time values and time spans, the package provides a second type called DateTimeDelta. The internal representation for this type is seconds and stored in a signed C double.
As of version 0.9.1, a third object type is available: RelativeDateTime. This object is currently implemented in Python and may be used to store relative time deltas (see below for an exact description). It's main purpose is providing an intuitive way to calculate e.g. the "first of next month".
Designing the types wasn't as easy as expected, since many criteria had to be taken into account. Here are some of them and their implementation:
Time zones are among the most difficult to handle issues when it comes to implementing and using types for date and time. We chose to move the time zone handling functionality out of the C implementation and into Python. This means that the types know nothing about the time zones of the values they store and calculations are done using the raw data.
If you need to store and use these informations in calculations, you can "subclass" the types to implement your ideas rather than having to stick to what the C implementation defines. The included ODMG submodule is an example of how this can be done.
Leap seconds are not supported either. You can implement classes respecting these by "subclassing" DateTime and DateTimeDelta and then overriding the calculation methods with methods that work on Unix ticks values (if the underlying C lib knows about leap seconds).
The module supports two calendars, the Gregorian (default and needed for most conversions) and the Julian, which is handy for dates prior to the Epoch.
Construction of Julian dates can be done using either the
JulianDateTime()
constructor or indirect through
the .Julian()
method of DateTime instances. To
check which calendar a DateTime instance uses, query the
calendar
instance attribute.
Note that Julian dates output the Julian date through the instances date attributes and broken down values. Not all conversions are available on instances using the Julian calendar.
Even though in the Julian calendar days start at noon (12:00:00.0), mxDateTime will use the Gregorian convention of using the date for the period from 00:00:00.0 to 23:59:59.99 of that day. (This may change in future versions, though.)
For the purpose of converting the stored values to Unix ticks (number of seconds since the Unix epoch; the C lib also uses this representation) we assume that the values are given in local time. This assumption had to be made because the C lib provides no standard way to convert a broken down date/time value in any other way into a ticks value.
Conversions to COM dates and tuples are done without any assumption on the time zone. The raw values are used.
Conversion from other formats to DateTime instances is always done by first calculating the corresponding absolute time and date values (which are also used as basis for calculations).
The internal representation of date/times behaves much like
floats do in Python, i.e. rounding errors can occur when
doing calculations. There is a special compare function included
(cmp()
) in the package that allows you to compare
two date/time values using a given accuracy,
e.g. cmp(date1,date2,0.5)
will allow 12:00:00.5 and
12:00:01.0 to compare equal.
Special care has been taken to prevent these rounding errors from occurring for COM dates. If you create a DateTime instance using a COM date, then the value returned by the .COMDate() method is guaranteed to be exactly the same as the one used for creation. The same is true for creation using absolute time and absolute date and broken down values.
One other thing to keep in mind when working with DateTime and DateTimeDelta instances is that they are immutable (like tuples). Once an instance is created you can not change its value. Instead, you will have to create a new instance with modified values. The advantage of having immutable objects is that they can be used as dictionary keys.
DateTime and DateTimeDelta instances can be compared and hashed, making them compatible to the dictionary implementation Python uses (they can be used as keys). The copy protocol, simple arithmetic and pickleing are also supported (ee below for details).
DateTime and DateTimeDelta instances know how to output
themselves as ISO8601-strings. The format is very simple:
YYYY-MM-DD HH:MM:SS.ss for DateTime instances and
[-][DD:]HH:MM:SS.ss for DateTimeDelta instances (the DD-part
(days) is only given if the absolute delta value is greater than
24 hours). Customized conversion to strings can be done using
the strftime
-methods or the included submodules.
String parsing is supported through the strptime()
constructor which implements a very strict parsing scheme and
the included submodules (e.g. ISO and ARPA), which allow a little more freedom.
Comparing the types to time-module based routines is not really possible, since the used strategies differ. You can compare them to tuple-based date/time classes though: DateTime[Delta] are much faster on creation, use less storage and are faster to convert to the supported other formats than any equivalent tuple-based implementation written in Python.
Creation of time-module values using time.mktime() is much slower than doing the same thing with DateTime(). The same holds for the reverse conversion (using time.localtime()).
The storage size of ticks (floats, which the time module uses) is about 1/3 of the size a DateTime instance uses. This is mainly due to the fact that DateTime instances cache the broken down values for fast access.
To summarize: DateTime[Delta] are faster, but also use more memory than traditional time-module based techniques.
Here is a small list of links I used as starting points to find some of the date/time related information included in this package:
The package provides three data structures for working with date and time values. These are:
Several constructors are available in the module DateTime. All of these return DateTime instances using the Gregorian calendar except for JulienDateTime() which returns instances using the Julian calendar.
DateTime(year,month=1,day=1,hour=0,minute=0,second=0.0)
Assumes that the date is given in the Gregorian calendar (which it the one used in many countries today).
The entry for day
can be negative to
indicate days counted in reverse order, that is the last
day becomes -1, the day before that -2, and so on,
e.g. DateTime(1997,12,-2)
gives the
30.12.1997 (this is useful especially for months).
Note that although the above makes it look like this function can handle keywords, it currently cannot.
JulianDateTime(year,month=1,day=1,hour=0,minute=0,second=0.0)
The instance will use the Julian calendar for all date
related methods and attributes. It's
calendar
attribute will return
'Julian'.
Same comments as for DateTime().
JulianDate(year,month=1,day=1)
Timestamp(year,month,day,hour=0,minute=0,second=0.0)
Date(year,month,day)
mktime(year,month,day,hour,minute,second,dow,doy,dst)
Note that the arguments
dow
,doy
and dst
are not used in any way.
You should only use this contructor for porting applications from time module based functions to DateTime.
DateTimeFromAbsDateTime(absdate,abstime)
This interface can be used by classes written in Python which implement other calendars than the Gregorian, for example.
localtime(ticks)
The instance will hold the associated local time.
now()
gmtime(ticks=time.time())
The instance will hold the associated UTC time. If
ticks is not given, the current time is
used. gmticks()
is the inverse of this
function.
utctime(ticks=time.time())
gmtime()
.
today(hour=0,minute=0,second=0.0)
DateTimeFromAbsDays(days)
DateTimeFromCOMDate(comdate)
This is used in the COM mechanism I'm told and repesents the date/time difference between 30.12.1899 and the represented date/time, with time being encoded as fraction of a whole day, thus 0.5 corresponds to 12:00:00.00.
Special care is taken that the resulting instance's
method COMDate()
returns exactly the same
value as the one used for constructing it -- even though
the internal representation is more accurate.
strptime(string,format_string[,default])
If default is given (must be a DateTime instance), it's
entries are used as default values. Otherwise,
01.01.0001 0:00:00.00 is used. An Error
is
raised if the underlying C parsing function
strptime()
fails.
Note: Since this C API is relatively new, you may not have access to this constructor on your platform. For further information on the format, please refer to the Unix manpage (it is very similar to that of strftime() which is documented in the Python library reference for the time module).
DateTimeFromMJD(mjd)
Since MJD values are given in UTC, the instance will represent UTC. See the Calendar FAQ for details.
Note: Usage of MJD notation is discouraged by the International Astronomical Union (IAU). Use JDN instead.
DateTimeFromTJD(tjd,tjd_myriad=current_myriad)
tjd_myriad will default to the tjd_myriad current at package import time, if not given. It refers to the truncated part of the TDJ number. The current myriad (245) started on 1995-10-10 00:00:00.00 UTC and will last until 2023-02-24 23:59:59.99 UTC.
Since TJD values are always given in UTC, the instance will represent UTC.
Please note that usage of TJD is depreciated because of the information loss involved with truncating data: use MJD or JDN instead.
DateTimeFromJDN(jdn)
Since JDN values are given in UTC, the instance will represent UTC. See the Calendar FAQ for details.
DateTimeFrom(*args,**kws)
This constructor can parser strings, handle numeric
arguments and knows about the keywords
year,month,day,hour,minute,second
.
It is still to be considered experimental with semantics defined by implementation.
The exact interface remains to be defined. The constructor analyses the number and types of the arguments and then passes control on to the more specific constructors.
Uses the new Parser module for parsing date/time strings.
TimestampFrom(*args,**kws)
DateFromTicks(ticks)
TimestampFromTicks(ticks)
A DateTime instance has the following methods. Note that the calendar setting of the instance effects all methods relying on date values.
tuple()
DST is set assuming local time. It can also be -1, meaning that the information is not available.
absvalues()
(absdate,
abstime)
.
ticks(offset=0.0,dst=-1)
The conversion routine assumes that the stored date/time value is given in local time.
The given value for DST is used by the conversion (0 = DST off, 1 = DST on, -1 = unkown) and offset is subtracted from the resulting value.
The method raises a RangeError
exception if
the objects value does not fit into the system's ticks
range.
Note: On some platforms the C lib's mktime()
function that this method uses does not allow setting
DST to an arbitrary value. The module checks for this
and raises a SystemError
in case setting
DST to 0 or 1 does not result in valid results.
gmticks(offset=0.0)
The conversion routine assumes that the stored date/time value is given in UTC time. offset is subtracted from the resulting value.
The method raises an RangeError
exception if the objects value does not fit into the
system's ticks range.
gmtoffset()
The UTC offset is defined as: local time - UTC time, e.g. it is negative in the US and positive in eastern Europe and Asia.
COMDate()
strftime(format_string="%c")
This is the same function as the one in the time module. For further information please refer to the manpage or the Python reference manual.
Note: strftime() and strptime() try to be the inverse of each other. The output from strftime() given to strptime() together with the format string passed to strftime() will in most cases give you a DateTime instance referring to the same date and time.
Time zone information is not available. Use the
instance variable tz
instead.
Format(format_string="%c")
Gregorian()
Julian()
To make life easier, the instances also provide a more direct interface to their stored values (these are all read-only). Note that the calendar setting of the instance effects all attributes referring to date values.
hour, minute, second
Note that in a future release, leap seconds may also be considered and thus second has a range of 0-60.
year, month, day
dst
The value is calculated assuming that the stored value is local time.
tz
day_of_week
day_of_year
days_in_month
iso_week
Note: isoday 1 is Monday !
is_leapyear
yearoffset
absdays
The value is calculated using a 86400.0 seconds/day basis and does not account for leap seconds. This value is handy if you need the date/time value stored in one number. By using a Python float, which is mapped to a C double internally, the accuracy should give a fairly large range of valid dates.
absdate
abstime
mjd
It is assumed for the calculation that the stored value is given in UTC. Fractions indicate parts of the full day, e.g. 0.5 referrs to noon on the 17 November 1858.
See the Calendar FAQ or Systems of Time for details.
Note: Usage of MJD notation is discouraged by the International Astronomical Union (IAU). Use JDN instead.
tjd
TJDs are calculated using 00:00 UTC on 1 January 4713 BC
as epoch, counting the number of days as for the Julian
Day Numbers and then omitting the myriad part (div
10000) from it. As a result the TJD will always have at
most 4 digits. The divisor is available through the
tjd_myriad
attribute.
It is assumed for the calculation that the stored value is given in UTC. Fractions indicate parts of the full day.
Some people claim that this term is also known under the name Star Date. Remember ? ... "Captain's Log, Star Date 8143.65". I wonder which myriad these dates refer to.
tjd_myriad
jdn
It is assumed for the calculation that the stored value is given in UTC. Fractions indicate parts of the full day, e.g. JDN 2451170.17393 referrs to Tue, 22 Dec 1998 16:10:27 UTC.
See the Calendar FAQ for details.
calendar
Several constructors are available:
DateTimeDelta(delta_days,delta_seconds=0.0)
The internal value is calculated using the formula
86400.0*delta_days + delta_seconds
. Keep
this in mind when passing negative values to the
constructor.
TimeDelta(hour=0.0,minute=0.0,second=0.0)
The internal value is calculated using the formula
hours * 3600 + minutes * 60 + seconds
. Keep
this in mind when passing negative values to the
constructor.
The constructor allows usage of keywords, e.g. Time(seconds=1.5) works.
Time(hour,minute=0.0,second=0.0)
DateTimeDeltaFromSeconds(seconds)
DateTimeDeltaFromDays(days)
The internal value is calculated using a 86400.0 seconds/day basis.
DateTimeDeltaFrom(*args,**kws)
This constructor can parser strings, handle numeric
arguments and knows about the keywords
year,month,day,hour,minute,second
.
It is still to be considered experimental with semantics defined by implementation.
The exact interface remains to be defined. The constructor analyses the number and types of the arguments and then passes control on to the more specific constructors.
Uses the new Parser module for parsing date/time strings.
TimeDeltaFrom(*args,**kws)
The interface is the same as for DateTimeDeltaFrom() with the exception that numeric arguments are interpreted without day part as for the TimeDelta() constructor.
TimeFrom(*args,**kws)
TimeFromTicks(ticks)
A DateTimeDelta instance has the following methods:
absvalues()
(absdays, absseconds)
tuple.
The absseconds
part is normalized in such
way that it is always smaller than 86400.0. Both values
are signed.
tuple()
The values are the same those returned by the attributes of the same name.
strftime(format_string)
This is the same function as the one in the time module. For further information please refer to the manpage or the Python reference manual.
Since some descriptors don't make any sense for
date/time deltas these return undefined values. Only the
fields hour, minute, seconds and day are set according
to the objects value (the descriptors %d %H %M %S
%I %p %X
work as expected).
Negative values show up positive -- you'll have to
provide your own way of showing the sign (the
seconds
instance variable is signed).
To make life easier, the instances also provide a more direct interface to their stored values (these are all read-only):
day, hour, minute, second
days, hours, minutes, seconds
TimeDelta(12,00,00).days ==
0.5
.
These constructors are avaiable:
RelativeDateTime(years=0,months=0,days=0,
year=0,month=0,day=0,
hours=0,minutes=0,seconds=0,
hour=None,minute=None,second=None,
weekday=None,weeks=0)
The constructor handles keywords, so you'll only have to give those parameters which should be changed when you add the relative to an absolute DateTime instance.
Do not pass arguments directly, always use the keyword notation !
Absolute values passed to the constructor will override
delta values of the same type. Note that
weeks
is added to days
so that
the instances days values will be days +
7*weeks
.
weekday must be a 2-tuple if given: (day_of_week, nth). The value is applied after all other calculations have been done resulting in moving the date to the nth weekday in the month that the date points to. Negative values for nth result in the ordering of the month's weekdays to be reversed, e.g. (Monday,-1) will move to the last Monday in that month. Setting nth to 0 results in the date's week to be used as reference, e.g (Tuesday,0) will move to Tuesday that week (which could lie in a different month). weekday is considered an absolute value, so multiplication or negation will not touch it.
RelativeDate(years=0,months=0,days=0,year=0,month=0,day=0,
weeks=0)
RelativeDateTimeDiff(date1,date2)
date2 +
RelativeDateDiff(date1,date2) == date1
for all dates date1 and date2.
Note that due to the algorithm used by this function, not the whole range of DateTime instances is supported; there could also be a loss of precision
This constructor is still experimental. It is not fully debugged yet.
RelativeDateDiff(date1,date2)
Age(date1,date2)
RelativeDateTime objects store the given settings (plural nouns meaning deltas, singular nouns absolute values) and apply them when used in calculations. Delta values will have the effect of changing the corresponding attribute of the involved absolute DateTime object accordingly, while absolute values overwrite the DateTime objects attribute value with a new one. The effective value of the object is thus determined at calculation time and depends on the context it is used in.
Adding and subtracting RelativeDateTime instances is supported with the following rules: deltas will be added together and right side absolute values override left side ones.
Multiplying RelativeDateTime instances with numbers will yield instances with scaled deltas (absolute values are not effected).
Adding RelativeDateTime instances to and subtracting
RelativeDateTime instances from DateTime instances will
return DateTime instances with the appropriate calculations
applied, e.g. to get a DateTime instance for the first of
next month, you'd call now() +
RelativeDateTime(months=+1, day=01)
.
Note that dates like Date(1999,1,30) +
RelativeDateTime(months=+1)
are not supported. The
package currently interprets these constructions as
Date(1999,2,1) + 30
, thus giving the 1999-03-02
which may not be what you'd expect.
When providing both delta and absolute values for an entity the absolute value is set first and then the delta applied to the outcome.
A few examples will probably make the intended usage clearer:
>>> from DateTime import * >>> print now() 1998-08-11 16:46:02.20 # add one month >>> print now() + RelativeDateTime(months=+1) 1998-09-11 16:46:24.59 # add ten months >>> print now() + RelativeDateTime(months=+10) 1999-06-11 16:47:03.07 # ten days from now >>> print now() + RelativeDateTime(days=+10) 1998-08-21 16:47:10.58 # first of next month >>> print now() + RelativeDateTime(months=+1,day=1) 1998-09-01 16:47:25.15 # first of this month, same time >>> print now() + RelativeDateTime(day=1) 1998-08-01 16:47:35.48 # first of this month at midnight >>> print now() + RelativeDateTime(day=1,hour=0,minute=0,second=0) 1998-08-01 00:00:00.00 # next year, first of previous month, same time >>> print now() + RelativeDateTime(years=+1,months=-1,day=1) 1999-07-01 16:48:31.87 # Last Sunday in October 1998 >>> print Date(1998) + RelativeDateTime(weekday=(Sunday,-1),month=10) 1998-10-25 00:00:00.00 # The result in ARPA notation: >>> print ARPA.str(Date(1998) + RelativeDateTime(weekday=(Sunday,-1),month=10)) Sun, 25 Oct 1998 00:00:00 +0200 # Generic way of specifying "next tuesday": >>> NextTuesday = RelativeDateTime(days=+6,weekday=(Tuesday,0))
RelativeDateTime instances currently don't have any instance methods.
The following attributes are exposed, but should not be written to directly (the objects are currently implemented in Python, but that could change in future releases).
year, month, day, hour, minute, second, weekday
years, months, days, hours, minutes, seconds
The given values are only defined in case they were set at instance creation time.
The package defines these constants:
oneWeek, oneDay, oneHour, oneMinute, oneSecond
Error, RangeError
DateTimeType, DateTimeDelta
Epoch
mxDateTimeAPI
MaxDateTime, MinDateTime, MaxDateTimeDelta,
MinDateTimeDelta
Monday, Tuesday, Wednesday,
Thursday, Friday, Saturday, Sunday
Weekday
January, February, March,
April, May, June, July, August, September, October,
November, December
Month
The package defines these additional functions:
cmp(obj1,obj2,accuracy=0.0)
If accuracy is given, then equality will result in case the absolute difference between the two values is less than or equal to accuracy.
gmticks(datetime)
DEPRECIATED: Use the .gmticks() method instead.
utcticks(datetime)
gmticks()
.
DEPRECIATED: Use the .gmticks() method instead.
tz_offset(datetime)
DEPRECIATED: Use the .gmtoffset() method instead.
gm2local(datetime)
utc2local(datetime)
gm2local()
.
local2gm(datetime)
local2utc(datetime)
local2gm()
.
If you find any bugs, please report them to me so that I can fix them for the next release.
The three objects DateTime, DateTimeDelta and
RelativeDateTime can be used to do simple date/time
arithmetic. Addition and subtraction are supported and
result in the expected results. In addition to handling
arithmetic using only the two types, mixed arithmetic with
numbers is also understood to a certain extent:
No operations defined.
Notes:
Operation and argument order are important because of the
different ways arguments are coerced. Use parenthesis to
make your intent clear or you will get unwanted results.
Due to a flaw in the C interface for coercion in the
interpreter, it is not possible to do proper handling of
mixed type arithmetic for types which don't coerce to a
common type (without creating temporary objets all the
time). The module uses a workaround, but unfortunately the
order of the operands is lost along the way. Under normal
circumstances you won't notice this defect, but be warned
since e.g.
Comparing RelativeDateTime instances does not work.
Adding/Subtracting DateTime instances causes the result to
inherit the calendar of the left operand.
The package provides additional features in form of the
following submodules. All submodules are imported on request
only.
The ISO submodule is intended to provide interfacing
functions to ISO 8601
date and time representations (the ISO document is also
available as PDF file).
The most common format is:
YYYY-MM-DD HH:MM:SS[+-HH:MM]
Note: timezone information (+-HH:MM) is only
interpreted by the
You can access the functions and symbols defined in the
submodule through
The module defines these constructors and functions:
A time part is optional and must be delimited from the
date by a space or 'T'. Year must be given, month and
day default to 1. For the time part, hour and minute
must be given, while second defaults to 0.
Time zone information is parsed, but not evaluated.
Note: UTC is practically the same as GMT, the old time
standard.
Note: UTC is practically the same as GMT, the old time
standard.
The parsing routines strip surrounding whitespace from the
strings, but are strict in what they want to see. Additional
characters are not allowed and will cause a
Timezone information may be included, but will not be
interpreted unless explicitly stated.
The parsing routines also understand the ISO 8601 date/time
formats without seperating dashes and colons,
e.g. '19980102T142020', and mixtures of both notations.
DateTime and DateTimeDelta instances use a slightly enhanced ISO
format for string represenation:
DateTime instances are converted to
DateTimeDelta instances use
The ARPA submodule is intended to provide interfacing
functions to ARPA date representations. These are used throughout
the Internet for passing around mails, postings, etc. The
format is very simple:
[Day, ]DD Mon YYYY HH:MM[:SS] ZONE
where ZONE can be one of these: MDT, O, EDT, X, Y,
CDT, UT, AST, GMT, PST, Z, V, CST, ADT, I, W, T, U, R, S, P,
Q, N, EST, L, M, MST, K, H, E, F, G, D, PDT, B, C, UTC, A
(the single letter ones being military
time zones). Use of explicit time zone names other than
UTC and GMT is depreciated, though. The better alternative
is providing the offset from UTC being in effect at the
given local time: +-HHMM (this is the offset you
have to subtract from the given time in order to get UTC).
You can access the functions and symbols defined in the
submodule through
The module defines these constructors and functions:
Note: Most Internet software expects to find
'GMT' and not 'UTC'.
The parsing routines strip surrounding whitespace from the
strings. Additional characters are allowed (because some
mail apps add extra information to the date header).
The Feasts submodule is intended to provide easy-to-use
constructors for common moveable christian feasts that can
be deduced from the date of Easter Sunday.
The algorithm used to calculate Easter Sunday is based on
the one presented in the Calendar
FAQ by Claus Tondering, which in return is based on the
algorithm of Oudin (1940) as quoted in "Explanatory
Supplement to the Astronomical Almanac", P. Kenneth
Seidelmann, editor.
The module defines these constructors and functions:
The other feasts are deduced from this date and all use the
same interface. The module defines these sets of
constructors the return the corresponding DateTime instance
for midnight of the implied day:
For further reading, have a look at the Ecclesiastical
Calendar.
The Parser submodule provides constructors for DateTime[Delta]
values taking a string as input. The module knows about quite
a few different date and time formats and will try very hard to
come up with a reasonable output given a valid input.
Date/time parsing is a very diffcult field of endeavour and
that's why the exact definition of what the module can parse
and what not is defined by implementation rather than a
rigorous set of formats.
Note: The module still has prototype
status. It is constantly being improved. This can also
mean that some formats might be dropped again in favour of
more general parsing regexps.
Things the module will recognize are the outputs of ISO,
ARPA and the .strftime() method. Currently only English
month and day names are supported.
The module defines these constructors and functions:
Inserts default values for missing parts. Default is
today for the date part and 0:00:00 for the time part.
Inserts default values for missing parts. Default is
today for the date parts.
The parsing routines ignore surrounding
whitespace. Additional characters and symbols are ignored.
The NIST submodule is useful when you are connected to the
Internet and want access to the accurate world standard
time, the NIST atomic clocks.
The module accesses a special
service provided by NIST and other partner
organizations, which allows anyone with Internet access to
query the current UTC time. Of the three provided protocols,
daytime, time and ntp, I chose the daytime protocol because
of its simplicity and robustness.
Since access through the Internet can be slow, the module
also provides a way to calibrate itself and then use the
computer's clock without the need to go accross the Internet
for every call to the current time constructors. The
defaults are set in such a way that calibration occurrs
without further interaction on part of the programmer. See
the code for details.
The module defines these constructors and functions:
Works must like the standard DateTime.now(), but tries
to use the NIST time servers as time reference -- not
only the computer's builtin clock.
Note that the contructor may take several seconds to
return in case no calibration was performed (see
In case the NIST service is not reachable, the
contructor falls back to using either the calibrated
(preferred) or uncalibrated computer's clock.
Setting
The constructor will use the received NIST information
for auto calibration.
Same notes as for utctime().
If you add the return value to the return value of
Note that due to network latencies and the socket
overhead, the calculated offset will include a small
hopefully constant error.
iterations sets the number of queries done to the NIST
time base. The average is taken over all queries.
Uses the NIST time service as time base. The computer
must have an active internet connection to be able to do
calibration using the NIST servers.
iterations sets the number of round to be done.
Note: This function takes a few seconds to complete. For
long running processes you should recalibrate every now
and then because the system clock tends to drift
(usually more than the hardware clock in the computer).
This also sets the global
This does not clear possibly available calibration
information, so the two time APIs will continue to
revert to the calibrated clock in case no connection to
the NIST servers is possible.
Auto calibration is on per default when the module is
imported.
The package defines these constants:
There's an example called AtomicClock.py in the
Examples/ subdir which demonstrates how easy it is
to turn your PC into a fairly accurate time piece.
For even better time accuracy, one would have to use NTP...
For an example of how to use the two types to develop other
date/time classes (e.g. ones that support time zones or
other calendars), see the included ODMG module. It
defines types similar to those of the ODMG standard.
Here is a little countdown script:
This snippet demonstrates some of the possible string
representations for DateTime instances:
More examples are available in the Examples
subdirectory of the package.
Names with trailing / are plain directories, ones with
[]-brackets are Python packages, ones with ".py" extension
are Python submodules.
The package imports all symbols from the extension module
and also registers the types so that they become compatible
to the pickle and copy mechanisms in Python.
Windows:
The package includes an up-to-date pre-compiled version of
the C extension for WinXX (version 1.3.0) which is included
in the archive -- no further steps or compilation are
necessary.
If you intend to recompile the module yourself, Florent
Heyworth (radbit.com; he donated many of the previous
pre-compiled binaries) has provided a batch file
(win32mk.bat) and a make file (mxDateTime.mak) for VC50
which you can use. All you have to do is run 'win32mk
c:\programs\python' from the mxDateTime subdirectory.
Unix:
MacOS:
Joseph Strout has kindly provided a compiled version of the
C extension for MacOS (version 1.2.0). It is included in the
StuffIt file mxDateTime/mxDateTime.sit.hqx.
In case you run into problems or want to compile the module
youself, see the Python Mac distribution docu or ask Joseph
Strout.
Please post any bug reports, questions etc. directly to me.
I am providing commercial support for this package through
Python Professional
Services Inc.. If you are interested in receiving
information about this service please visit their web-site.
© 1997,1998, Copyright by Marc-André Lemburg; All
Rights Reserved. mailto: mal@lemburg.com
Permission to use, copy, modify, and distribute this
software and its documentation for any purpose and without fee
or royalty is hereby granted, provided that the above
copyright notice appear in all copies and that both the
copyright notice and this permission notice appear in
supporting documentation or portions thereof, including
modifications, that you make.
THE AUTHOR MARC-ANDRE LEMBURG DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL THE AUTHOR BE
LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
OR PERFORMANCE OF THIS SOFTWARE !
Things that still need to be done:
Things that changed from 1.2.0 to 1.3.0:
The exported C API DateTime_AsTmStruct() will also
reflect this change, since it uses the same conversion
routines.
Things that changed from 1.1.0 to 1.2.0:
XXX Note that the support is still experimental and
still contains some bugs that need fixing... e.g.
DateTimeFromJDN(0).jdn == 1.
Note that the function no longer does rounding of the
seconds part: you get the full precision returned by the
time.time() function (which is system dependent).
If you have the timegm() API, enable it in Setup -- it's
more accurate and probably faster too.
Things that changed from 1.0.1 to 1.1.0:
Things that changed from 1.0.0 to 1.0.1:
Things that changed from 0.9.2 to 1.0.0:
This change was needed since there is no way in Python
to make sure that C extensions are really only imported
once: importing mxDateTime directly and indirectly through
the DateTime package lead to two versions of the
extensions being loaded. While this is not too serious at
first sight (it may even be useful in some cases) it turns
out to be a significant problem because the objects
declared by the two versions are seen as being of
different type (type checks in Python are done via
comparing the address of type objects).
As a result, you no longer have to run 'make install'
to install the C extension.
Things that changed from 0.9.1 to 0.9.2:
Things that changed from 0.9.0 to 0.9.1:
Older history entries can be found in a seperate list.
Date/Time Arithmetic
Argument 1
Argument 2
Result
DateTime object v
DateTime object w
v - w
v + w
DateTime object v
A number w
v - w
w
days (floats can be used to indicate day
fractions);
v + w
Note: you can use the object oneDay to get similar
effects in a more intuitive way.
v cmp w
v
to Unix ticks and returns the result of comparing the
ticks value to the number w
. Note: the
ticks conversion assumes that the stored value is
given in local time. Also note that the comparison will
only yield correct results if the DateTime instance is
placed on the left of the comparison operator
(this is because of the coercion quirks mentioned
above).
DateTime object v
DateTimeDelta object w
v - w
w
's value;
v + w
DateTime object v
RelativeDateTime object w
v + w
w
's settings;
v - w
RelativeDateTime object v
A number w
v * w
float(w)
(w * v
works in the
same way);
v / w
float(w)
;
DateTimeDelta object v
DateTime object w
DateTimeDelta object v
A number w
v - w
w
seconds (can be
given as float to indicate fractions of a second);
v + w
Note: you can use the object oneSecond to get similar
effects in a more intuitive way;
v * w
float(w)
(w * v
works in the
same way);
v / w
float(w)
;
v cmp w
v
to a signed float representing the delta in seconds
and returns the result of comparing the seconds value
to the number w
.Note that the comparison
will only yield correct results if the DateTimeDelta
instance is placed on the left of the comparison
operator (this is because of the coercion quirks
mentioned above).
DateTimeDelta object v
DateTimeDelta object w
v + w
(v+w).seconds == v.seconds +
w.seconds
);
v - w
v / w
v.seconds / w.seconds
.
oneDay - 1 == 1 - oneDay
, yet
oneDay - oneSecond != oneSecond - oneDay
.
Submodules
ISO Submodule
ParseDateTimeUTC()
constructor. All others ignore the given offset and store
the time value as-is.
DateTime.ISO
-- it is
imported on demand.
WeekTime(year,isoweek=1,isoday=1,hour=0,minute=0,second=0.0)
iso_week
provides
an inverse to this function.
Week(year,isoweek,isoday=1)
WeekTime()
.
DateTime(), Time(), TimeDelta()
ParseDateTime(isostring)
ParseDateTimeGMT(isostring)
ParseDateTimeUTC(isostring)
ParseDate(isostring)
ParseWeek(isostring)
ParseWeekTime(isostring)
ParseTime(isostring)
ParseTimeDelta(isostring)
ParseAny(isostring)
str(datetime)
strGMT(datetime)
strUTC(datetime)
ValueError
to be raised.
ISO 8601 string formats and DateTime[Delta] instances
'YYYY-MM-DD
HH:MM:SS.ss'
where the last ss indicate hundredths of a
second (ISO doesn't define how to display these).
'[-][DD:]HH:MM:SS.ss'
as format, where DD: is only shown for deltas spanning more than
one day (24 hours). The ss part has the same meaning as for
DateTime instances: hundredths of a second. A minus is shown for
negative deltas. ISO does not define relative time deltas, but
the time representation is allowed to be 'HH:MM:SS'.
ARPA Submodule
DateTime.ARPA
-- it is
imported on demand.
ParseDate(arpastring)
ParseDateTime(arpastring)
ParseDateTimeGMT(arpastring)
ParseDateTimeUTC(arpastring)
str(datetime,tz=DateTime.tz_offset(datetime))
strGMT(datetime)
strUTC(datetime)
Feasts Submodule
EasterSunday(year),
Ostersonntag(year), DimanchePaques(year)
CarnivalMonday(year),
Rosenmontag(year)
MardiGras(year)
AshWednesday(year),
Aschermittwoch(year), MercrediCendres(year)
PalmSunday(year),
Palmsonntag(year), DimancheRameaux(year)
EasterFriday(year),
GoodFriday(year), Karfreitag(year), VendrediSaint(year)
EasterMonday(year),
Ostermontag(year), LundiPaques(year)
Ascension(year),
Himmelfahrt(year)
Pentecost(year),
WhitSunday(year), Pfingstsonntag(year),
DimanchePentecote(year)
WhitMonday(year),
Pfingstmontag(year), LundiPentecote(year)
TrinitySunday(year)
CorpusChristi(year),
Fronleichnam(year), FeteDieu(year)
Parser Submodule
DateTimeFromString(text)
DateFromString(text)
DateTimeDeltaFromString(text)
TimeFromString(text)
TimeDeltaFromString(text)
NIST Submodule
utctime(nist_lookup=0)
calibrate()
). With calibration information,
the computer's clock is used as reference and the offset
to NIST time is compensated by the contructor.
nist_lookup
to false (default) will
cause the contructor to prefer the calibrated CPU time
over the expensive Internet queries. If it is true, then
Internet lookups are always tried first before using the
local clock. A value of 2 will cause an
Error
(see below) to be raised in case the
NIST servers are not reachable.
gmtime()
localtime(nist_lookup=0)
now()
time_offset(iterations=10)
time.time()
, you will have a pretty
accurate time base to use in your applications.
calibrate(iterations=20)
set_calibration(calibration_offset)
calibrated
to 1
and disables auto calibration.
reset_auto_calibration()
enable_auto_calibration()
reset_auto_calibration()
.
disable_auto_calibration()
Error
calibration
calibrated
calibration
contains
valid information.
calibrating
Examples of Use
#!/usr/local/bin/python -u
""" Y2000.py - The year 2000 countdown.
"""
from DateTime import *
from time import sleep
while 1:
d = Date(2000,1,1) - now()
print 'Y2000... time left: %2i days %2i hours '
'%2i minutes %2i seconds\r' % \
(d.day,d.hour,d.minute,d.second),
sleep(1)
>>> from DateTime import *
>>> ISO.str(now())
'1998-06-14 11:08:27+0200'
>>> ARPA.str(now())
'Sun, 14 Jun 1998 11:08:33 +0200'
>>> now().strftime()
'Sun Jun 14 11:08:51 1998'
>>> str(now())
'1998-06-14 11:09:17.82'
Supported Data Types in the C-API
Please have look at the file mxDateTime.h for details.
Interfacing is provided through a Python C object for ticks, struct
tm, COM doubles, Python tuples and direct input either by giving
absolute date/time or a broken down tuple.
To access the module, do the following (note the similarities with
Python's way of accessing functions from a module):
#include "mxDateTime.h"
...
PyObject *v;
/* Import the mxDateTime module */
if (mxDateTime_ImportModuleAndAPI())
goto onError;
/* Access functions from the exported C API through mxDateTime */
v = mxDateTime.DateTime_FromAbsDateAndTime(729376, 49272.0);
if (!v)
goto onError;
/* Type checking */
if (mxDateTime_Check(v))
printf("Works.\n");
Py_DECREF(v);
...
Package Structure
[DateTime]
Doc/
[Examples]
AtomicClock.py
CommandLine.py
Y2000.py
alarm.py
lifespan.py
[mxDateTime]
test.py
ARPA.py
DateTime.py
Feasts.py
ISO.py
LazyModule.py
Locale.py
NIST.py
ODMG.py
Parser.py
Timezone.py
timegm.py
Installation
First, download the mxDateTime
archive, unzip it to a directory on your Python
path e.g. /usr/local/lib/python1.5/site-packages/
on Unix or C:\Python\Lib\ under Windows (note: do not
put the DateTime directory itself on the Python path)
and then follow these steps:
timegm
symbol. The next Python release (1.5.2) will do the
needed checking for you, until then you'll have to edit
the file manually...
Support
What I'd like to hear from you...
Copyright & Disclaimer
History & Future