quickfix_ruby 1.14.3.1 → 1.15.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. checksums.yaml +4 -4
  2. data/ext/quickfix/Acceptor.h +2 -0
  3. data/ext/quickfix/AtomicCount.h +82 -12
  4. data/ext/quickfix/DOMDocument.h +9 -7
  5. data/ext/quickfix/DataDictionary.cpp +77 -14
  6. data/ext/quickfix/DataDictionary.h +90 -16
  7. data/ext/quickfix/Dictionary.cpp +1 -2
  8. data/ext/quickfix/Exceptions.h +3 -5
  9. data/ext/quickfix/Field.h +83 -32
  10. data/ext/quickfix/FieldConvertors.cpp +93 -0
  11. data/ext/quickfix/FieldConvertors.h +129 -275
  12. data/ext/quickfix/FieldMap.cpp +53 -13
  13. data/ext/quickfix/FieldMap.h +200 -62
  14. data/ext/quickfix/FieldTypes.cpp +10 -10
  15. data/ext/quickfix/FieldTypes.h +293 -44
  16. data/ext/quickfix/FileLog.cpp +6 -10
  17. data/ext/quickfix/FileLog.h +4 -10
  18. data/ext/quickfix/FileStore.cpp +19 -6
  19. data/ext/quickfix/FileStore.h +4 -0
  20. data/ext/quickfix/FixFieldNumbers.h +1462 -1461
  21. data/ext/quickfix/FixFields.h +1462 -1461
  22. data/ext/quickfix/FixValues.h +3230 -3227
  23. data/ext/quickfix/HttpConnection.cpp +1 -1
  24. data/ext/quickfix/Initiator.cpp +7 -1
  25. data/ext/quickfix/Initiator.h +2 -0
  26. data/ext/quickfix/Log.h +6 -12
  27. data/ext/quickfix/Message.cpp +186 -57
  28. data/ext/quickfix/Message.h +109 -47
  29. data/ext/quickfix/MySQLConnection.h +1 -1
  30. data/ext/quickfix/PostgreSQLConnection.h +1 -1
  31. data/ext/quickfix/QuickfixRuby.cpp +79141 -77959
  32. data/ext/quickfix/QuickfixRuby.h +1 -1
  33. data/ext/quickfix/SSLSocketAcceptor.cpp +410 -0
  34. data/ext/quickfix/SSLSocketAcceptor.h +185 -0
  35. data/ext/quickfix/SSLSocketConnection.cpp +427 -0
  36. data/ext/quickfix/SSLSocketConnection.h +206 -0
  37. data/ext/quickfix/SSLSocketInitiator.cpp +485 -0
  38. data/ext/quickfix/SSLSocketInitiator.h +196 -0
  39. data/ext/quickfix/Session.cpp +113 -20
  40. data/ext/quickfix/Session.h +18 -4
  41. data/ext/quickfix/SessionFactory.cpp +10 -3
  42. data/ext/quickfix/SessionSettings.cpp +5 -3
  43. data/ext/quickfix/SessionSettings.h +97 -5
  44. data/ext/quickfix/Settings.cpp +72 -2
  45. data/ext/quickfix/Settings.h +3 -0
  46. data/ext/quickfix/SharedArray.h +140 -6
  47. data/ext/quickfix/SocketConnection.cpp +2 -2
  48. data/ext/quickfix/SocketConnector.cpp +5 -2
  49. data/ext/quickfix/SocketConnector.h +3 -2
  50. data/ext/quickfix/SocketInitiator.cpp +28 -4
  51. data/ext/quickfix/SocketInitiator.h +1 -1
  52. data/ext/quickfix/SocketMonitor.cpp +5 -5
  53. data/ext/quickfix/ThreadedSSLSocketAcceptor.cpp +455 -0
  54. data/ext/quickfix/ThreadedSSLSocketAcceptor.h +217 -0
  55. data/ext/quickfix/ThreadedSSLSocketConnection.cpp +404 -0
  56. data/ext/quickfix/ThreadedSSLSocketConnection.h +189 -0
  57. data/ext/quickfix/ThreadedSSLSocketInitiator.cpp +469 -0
  58. data/ext/quickfix/ThreadedSSLSocketInitiator.h +201 -0
  59. data/ext/quickfix/ThreadedSocketAcceptor.cpp +5 -1
  60. data/ext/quickfix/ThreadedSocketConnection.cpp +8 -2
  61. data/ext/quickfix/ThreadedSocketConnection.h +4 -1
  62. data/ext/quickfix/ThreadedSocketInitiator.cpp +24 -4
  63. data/ext/quickfix/ThreadedSocketInitiator.h +1 -1
  64. data/ext/quickfix/Utility.cpp +23 -1
  65. data/ext/quickfix/Utility.h +28 -2
  66. data/ext/quickfix/UtilitySSL.cpp +1733 -0
  67. data/ext/quickfix/UtilitySSL.h +277 -0
  68. data/ext/quickfix/config-all.h +10 -0
  69. data/ext/quickfix/dirent_windows.h +838 -0
  70. data/ext/quickfix/double-conversion/bignum-dtoa.cc +641 -0
  71. data/ext/quickfix/double-conversion/bignum-dtoa.h +84 -0
  72. data/ext/quickfix/double-conversion/bignum.cc +766 -0
  73. data/ext/quickfix/double-conversion/bignum.h +144 -0
  74. data/ext/quickfix/double-conversion/cached-powers.cc +176 -0
  75. data/ext/quickfix/double-conversion/cached-powers.h +64 -0
  76. data/ext/quickfix/double-conversion/diy-fp.cc +57 -0
  77. data/ext/quickfix/double-conversion/diy-fp.h +118 -0
  78. data/ext/quickfix/double-conversion/double-conversion.cc +994 -0
  79. data/ext/quickfix/double-conversion/double-conversion.h +543 -0
  80. data/ext/quickfix/double-conversion/fast-dtoa.cc +665 -0
  81. data/ext/quickfix/double-conversion/fast-dtoa.h +88 -0
  82. data/ext/quickfix/double-conversion/fixed-dtoa.cc +404 -0
  83. data/ext/quickfix/double-conversion/fixed-dtoa.h +56 -0
  84. data/ext/quickfix/double-conversion/ieee.h +402 -0
  85. data/ext/quickfix/double-conversion/strtod.cc +557 -0
  86. data/ext/quickfix/double-conversion/strtod.h +45 -0
  87. data/ext/quickfix/double-conversion/utils.h +372 -0
  88. data/ext/quickfix/stdint_msvc.h +254 -0
  89. data/lib/quickfix44.rb +3329 -10
  90. data/lib/quickfix50.rb +6649 -81
  91. data/lib/quickfix50sp1.rb +8054 -142
  92. data/lib/quickfix50sp2.rb +10900 -234
  93. data/lib/quickfix_fields.rb +7662 -7649
  94. data/spec/FIX40.xml +28 -28
  95. data/spec/FIX41.xml +29 -29
  96. data/spec/FIX42.xml +47 -47
  97. data/spec/FIX43.xml +148 -148
  98. data/spec/FIX44.xml +1078 -1081
  99. data/spec/FIX50.xml +1292 -1289
  100. data/spec/FIX50SP1.xml +1811 -1802
  101. data/spec/FIX50SP2.xml +1948 -1939
  102. data/spec/FIXT11.xml +5 -8
  103. data/test/test_FieldBaseTestCase.rb +1 -1
  104. data/test/test_MessageTestCase.rb +2 -2
  105. metadata +42 -6
@@ -33,14 +33,14 @@ namespace FIX {
33
33
 
34
34
  DateTime DateTime::nowUtc()
35
35
  {
36
- #if defined( HAVE_FTIME )
36
+ #if defined( _POSIX_SOURCE ) || defined(HAVE_GETTIMEOFDAY)
37
+ struct timeval tv;
38
+ gettimeofday (&tv, 0);
39
+ return fromUtcTimeT( tv.tv_sec, tv.tv_usec, 6 );
40
+ #elif defined( HAVE_FTIME )
37
41
  timeb tb;
38
42
  ftime (&tb);
39
43
  return fromUtcTimeT (tb.time, tb.millitm);
40
- #elif defined( _POSIX_SOURCE )
41
- struct timeval tv;
42
- gettimeofday (&tv, 0);
43
- return fromUtcTimeT( tv.tv_sec, tv.tv_usec / 1000 );
44
44
  #else
45
45
  return fromUtcTimeT( ::time (0), 0 );
46
46
  #endif
@@ -48,14 +48,14 @@ DateTime DateTime::nowUtc()
48
48
 
49
49
  DateTime DateTime::nowLocal()
50
50
  {
51
- #if defined( HAVE_FTIME )
51
+ #if defined( _POSIX_SOURCE ) || defined(HAVE_GETTIMEOFDAY)
52
+ struct timeval tv;
53
+ gettimeofday (&tv, 0);
54
+ return fromLocalTimeT( tv.tv_sec, tv.tv_usec, 6 );
55
+ #elif defined( HAVE_FTIME )
52
56
  timeb tb;
53
57
  ftime (&tb);
54
58
  return fromLocalTimeT( tb.time, tb.millitm );
55
- #elif defined( _POSIX_SOURCE )
56
- struct timeval tv;
57
- gettimeofday (&tv, 0);
58
- return fromLocalTimeT( tv.tv_sec, tv.tv_usec / 1000 );
59
59
  #else
60
60
  return fromLocalTimeT( ::time (0), 0 );
61
61
  #endif
@@ -26,6 +26,12 @@
26
26
  #pragma warning( disable : 4503 4355 4786 4290 )
27
27
  #endif
28
28
 
29
+ #if defined(_MSC_VER) && (_MSC_VER < 1600)
30
+ #include "stdint_msvc.h"
31
+ #else
32
+ #include <stdint.h> /* integer types int8_t .. uint64_t, intptr_t */
33
+ #endif
34
+
29
35
  #include "Utility.h"
30
36
  #include <string>
31
37
  #include <time.h>
@@ -37,7 +43,7 @@ namespace FIX
37
43
  */
38
44
 
39
45
  /// Date and Time stored as a Julian day number and number of
40
- /// milliseconds since midnight. Does not perform any timezone
46
+ /// nanoseconds since midnight. Does not perform any timezone
41
47
  /// calculations. All magic numbers and related calculations
42
48
  /// have been taken from:
43
49
  ///
@@ -47,40 +53,50 @@ namespace FIX
47
53
  /// \sa http://scienceworld.wolfram.com/astronomy/Weekday.html
48
54
  ///
49
55
  /// \author Caleb Epstein <caleb.epstein at gmail dot com>
56
+
57
+ // Precision factor of timestamp. [0] - second, [9] - nanosecond
58
+ static const int PRECISION_FACTOR[10] = {1000000000, 100000000, 10000000, 1000000, 100000, 10000, 1000, 100, 10, 1};
59
+
50
60
  struct DateTime
51
61
  {
52
62
  int m_date;
53
- int m_time;
63
+ int64_t m_time;
54
64
 
55
65
  /// Magic numbers
56
- enum
57
- {
58
- SECONDS_PER_DAY = 86400,
59
- SECONDS_PER_HOUR = 3600,
60
- SECONDS_PER_MIN = 60,
61
- MINUTES_PER_HOUR = 60,
66
+ static const int64_t SECONDS_PER_DAY = 86400;
67
+ static const int64_t SECONDS_PER_HOUR = 3600;
68
+ static const int64_t SECONDS_PER_MIN = 60;
69
+ static const int64_t MINUTES_PER_HOUR = 60;
62
70
 
63
- MILLIS_PER_DAY = 86400000,
64
- MILLIS_PER_HOUR = 3600000,
65
- MILLIS_PER_MIN = 60000,
66
- MILLIS_PER_SEC = 1000,
71
+ static const int64_t NANOS_PER_DAY = 86400000000000;
72
+ static const int64_t NANOS_PER_HOUR = 3600000000000;
73
+ static const int64_t NANOS_PER_MIN = 60000000000;
74
+ static const int64_t NANOS_PER_SEC = 1000000000;
67
75
 
68
- // time_t epoch (1970-01-01) as a Julian date
69
- JULIAN_19700101 = 2440588
70
- };
76
+ // time_t epoch (1970-01-01) as a Julian date
77
+ static const int64_t JULIAN_19700101 = 2440588;
71
78
 
72
79
  /// Default constructor - initializes to zero
73
80
  DateTime () : m_date (0), m_time (0) {}
74
81
 
75
82
  /// Construct from a Julian day number and time in millis
76
- DateTime (int date, int time) : m_date (date), m_time (time) {}
83
+ DateTime (int date, int64_t time) : m_date (date), m_time (time) {}
77
84
 
78
85
  /// Construct from the specified components
79
86
  DateTime( int year, int month, int day,
80
87
  int hour, int minute, int second, int millis )
81
88
  {
82
89
  m_date = julianDate( year, month, day );
83
- m_time = makeHMS( hour, minute, second, millis );
90
+ m_time = makeHMS( hour, minute, second, millis * PRECISION_FACTOR[3] );
91
+ }
92
+
93
+ /// Construct from the specified components
94
+ DateTime( int year, int month, int day,
95
+ int hour, int minute, int second, int fraction, int precision )
96
+ {
97
+ m_date = julianDate( year, month, day );
98
+ int nanos = convertToNanos(fraction, precision);
99
+ m_time = makeHMS( hour, minute, second, nanos );
84
100
  }
85
101
 
86
102
  virtual ~DateTime() {}
@@ -117,27 +133,77 @@ struct DateTime
117
133
  inline int getJulianDate() const { return m_date; }
118
134
 
119
135
  /// Return the hour portion of the time (0-23)
120
- inline int getHour() const
136
+ inline int getHour() const
121
137
  {
122
- return m_time / MILLIS_PER_HOUR;
138
+ return (int)(m_time / NANOS_PER_HOUR);
123
139
  }
124
140
 
125
141
  /// Return the minute portion of the time (0-59)
126
- inline int getMinute() const
142
+ inline int getMinute() const
127
143
  {
128
- return (m_time / MILLIS_PER_MIN) % MINUTES_PER_HOUR;
144
+ return (m_time / NANOS_PER_MIN) % MINUTES_PER_HOUR;
129
145
  }
130
146
 
131
147
  /// Return the second portion of the time (0-59)
132
- inline int getSecond() const
148
+ inline int getSecond() const
149
+ {
150
+ return (m_time / NANOS_PER_SEC) % SECONDS_PER_MIN;
151
+ }
152
+
153
+ /// Return the millisecond portion of the time (0-999)
154
+ inline int getMillisecond() const
133
155
  {
134
- return (m_time / MILLIS_PER_SEC) % SECONDS_PER_MIN;
156
+ return (getNanosecond() / PRECISION_FACTOR[3]);
135
157
  }
136
158
 
137
- /// Return the millisecond portion of the time
138
- inline int getMillisecond() const
159
+ /// Return the microsecond portion of the time
160
+ inline int getMicroecond() const
139
161
  {
140
- return m_time % MILLIS_PER_SEC;
162
+ return (getNanosecond() / PRECISION_FACTOR[6]);
163
+ }
164
+
165
+ /// Return the nanosecond portion of the time
166
+ inline unsigned int getNanosecond() const
167
+ {
168
+ return static_cast<uint64_t>(m_time) % NANOS_PER_SEC;
169
+ }
170
+
171
+ /// Return the fraction portion of the time
172
+ inline int getFraction(int precision) const
173
+ {
174
+ switch (precision)
175
+ {
176
+ case 0:
177
+ return (getNanosecond() / PRECISION_FACTOR[0]);
178
+
179
+ case 1:
180
+ return (getNanosecond() / PRECISION_FACTOR[1]);
181
+
182
+ case 2:
183
+ return (getNanosecond() / PRECISION_FACTOR[2]);
184
+
185
+ case 3:
186
+ return (getNanosecond() / PRECISION_FACTOR[3]);
187
+
188
+ case 4:
189
+ return (getNanosecond() / PRECISION_FACTOR[4]);
190
+
191
+ case 5:
192
+ return (getNanosecond() / PRECISION_FACTOR[5]);
193
+
194
+ case 6:
195
+ return (getNanosecond() / PRECISION_FACTOR[6]);
196
+
197
+ case 7:
198
+ return (getNanosecond() / PRECISION_FACTOR[7]);
199
+
200
+ case 8:
201
+ return (getNanosecond() / PRECISION_FACTOR[8]);
202
+
203
+ case 9:
204
+ default:
205
+ return (getNanosecond() / PRECISION_FACTOR[9]);
206
+ }
141
207
  }
142
208
 
143
209
  /// Load the referenced values with the year, month and day
@@ -151,11 +217,22 @@ struct DateTime
151
217
  /// millisecond portions of the time in a single operation
152
218
  inline void getHMS( int& hour, int& minute, int& second, int& millis ) const
153
219
  {
154
- int ticks = m_time / MILLIS_PER_SEC;
220
+ int ticks = (int)(m_time / NANOS_PER_SEC);
221
+ hour = ticks / SECONDS_PER_HOUR;
222
+ minute = (ticks / SECONDS_PER_MIN) % MINUTES_PER_HOUR;
223
+ second = ticks % SECONDS_PER_MIN;
224
+ millis = getMillisecond();
225
+ }
226
+
227
+ /// Load the referenced values with the hour, minute, second and
228
+ /// fraction portions of the time in a single operation
229
+ inline void getHMS( int& hour, int& minute, int& second, int& fraction, int precision ) const
230
+ {
231
+ int ticks = (int)(m_time / NANOS_PER_SEC);
155
232
  hour = ticks / SECONDS_PER_HOUR;
156
233
  minute = (ticks / SECONDS_PER_MIN) % MINUTES_PER_HOUR;
157
234
  second = ticks % SECONDS_PER_MIN;
158
- millis = m_time % MILLIS_PER_SEC;
235
+ fraction = getFraction(precision);
159
236
  }
160
237
 
161
238
  /// Calculate the weekday of the date (Sunday is 1, Saturday is 7)
@@ -177,7 +254,7 @@ struct DateTime
177
254
  inline time_t getTimeT() const
178
255
  {
179
256
  return (SECONDS_PER_DAY * (m_date - JULIAN_19700101) +
180
- m_time / MILLIS_PER_SEC);
257
+ m_time / NANOS_PER_SEC);
181
258
  }
182
259
 
183
260
  /// Convert the DateTime to a struct tm which is in UTC
@@ -210,7 +287,15 @@ struct DateTime
210
287
  /// Set the time portion of the DateTime
211
288
  void setHMS( int hour, int minute, int second, int millis )
212
289
  {
213
- m_time = makeHMS( hour, minute, second, millis );
290
+ m_time = makeHMS( hour, minute, second, millis * PRECISION_FACTOR[3] );
291
+ }
292
+
293
+ /// Set the time portion of the DateTime
294
+ void setHMS( int hour, int minute, int second, int fraction, int precision )
295
+ {
296
+ int nanos = convertToNanos(fraction, precision);
297
+
298
+ m_time = makeHMS( hour, minute, second, nanos);
214
299
  }
215
300
 
216
301
  /// Set the hour portion of the time
@@ -245,6 +330,30 @@ struct DateTime
245
330
  setHMS( hour, min, sec, millis );
246
331
  }
247
332
 
333
+ /// Set the microsecond portion of the time
334
+ void setMicrosecond( int micros )
335
+ {
336
+ int hour, min, sec, old_nanos;
337
+ getHMS( hour, min, sec, old_nanos, 9 );
338
+ setHMS( hour, min, sec, micros, 6 );
339
+ }
340
+
341
+ /// Set the nanosecond portion of the time
342
+ void setNanosecond( int nanos )
343
+ {
344
+ int hour, min, sec, old_nanos;
345
+ getHMS( hour, min, sec, old_nanos, 9 );
346
+ setHMS( hour, min, sec, nanos, 9 );
347
+ }
348
+
349
+ /// Set the fraction portion of the time
350
+ void setFraction( int fraction, int precision )
351
+ {
352
+ int hour, min, sec, old_nanos;
353
+ getHMS( hour, min, sec, old_nanos, 9 );
354
+ setHMS( hour, min, sec, fraction, precision );
355
+ }
356
+
248
357
  /// Clear the date portion of the DateTime
249
358
  void clearDate()
250
359
  {
@@ -258,7 +367,7 @@ struct DateTime
258
367
  }
259
368
 
260
369
  /// Set the internal date and time members
261
- void set( int date, int time ) { m_date = date; m_time = time; }
370
+ void set( int date, int64_t time ) { m_date = date; m_time = time; }
262
371
 
263
372
  /// Initialize from another DateTime
264
373
  void set( const DateTime& other )
@@ -268,33 +377,85 @@ struct DateTime
268
377
  }
269
378
 
270
379
  /// Add a number of seconds to this
271
- void operator+=( int seconds )
380
+ void operator+=( int seconds )
272
381
  {
273
382
  int d = seconds / SECONDS_PER_DAY;
274
383
  int s = seconds % SECONDS_PER_DAY;
275
384
 
276
385
  m_date += d;
277
- m_time += s * MILLIS_PER_SEC;
386
+ m_time += s * NANOS_PER_SEC;
278
387
 
279
- if( m_time > MILLIS_PER_DAY )
388
+ if( m_time > NANOS_PER_DAY )
280
389
  {
281
390
  m_date++;
282
- m_time %= MILLIS_PER_DAY;
391
+ m_time %= NANOS_PER_DAY;
283
392
  }
284
393
  else if( m_time < 0 )
285
394
  {
286
395
  m_date--;
287
- m_time += MILLIS_PER_DAY;
396
+ m_time += NANOS_PER_DAY;
397
+ }
398
+ }
399
+
400
+ /// Convert to internal nanos
401
+ static int convertToNanos(int fraction, int precision)
402
+ {
403
+ int nanos;
404
+
405
+ switch (precision)
406
+ {
407
+ case 0:
408
+ nanos = fraction * PRECISION_FACTOR[0];
409
+ break;
410
+
411
+ case 1:
412
+ nanos = fraction * PRECISION_FACTOR[1];
413
+ break;
414
+
415
+ case 2:
416
+ nanos = fraction * PRECISION_FACTOR[2];
417
+ break;
418
+
419
+ case 3:
420
+ nanos = fraction * PRECISION_FACTOR[3];
421
+ break;
422
+
423
+ case 4:
424
+ nanos = fraction * PRECISION_FACTOR[4];
425
+ break;
426
+
427
+ case 5:
428
+ nanos = fraction * PRECISION_FACTOR[5];
429
+ break;
430
+
431
+ case 6:
432
+ nanos = fraction * PRECISION_FACTOR[6];
433
+ break;
434
+
435
+ case 7:
436
+ nanos = fraction * PRECISION_FACTOR[7];
437
+ break;
438
+
439
+ case 8:
440
+ nanos = fraction * PRECISION_FACTOR[8];
441
+ break;
442
+
443
+ case 9:
444
+ default:
445
+ nanos = fraction * PRECISION_FACTOR[9];
446
+ break;
288
447
  }
448
+
449
+ return nanos;
289
450
  }
290
451
 
291
452
  /// Helper method to convert a broken down time to a number of
292
- /// milliseconds since midnight
293
- static int makeHMS( int hour, int minute, int second, int millis )
453
+ /// nanoseconds since midnight
454
+ static int64_t makeHMS( int hour, int minute, int second, int nanos )
294
455
  {
295
- return MILLIS_PER_SEC * (SECONDS_PER_HOUR * hour +
296
- SECONDS_PER_MIN * minute +
297
- second) + millis;
456
+ return NANOS_PER_SEC * (SECONDS_PER_HOUR * hour +
457
+ SECONDS_PER_MIN * minute +
458
+ second) + nanos;
298
459
  }
299
460
 
300
461
  /// Return the current wall-clock time as a utc DateTime
@@ -316,13 +477,35 @@ struct DateTime
316
477
  return fromTm( tm, millis );
317
478
  }
318
479
 
480
+ static DateTime fromUtcTimeT( time_t t, int fraction, int precision )
481
+ {
482
+ struct tm tm = time_gmtime( &t );
483
+ return fromTm( tm, fraction, precision );
484
+ }
485
+
486
+ static DateTime fromLocalTimeT( time_t t, int fraction, int precision )
487
+ {
488
+ struct tm tm = time_localtime( &t );
489
+ return fromTm( tm, fraction, precision );
490
+ }
491
+
319
492
  /// Convert a tm and optional milliseconds to a DateTime. \note
320
493
  /// the tm structure is assumed to contain a date specified in UTC
321
494
  static DateTime fromTm( const tm& tm, int millis = 0 )
322
495
  {
323
496
  return DateTime ( julianDate(tm.tm_year + 1900, tm.tm_mon + 1,
324
497
  tm.tm_mday),
325
- makeHMS(tm.tm_hour, tm.tm_min, tm.tm_sec, millis) );
498
+ makeHMS(tm.tm_hour, tm.tm_min, tm.tm_sec, millis * PRECISION_FACTOR[3]) );
499
+ }
500
+
501
+ /// Convert a tm and optional milliseconds to a DateTime. \note
502
+ /// the tm structure is assumed to contain a date specified in UTC
503
+ static DateTime fromTm( const tm& tm, int fraction, int precision )
504
+ {
505
+ int nanos = convertToNanos(fraction, precision);
506
+ return DateTime ( julianDate(tm.tm_year + 1900, tm.tm_mon + 1,
507
+ tm.tm_mday),
508
+ makeHMS(tm.tm_hour, tm.tm_min, tm.tm_sec, nanos) );
326
509
  }
327
510
 
328
511
  /// Helper method to calculate a Julian day number.
@@ -391,8 +574,8 @@ inline bool operator>=( const DateTime& lhs, const DateTime& rhs )
391
574
  inline int operator-( const DateTime& lhs, const DateTime& rhs )
392
575
  {
393
576
  return (DateTime::SECONDS_PER_DAY * (lhs.m_date - rhs.m_date) +
394
- // Truncate the millis before subtracting
395
- lhs.m_time / 1000 - rhs.m_time / 1000);
577
+ // Truncate the nanos before subtracting
578
+ (int)(lhs.m_time / DateTime::NANOS_PER_SEC) - (int)(rhs.m_time / DateTime::NANOS_PER_SEC));
396
579
  }
397
580
 
398
581
  /// Date and Time represented in UTC.
@@ -410,6 +593,12 @@ public:
410
593
  setHMS( hour, minute, second, millisecond );
411
594
  }
412
595
 
596
+ UtcTimeStamp( int hour, int minute, int second, int fraction, int precision )
597
+ : DateTime( DateTime::nowUtc() )
598
+ {
599
+ setHMS( hour, minute, second, fraction, precision );
600
+ }
601
+
413
602
  UtcTimeStamp( int hour, int minute, int second,
414
603
  int date, int month, int year )
415
604
  : DateTime( year, month, date, hour, minute, second, 0 ) {}
@@ -418,12 +607,22 @@ public:
418
607
  int date, int month, int year )
419
608
  : DateTime( year, month, date, hour, minute, second, millisecond ) {}
420
609
 
610
+ UtcTimeStamp( int hour, int minute, int second, int fraction,
611
+ int date, int month, int year, int precision )
612
+ : DateTime( year, month, date, hour, minute, second, fraction, precision ) {}
613
+
421
614
  explicit UtcTimeStamp( time_t time, int millisecond = 0 )
422
615
  : DateTime( fromUtcTimeT (time, millisecond) ) {}
423
616
 
617
+ UtcTimeStamp( time_t time, int fraction, int precision )
618
+ : DateTime( fromUtcTimeT (time, fraction, precision) ) {}
619
+
424
620
  UtcTimeStamp( const tm* time, int millisecond = 0 )
425
621
  : DateTime( fromTm (*time, millisecond) ) {}
426
622
 
623
+ UtcTimeStamp( const tm* time, int fraction, int precision )
624
+ : DateTime( fromTm (*time, fraction, precision) ) {}
625
+
427
626
  void setCurrent()
428
627
  {
429
628
  set( DateTime::nowUtc() );
@@ -445,6 +644,12 @@ public:
445
644
  setHMS( hour, minute, second, millisecond );
446
645
  }
447
646
 
647
+ LocalTimeStamp( int hour, int minute, int second, int fraction, int precision )
648
+ : DateTime( DateTime::nowLocal() )
649
+ {
650
+ setHMS( hour, minute, second, fraction, precision );
651
+ }
652
+
448
653
  LocalTimeStamp( int hour, int minute, int second,
449
654
  int date, int month, int year )
450
655
  : DateTime( year, month, date, hour, minute, second, 0 ) {}
@@ -453,12 +658,22 @@ public:
453
658
  int date, int month, int year )
454
659
  : DateTime( year, month, date, hour, minute, second, millisecond ) {}
455
660
 
661
+ LocalTimeStamp( int hour, int minute, int second, int fraction,
662
+ int date, int month, int year, int precision )
663
+ : DateTime( year, month, date, hour, minute, second, fraction, precision ) {}
664
+
456
665
  explicit LocalTimeStamp( time_t time, int millisecond = 0 )
457
666
  : DateTime( fromLocalTimeT (time, millisecond) ) {}
458
667
 
668
+ LocalTimeStamp( time_t time, int fraction, int precision )
669
+ : DateTime( fromLocalTimeT (time, fraction, precision) ) {}
670
+
459
671
  LocalTimeStamp( const tm* time, int millisecond = 0 )
460
672
  : DateTime( fromTm (*time, millisecond) ) {}
461
673
 
674
+ LocalTimeStamp( const tm* time, int fraction, int precision )
675
+ : DateTime( fromTm (*time, fraction, precision) ) {}
676
+
462
677
  void setCurrent()
463
678
  {
464
679
  set( DateTime::nowLocal() );
@@ -486,18 +701,35 @@ public:
486
701
  setHMS( hour, minute, second, millisecond );
487
702
  }
488
703
 
704
+ UtcTimeOnly( int hour, int minute, int second, int fraction, int precision )
705
+ {
706
+ setHMS( hour, minute, second, fraction, precision );
707
+ }
708
+
489
709
  explicit UtcTimeOnly( time_t time, int millisecond = 0 )
490
710
  : DateTime( fromUtcTimeT (time, millisecond) )
491
711
  {
492
712
  clearDate();
493
713
  }
494
714
 
715
+ UtcTimeOnly( time_t time, int fraction, int precision )
716
+ : DateTime( fromUtcTimeT (time, fraction, precision) )
717
+ {
718
+ clearDate();
719
+ }
720
+
495
721
  UtcTimeOnly( const tm* time, int millisecond = 0 )
496
722
  : DateTime( fromTm (*time, millisecond) )
497
723
  {
498
724
  clearDate();
499
725
  }
500
726
 
727
+ UtcTimeOnly( const tm* time, int fraction, int precision )
728
+ : DateTime( fromTm (*time, fraction, precision) )
729
+ {
730
+ clearDate();
731
+ }
732
+
501
733
  /// Set to the current time.
502
734
  void setCurrent()
503
735
  {
@@ -527,18 +759,35 @@ public:
527
759
  setHMS( hour, minute, second, millisecond );
528
760
  }
529
761
 
762
+ LocalTimeOnly( int hour, int minute, int second, int fraction, int precision )
763
+ {
764
+ setHMS( hour, minute, second, fraction, precision );
765
+ }
766
+
530
767
  explicit LocalTimeOnly( time_t time, int millisecond = 0 )
531
768
  : DateTime( fromLocalTimeT (time, millisecond) )
532
769
  {
533
770
  clearDate();
534
771
  }
535
772
 
773
+ LocalTimeOnly( time_t time, int fraction, int precision )
774
+ : DateTime( fromLocalTimeT (time, fraction, precision) )
775
+ {
776
+ clearDate();
777
+ }
778
+
536
779
  LocalTimeOnly( const tm* time, int millisecond = 0 )
537
780
  : DateTime( fromTm (*time, millisecond) )
538
781
  {
539
782
  clearDate();
540
783
  }
541
784
 
785
+ LocalTimeOnly( const tm* time, int fraction, int precision )
786
+ : DateTime( fromTm (*time, fraction, precision) )
787
+ {
788
+ clearDate();
789
+ }
790
+
542
791
  /// Set to the current time.
543
792
  void setCurrent()
544
793
  {