Project

This chapter discusses the project from a management perspective.

Introduction

rhythm exists to provide a pure-Python, nanosecond precision time package. It features support for the proleptic gregorian calendar, and points and deltas of configurable precision.

Structure

This project consists of the following modules:

rhythm.lib
The primary developer interface module that ties many of the other modules together. This is the module that is normally imported.
rhythm.libfs
File system tools based on rhythm.lib: stat, fstat, and lstat calls returning the ctime, mtime, and atime as rhythm.lib.Timestamp instances.
rhythm.libunit
The unit context module. This provides the standard context definition used by rhythm.lib.
rhythm.libformat
The implementation of standard formatting functions for parsing and formatting.
rhythm.libzone
rhythm.libtzif based time zone support.
rhythm.earth
Definition of earth based measures of time.
rhythm.metric
Definition of metric-unit based measures of time. Also earth-based.
rhythm.gregorian
The implementation of gregorian-unit based time measures and points; dates, day deltas, and month deltas.

Requirements

A functioning Python interpreter and a C compiler capable of compiling Python extension modules, clock and sleep access.

Conventions

Capitalization

Often, capitalization will be used in the documentation in order to convey that the word or phrase is being used with regards to its meaning in the context of the project.

Terminology

Horology
The study of and measurement of time. (definition)
Unit
A unit of time. Normally, a typed quantity.
Part
A measure of a particular unit in a Time instance. Often with regards to a whole.
Whole
The unit that a selected part should be aligned to. Often, the of keyword parameter refers to a whole. In comments, it can be referred to as of-whole.
Point
A point in time, however, it is a misleading designation as Points in Time are always vectors. Essentially, they can be treated as Points or as Vectors. It is a scalar quantity relative to a datum and with a magnitude of no less than one unit of the scalar quantity.
PiT
Shorthand for: Point in Time.
Subsecond
Often, a reference to the precision of representation type.
Representation Type
An actual Python class representing a [unit] Type defined in a Time Context.
Time Context
An instance of rhythm.libunit.Context managing the set of defined unit Types and any corresponding Representation Types.
Canonical Position
A PiT that is in the understood time zone that does not vary. Usually referring to UTC.
Localization
Referring to the process of localizing a timestamp to a particular time zone. Given a UTC timestamp, a localized version of the timestamp would be the timestamp adjusted by the offset identified by the specified rhythm.libzone.Zone. rhythm.libzone.Zone.localize().
Normalization
Referring the process of normalizing a localized timestamp to a particular time zone. Given a localized timestamp, a normalized version of the timestamp would be the timestamp adjusted to UTC and then localized. Normalization should be used when representing timestamps whose localized version has been manipulated. rhythm.libzone.Zone.normalize().
Term
Internal to rhythm: a core unit. Units are associated as “like” terms by rhythm.libunit.Context instances. In the default context, there are only two terms: days and months.
Bridge
Internal to rhythm: a set of mappings that allow “unlike” terms to be converted. This is the infrastructure that provides a means to register the conversion methods for converting days to months and months to days.
Type
A particular unit of time in a Time Context. second, day, month are all types.

Examples

Examples will often reference a libtime module. This module is defined:

from rhythm import lib as libtime

Defense

This section details arguments for rhythm’s existence.

Existence

rhythm is the only alternative pure-Python, save clock access, datetime package.

Development

Evolution

rhythm strives to isolate functionality as much as possible. However, in early implementations, difficulty came when using managing distinct units as separate classes. Even with a common superclass, greater integration was necessary to provide a cohesive programmer interface. Notably, when using time classes interchangeably.

rhythm still strives, and does so with regards to basic functionality and logic. But in order to provide the greater integration, unit classes are connected by a Time Context that defines the consistency of all time types, and provides a means for resolving unit conversion paths.

References

The functionality and API choices of a number of datetime implementations were analyzed during the development of rhythm:

  • Chronus-ST (http://chronos-st.org/)
  • SQL/Postgres’ DATE, TIME, and TIMESTAMP types.
  • Python datetime
  • dateutils
  • mxDateTime
  • <There is another datetime package that largely influenced rhythm’s API. Can’t find it again...>

In addition to various packages for other languages such as ruby and java.

Wikipedia was, naturally, heavily referenced during the development of rhythm. Here are many of the links:

Gotchas

Points and Measures are Python Integers

This has the effect that integers with the same value will be seen as the same key:

>>> from rhythm import lib
>>> d = {}
>>> d[lib.Date(0)] = 'Hello, World!'
>>> print d[0]
Hello, World!

Month Arithmetic Can Overflow

The implementation of month arithmetic is sensitive to the selected day:

# working with a leap year
pit = lib.Timestamp.of(iso='2012-01-31T18:55:33.946259')
pit.elapse(month=1)
rhythm.lib.Timestamp.of(iso='2012-03-02T18:55:33.946259')

The issue can be avoided by adjusted the PiT to the beginning of the month:

pit = pit.update('day', 0, 'month')