utmscale.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481
  1. /*
  2. *******************************************************************************
  3. * Copyright (C) 2004 - 2008, International Business Machines Corporation and
  4. * others. All Rights Reserved.
  5. *******************************************************************************
  6. */
  7. #ifndef UTMSCALE_H
  8. #define UTMSCALE_H
  9. #include "unicode/utypes.h"
  10. #if !UCONFIG_NO_FORMATTING
  11. /**
  12. * \file
  13. * \brief C API: Universal Time Scale
  14. *
  15. * There are quite a few different conventions for binary datetime, depending on different
  16. * platforms and protocols. Some of these have severe drawbacks. For example, people using
  17. * Unix time (seconds since Jan 1, 1970) think that they are safe until near the year 2038.
  18. * But cases can and do arise where arithmetic manipulations causes serious problems. Consider
  19. * the computation of the average of two datetimes, for example: if one calculates them with
  20. * <code>averageTime = (time1 + time2)/2</code>, there will be overflow even with dates
  21. * around the present. Moreover, even if these problems don't occur, there is the issue of
  22. * conversion back and forth between different systems.
  23. *
  24. * <p>
  25. * Binary datetimes differ in a number of ways: the datatype, the unit,
  26. * and the epoch (origin). We'll refer to these as time scales. For example:
  27. *
  28. * <table border="1" cellspacing="0" cellpadding="4">
  29. * <caption>Table 1: Binary Time Scales</caption>
  30. * <tr>
  31. * <th align="left">Source</th>
  32. * <th align="left">Datatype</th>
  33. * <th align="left">Unit</th>
  34. * <th align="left">Epoch</th>
  35. * </tr>
  36. *
  37. * <tr>
  38. * <td>UDTS_JAVA_TIME</td>
  39. * <td>int64_t</td>
  40. * <td>milliseconds</td>
  41. * <td>Jan 1, 1970</td>
  42. * </tr>
  43. * <tr>
  44. *
  45. * <td>UDTS_UNIX_TIME</td>
  46. * <td>int32_t or int64_t</td>
  47. * <td>seconds</td>
  48. * <td>Jan 1, 1970</td>
  49. * </tr>
  50. * <tr>
  51. * <td>UDTS_ICU4C_TIME</td>
  52. *
  53. * <td>double</td>
  54. * <td>milliseconds</td>
  55. * <td>Jan 1, 1970</td>
  56. * </tr>
  57. * <tr>
  58. * <td>UDTS_WINDOWS_FILE_TIME</td>
  59. * <td>int64_t</td>
  60. *
  61. * <td>ticks (100 nanoseconds)</td>
  62. * <td>Jan 1, 1601</td>
  63. * </tr>
  64. * <tr>
  65. * <td>UDTS_DOTNET_DATE_TIME</td>
  66. * <td>int64_t</td>
  67. * <td>ticks (100 nanoseconds)</td>
  68. *
  69. * <td>Jan 1, 0001</td>
  70. * </tr>
  71. * <tr>
  72. * <td>UDTS_MAC_OLD_TIME</td>
  73. * <td>int32_t or int64_t</td>
  74. * <td>seconds</td>
  75. * <td>Jan 1, 1904</td>
  76. *
  77. * </tr>
  78. * <tr>
  79. * <td>UDTS_MAC_TIME</td>
  80. * <td>double</td>
  81. * <td>seconds</td>
  82. * <td>Jan 1, 2001</td>
  83. * </tr>
  84. *
  85. * <tr>
  86. * <td>UDTS_EXCEL_TIME</td>
  87. * <td>?</td>
  88. * <td>days</td>
  89. * <td>Dec 31, 1899</td>
  90. * </tr>
  91. * <tr>
  92. *
  93. * <td>UDTS_DB2_TIME</td>
  94. * <td>?</td>
  95. * <td>days</td>
  96. * <td>Dec 31, 1899</td>
  97. * </tr>
  98. *
  99. * <tr>
  100. * <td>UDTS_UNIX_MICROSECONDS_TIME</td>
  101. * <td>int64_t</td>
  102. * <td>microseconds</td>
  103. * <td>Jan 1, 1970</td>
  104. * </tr>
  105. * </table>
  106. *
  107. * <p>
  108. * All of the epochs start at 00:00 am (the earliest possible time on the day in question),
  109. * and are assumed to be UTC.
  110. *
  111. * <p>
  112. * The ranges for different datatypes are given in the following table (all values in years).
  113. * The range of years includes the entire range expressible with positive and negative
  114. * values of the datatype. The range of years for double is the range that would be allowed
  115. * without losing precision to the corresponding unit.
  116. *
  117. * <table border="1" cellspacing="0" cellpadding="4">
  118. * <tr>
  119. * <th align="left">Units</th>
  120. * <th align="left">int64_t</th>
  121. * <th align="left">double</th>
  122. * <th align="left">int32_t</th>
  123. * </tr>
  124. *
  125. * <tr>
  126. * <td>1 sec</td>
  127. * <td align="right">5.84542x10<sup>11</sup></td>
  128. * <td align="right">285,420,920.94</td>
  129. * <td align="right">136.10</td>
  130. * </tr>
  131. * <tr>
  132. *
  133. * <td>1 millisecond</td>
  134. * <td align="right">584,542,046.09</td>
  135. * <td align="right">285,420.92</td>
  136. * <td align="right">0.14</td>
  137. * </tr>
  138. * <tr>
  139. * <td>1 microsecond</td>
  140. *
  141. * <td align="right">584,542.05</td>
  142. * <td align="right">285.42</td>
  143. * <td align="right">0.00</td>
  144. * </tr>
  145. * <tr>
  146. * <td>100 nanoseconds (tick)</td>
  147. * <td align="right">58,454.20</td>
  148. * <td align="right">28.54</td>
  149. * <td align="right">0.00</td>
  150. * </tr>
  151. * <tr>
  152. * <td>1 nanosecond</td>
  153. * <td align="right">584.5420461</td>
  154. * <td align="right">0.2854</td>
  155. * <td align="right">0.00</td>
  156. * </tr>
  157. * </table>
  158. *
  159. * <p>
  160. * These functions implement a universal time scale which can be used as a 'pivot',
  161. * and provide conversion functions to and from all other major time scales.
  162. * This datetimes to be converted to the pivot time, safely manipulated,
  163. * and converted back to any other datetime time scale.
  164. *
  165. *<p>
  166. * So what to use for this pivot? Java time has plenty of range, but cannot represent
  167. * .NET <code>System.DateTime</code> values without severe loss of precision. ICU4C time addresses this by using a
  168. * <code>double</code> that is otherwise equivalent to the Java time. However, there are disadvantages
  169. * with <code>doubles</code>. They provide for much more graceful degradation in arithmetic operations.
  170. * But they only have 53 bits of accuracy, which means that they will lose precision when
  171. * converting back and forth to ticks. What would really be nice would be a
  172. * <code>long double</code> (80 bits -- 64 bit mantissa), but that is not supported on most systems.
  173. *
  174. *<p>
  175. * The Unix extended time uses a structure with two components: time in seconds and a
  176. * fractional field (microseconds). However, this is clumsy, slow, and
  177. * prone to error (you always have to keep track of overflow and underflow in the
  178. * fractional field). <code>BigDecimal</code> would allow for arbitrary precision and arbitrary range,
  179. * but we do not want to use this as the normal type, because it is slow and does not
  180. * have a fixed size.
  181. *
  182. *<p>
  183. * Because of these issues, we ended up concluding that the .NET framework's
  184. * <code>System.DateTime</code> would be the best pivot. However, we use the full range
  185. * allowed by the datatype, allowing for datetimes back to 29,000 BC and up to 29,000 AD.
  186. * This time scale is very fine grained, does not lose precision, and covers a range that
  187. * will meet almost all requirements. It will not handle the range that Java times do,
  188. * but frankly, being able to handle dates before 29,000 BC or after 29,000 AD is of very limited interest.
  189. *
  190. */
  191. /**
  192. * <code>UDateTimeScale</code> values are used to specify the time scale used for
  193. * conversion into or out if the universal time scale.
  194. *
  195. * @stable ICU 3.2
  196. */
  197. typedef enum UDateTimeScale {
  198. /**
  199. * Used in the JDK. Data is a Java <code>long</code> (<code>int64_t</code>). Value
  200. * is milliseconds since January 1, 1970.
  201. *
  202. * @stable ICU 3.2
  203. */
  204. UDTS_JAVA_TIME = 0,
  205. /**
  206. * Used on Unix systems. Data is <code>int32_t</code> or <code>int64_t</code>. Value
  207. * is seconds since January 1, 1970.
  208. *
  209. * @stable ICU 3.2
  210. */
  211. UDTS_UNIX_TIME,
  212. /**
  213. * Used in IUC4C. Data is a <code>double</code>. Value
  214. * is milliseconds since January 1, 1970.
  215. *
  216. * @stable ICU 3.2
  217. */
  218. UDTS_ICU4C_TIME,
  219. /**
  220. * Used in Windows for file times. Data is an <code>int64_t</code>. Value
  221. * is ticks (1 tick == 100 nanoseconds) since January 1, 1601.
  222. *
  223. * @stable ICU 3.2
  224. */
  225. UDTS_WINDOWS_FILE_TIME,
  226. /**
  227. * Used in the .NET framework's <code>System.DateTime</code> structure. Data is an <code>int64_t</code>. Value
  228. * is ticks (1 tick == 100 nanoseconds) since January 1, 0001.
  229. *
  230. * @stable ICU 3.2
  231. */
  232. UDTS_DOTNET_DATE_TIME,
  233. /**
  234. * Used in older Macintosh systems. Data is <code>int32_t</code> or <code>int64_t</code>. Value
  235. * is seconds since January 1, 1904.
  236. *
  237. * @stable ICU 3.2
  238. */
  239. UDTS_MAC_OLD_TIME,
  240. /**
  241. * Used in newer Macintosh systems. Data is a <code>double</code>. Value
  242. * is seconds since January 1, 2001.
  243. *
  244. * @stable ICU 3.2
  245. */
  246. UDTS_MAC_TIME,
  247. /**
  248. * Used in Excel. Data is an <code>?unknown?</code>. Value
  249. * is days since December 31, 1899.
  250. *
  251. * @stable ICU 3.2
  252. */
  253. UDTS_EXCEL_TIME,
  254. /**
  255. * Used in DB2. Data is an <code>?unknown?</code>. Value
  256. * is days since December 31, 1899.
  257. *
  258. * @stable ICU 3.2
  259. */
  260. UDTS_DB2_TIME,
  261. /**
  262. * Data is a <code>long</code>. Value is microseconds since January 1, 1970.
  263. * Similar to Unix time (linear value from 1970) and struct timeval
  264. * (microseconds resolution).
  265. *
  266. * @stable ICU 3.8
  267. */
  268. UDTS_UNIX_MICROSECONDS_TIME,
  269. /**
  270. * The first unused time scale value. The limit of this enum
  271. */
  272. UDTS_MAX_SCALE
  273. } UDateTimeScale;
  274. /**
  275. * <code>UTimeScaleValue</code> values are used to specify the time scale values
  276. * to <code>utmscale_getTimeScaleValue</code>.
  277. *
  278. * @see utmscale_getTimeScaleValue
  279. *
  280. * @stable ICU 3.2
  281. */
  282. typedef enum UTimeScaleValue {
  283. /**
  284. * The constant used to select the units vale
  285. * for a time scale.
  286. *
  287. * @see utmscale_getTimeScaleValue
  288. *
  289. * @stable ICU 3.2
  290. */
  291. UTSV_UNITS_VALUE = 0,
  292. /**
  293. * The constant used to select the epoch offset value
  294. * for a time scale.
  295. *
  296. * @see utmscale_getTimeScaleValue
  297. *
  298. * @stable ICU 3.2
  299. */
  300. UTSV_EPOCH_OFFSET_VALUE=1,
  301. /**
  302. * The constant used to select the minimum from value
  303. * for a time scale.
  304. *
  305. * @see utmscale_getTimeScaleValue
  306. *
  307. * @stable ICU 3.2
  308. */
  309. UTSV_FROM_MIN_VALUE=2,
  310. /**
  311. * The constant used to select the maximum from value
  312. * for a time scale.
  313. *
  314. * @see utmscale_getTimeScaleValue
  315. *
  316. * @stable ICU 3.2
  317. */
  318. UTSV_FROM_MAX_VALUE=3,
  319. /**
  320. * The constant used to select the minimum to value
  321. * for a time scale.
  322. *
  323. * @see utmscale_getTimeScaleValue
  324. *
  325. * @stable ICU 3.2
  326. */
  327. UTSV_TO_MIN_VALUE=4,
  328. /**
  329. * The constant used to select the maximum to value
  330. * for a time scale.
  331. *
  332. * @see utmscale_getTimeScaleValue
  333. *
  334. * @stable ICU 3.2
  335. */
  336. UTSV_TO_MAX_VALUE=5,
  337. #ifndef U_HIDE_INTERNAL_API
  338. /**
  339. * The constant used to select the epoch plus one value
  340. * for a time scale.
  341. *
  342. * NOTE: This is an internal value. DO NOT USE IT. May not
  343. * actually be equal to the epoch offset value plus one.
  344. *
  345. * @see utmscale_getTimeScaleValue
  346. *
  347. * @internal ICU 3.2
  348. */
  349. UTSV_EPOCH_OFFSET_PLUS_1_VALUE=6,
  350. /**
  351. * The constant used to select the epoch plus one value
  352. * for a time scale.
  353. *
  354. * NOTE: This is an internal value. DO NOT USE IT. May not
  355. * actually be equal to the epoch offset value plus one.
  356. *
  357. * @see utmscale_getTimeScaleValue
  358. *
  359. * @internal ICU 3.2
  360. */
  361. UTSV_EPOCH_OFFSET_MINUS_1_VALUE=7,
  362. /**
  363. * The constant used to select the units round value
  364. * for a time scale.
  365. *
  366. * NOTE: This is an internal value. DO NOT USE IT.
  367. *
  368. * @see utmscale_getTimeScaleValue
  369. *
  370. * @internal ICU 3.2
  371. */
  372. UTSV_UNITS_ROUND_VALUE=8,
  373. /**
  374. * The constant used to select the minimum safe rounding value
  375. * for a time scale.
  376. *
  377. * NOTE: This is an internal value. DO NOT USE IT.
  378. *
  379. * @see utmscale_getTimeScaleValue
  380. *
  381. * @internal ICU 3.2
  382. */
  383. UTSV_MIN_ROUND_VALUE=9,
  384. /**
  385. * The constant used to select the maximum safe rounding value
  386. * for a time scale.
  387. *
  388. * NOTE: This is an internal value. DO NOT USE IT.
  389. *
  390. * @see utmscale_getTimeScaleValue
  391. *
  392. * @internal ICU 3.2
  393. */
  394. UTSV_MAX_ROUND_VALUE=10,
  395. #endif /* U_HIDE_INTERNAL_API */
  396. /**
  397. * The number of time scale values, in other words limit of this enum.
  398. *
  399. * @see utmscale_getTimeScaleValue
  400. */
  401. UTSV_MAX_SCALE_VALUE=11
  402. } UTimeScaleValue;
  403. /**
  404. * Get a value associated with a particular time scale.
  405. *
  406. * @param timeScale The time scale
  407. * @param value A constant representing the value to get
  408. * @param status The status code. Set to <code>U_ILLEGAL_ARGUMENT_ERROR</code> if arguments are invalid.
  409. * @return - the value.
  410. *
  411. * @stable ICU 3.2
  412. */
  413. U_STABLE int64_t U_EXPORT2
  414. utmscale_getTimeScaleValue(UDateTimeScale timeScale, UTimeScaleValue value, UErrorCode *status);
  415. /* Conversion to 'universal time scale' */
  416. /**
  417. * Convert a <code>int64_t</code> datetime from the given time scale to the universal time scale.
  418. *
  419. * @param otherTime The <code>int64_t</code> datetime
  420. * @param timeScale The time scale to convert from
  421. * @param status The status code. Set to <code>U_ILLEGAL_ARGUMENT_ERROR</code> if the conversion is out of range.
  422. *
  423. * @return The datetime converted to the universal time scale
  424. *
  425. * @stable ICU 3.2
  426. */
  427. U_STABLE int64_t U_EXPORT2
  428. utmscale_fromInt64(int64_t otherTime, UDateTimeScale timeScale, UErrorCode *status);
  429. /* Conversion from 'universal time scale' */
  430. /**
  431. * Convert a datetime from the universal time scale to a <code>int64_t</code> in the given time scale.
  432. *
  433. * @param universalTime The datetime in the universal time scale
  434. * @param timeScale The time scale to convert to
  435. * @param status The status code. Set to <code>U_ILLEGAL_ARGUMENT_ERROR</code> if the conversion is out of range.
  436. *
  437. * @return The datetime converted to the given time scale
  438. *
  439. * @stable ICU 3.2
  440. */
  441. U_STABLE int64_t U_EXPORT2
  442. utmscale_toInt64(int64_t universalTime, UDateTimeScale timeScale, UErrorCode *status);
  443. #endif /* #if !UCONFIG_NO_FORMATTING */
  444. #endif