.. _date-handling-example: Handling Date Data ================== Format an INGRESDATE for display. Everything in Python is an object, but everything in an Actian SQL DBMS is a hardware datatype or a C structure. ``ctypes`` automatically takes care of marshalling the hardware datatypes and C strings to and from Python, but the other SQL datatypes need to be accommodated as ``ctypes`` structures, which have to be defined, or as byte arrays. (See :ref:`Data Marshalling ` for more information.) In general, all the Actian SQL abstract data types (dates/times, money, decimal/numeric, etc.) are represented in the database as C structures. The OpenAPI exchanges those structures with the application. In the case of dates they can be treated as byte arrays. It is not necessary to understand the internal structure in order to allocate a buffer. .. TIP:: The required buffer size can be determined in two ways. The OpenAPI returns query metadata in the form of a list of :attr:`!IIAPI_DESCRIPTOR`. The :attr:`!ds_length` attribute indicates the size of bufffer required. Alternatively, see `Ingres Data Types `_ in the *OpenAPI User Guide*. Byte arrays (structures) are incomprehensible to a human user. All OpenAPI applications have to explicitly format abstract types such as dates in a human-readable form. The OpenAPI :func:`!IIapi_convertData` and :func:`!IIapi_formatData` functions are provided for the purpose. This example illustrates how to format an INGRESDATE for display. The same general approach is used for ANSIDATE, TIME, TIMESTAMP, and INTERVAL. INGRESDATE values are represented in a 12 byte structure. The example below allocates a 12 byte buffer using `ctypes.c_buffer`. .. NOTE:: This example formats the byte array representation of a date as a human-readable string. The same function can be used for the inverse operation, to load a human-readable source date into a destination buffer. :download:`Download <./examples/date.py>` .. LITERALINCLUDE:: ./examples/date.py :linenos: :download:`Download <./examples/date.py>`