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