1.. _rfc-56:
2
3=======================================================================================
4RFC 56: OFTTime/OFTDateTime millisecond accuracy
5=======================================================================================
6
7Author: Even Rouault
8
9Contact: even dot rouault at spatialys dot com
10
11Status: Adopted, implemented
12
13Version: 2.0
14
15Summary
16-------
17
18This RFC aims at adding millisecond accuracy to OFTTime and OFTDateTime
19fields, as a number of formats support it explicitly or implicitly :
20MapInfo, GPX, Atom (GeoRSS driver), GeoPackage, SQLite, PostgreSQL, CSV,
21GeoJSON, ODS, XLSX, KML (potentially GML too)...
22
23Core changes
24------------
25
26The OGRField enumeration is modified as such :
27
28::
29
30   typedef union {
31       [... unchanged ... ]
32
33       struct {
34           GInt16  Year;
35           GByte   Month;
36           GByte   Day;
37           GByte   Hour;
38           GByte   Minute;
39           GByte   TZFlag; /* 0=unknown, 1=localtime(ambiguous),
40                              100=GMT, 104=GMT+1, 80=GMT-5, etc */
41           GByte   Reserved; /* must be set to 0 */
42           float   Second; /* with millisecond accuracy. at the end of the structure, so as to keep it 12 bytes on 32 bit */
43       } Date;
44   } OGRField;
45
46So the "GByte Second" field is removed and replaced by a padding Byte
47reserved for potential later uses. A "float Second" field is added.
48
49On 32 bit builds, the size of OGRField is now 12 bytes instead of 8
50bytes. On 64 bit builds, the size of OGRField remains 16 bytes.
51
52New/modified methods
53~~~~~~~~~~~~~~~~~~~~
54
55OGRFeature::SetFieldAsDateTime() methods that took a int nSecond now
56take a float fSecond parameter. The GetFieldAsDateTime() method that
57took a int\* pnSecond is kept, and a new GetFieldAsDateTime() method
58that takes a float\* pfSecond is added.
59
60-  In OGRFeature class :
61
62::
63
64       int                 GetFieldAsDateTime( int i,
65                                        int *pnYear, int *pnMonth, int *pnDay,
66                                        int *pnHour, int *pnMinute, int *pnSecond,
67                                        int *pnTZFlag ); /* unchanged from GDAL 1.X */
68       int                 GetFieldAsDateTime( int i,
69                                        int *pnYear, int *pnMonth, int *pnDay,
70                                        int *pnHour, int *pnMinute, float *pfSecond,
71                                        int *pnTZFlag ); /* new */
72       void                SetField( int i, int nYear, int nMonth, int nDay,
73                                     int nHour=0, int nMinute=0, float fSecond=0.f,
74                                     int nTZFlag = 0 ); /* modified */
75       void                SetField( const char *pszFName,
76                                     int nYear, int nMonth, int nDay,
77                                     int nHour=0, int nMinute=0, float fSecond=0.f,
78                                     int nTZFlag = 0 ); /* modified */
79
80OGRFeature::GetFieldAsString() is modified to output milliseconds if the
81Second member of OGRField.Date is not integral
82
83OGRParseDate() is modified to parse second as floating point number.
84
85The following utility functions have their signature modified to take a
86OGRField (instead of the full year, month, day, hour, minute, second,
87TZFlag decomposition) and accept decimal seconds as input/output :
88
89::
90
91   int CPL_DLL OGRParseXMLDateTime( const char* pszXMLDateTime,
92                                    OGRField* psField );
93   int CPL_DLL OGRParseRFC822DateTime( const char* pszRFC822DateTime,
94                                       OGRField* psField );
95   char CPL_DLL * OGRGetRFC822DateTime(const OGRField* psField);
96   char CPL_DLL * OGRGetXMLDateTime(const OGRField* psField);
97
98C API changes
99~~~~~~~~~~~~~
100
101Only additions :
102
103::
104
105   int   CPL_DLL OGR_F_GetFieldAsDateTimeEx( OGRFeatureH hFeat, int iField,
106                                   int *pnYear, int *pnMonth, int *pnDay,
107                                   int *pnHour, int *pnMinute, float *pfSecond,
108                                   int *pnTZFlag );
109   void   CPL_DLL OGR_F_SetFieldDateTimeEx( OGRFeatureH, int,
110                                          int, int, int, int, int, float, int );
111
112Changes in drivers
113------------------
114
115The following drivers now accept milliseconds as input/output :
116
117-  GeoJSON
118-  CSV
119-  PG
120-  PGDump (output only)
121-  CartoDB
122-  GeoPackage
123-  SQLite
124-  MapInfo .tab and .mif
125-  LIBKML
126-  ODS
127-  XLSX
128-  GeoRSS (Atom format)
129-  GPX
130
131Changes in SWIG bindings
132------------------------
133
134Feature.GetFieldAsDateTime() and Feature.SetFieldAsDateTime() now
135takes/returns a floating point number for seconds
136
137Compatibility
138-------------
139
140This modifies the C/C++ API and ABI.
141
142Output of above mentioned drivers will now include milliseconds if a
143DateTime/Time field has such precision.
144
145Related ticket
146--------------
147
148The need came from
149`http://trac.osgeo.org/gdal/ticket/2680 <http://trac.osgeo.org/gdal/ticket/2680>`__
150for MapInfo driver.
151
152Documentation
153-------------
154
155All new/modified methods are documented. MIGRATION_GUIDE.TXT is updated
156with a new section for this RFC.
157
158Testing
159-------
160
161The various aspects of this RFC are tested:
162
163-  core changes
164-  driver changes
165
166Implementation
167--------------
168
169Implementation will be done by Even Rouault
170(`Spatialys <http://spatialys.com>`__).
171
172The proposed implementation lies in the "subsecond_accuracy" branch of
173the
174`https://github.com/rouault/gdal2/tree/subsecond_accuracy <https://github.com/rouault/gdal2/tree/subsecond_accuracy>`__
175repository.
176
177The list of changes :
178`https://github.com/rouault/gdal2/compare/subsecond_accuracy <https://github.com/rouault/gdal2/compare/subsecond_accuracy>`__
179
180Voting history
181--------------
182
183+1 from DanielM, JukkaR and EvenR
184