Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:13:16

0001 // © 2016 and later: Unicode, Inc. and others.
0002 // License & terms of use: http://www.unicode.org/copyright.html
0003 /*
0004 *******************************************************************************
0005 * Copyright (C) 2004 - 2008, International Business Machines Corporation and
0006 * others. All Rights Reserved.
0007 *******************************************************************************
0008 */
0009 
0010 #ifndef UTMSCALE_H
0011 #define UTMSCALE_H
0012 
0013 #include "unicode/utypes.h"
0014 
0015 #if !UCONFIG_NO_FORMATTING
0016 
0017 /** 
0018  * \file
0019  * \brief C API: Universal Time Scale
0020  *
0021  * There are quite a few different conventions for binary datetime, depending on different
0022  * platforms and protocols. Some of these have severe drawbacks. For example, people using
0023  * Unix time (seconds since Jan 1, 1970) think that they are safe until near the year 2038.
0024  * But cases can and do arise where arithmetic manipulations causes serious problems. Consider
0025  * the computation of the average of two datetimes, for example: if one calculates them with
0026  * <code>averageTime = (time1 + time2)/2</code>, there will be overflow even with dates
0027  * around the present. Moreover, even if these problems don't occur, there is the issue of
0028  * conversion back and forth between different systems.
0029  *
0030  * <p>
0031  * Binary datetimes differ in a number of ways: the datatype, the unit,
0032  * and the epoch (origin). We'll refer to these as time scales. For example:
0033  *
0034  * <table border="1" cellspacing="0" cellpadding="4">
0035  *  <caption>Table 1: Binary Time Scales</caption>
0036  *  <tr>
0037  *    <th align="left">Source</th>
0038  *    <th align="left">Datatype</th>
0039  *    <th align="left">Unit</th>
0040  *    <th align="left">Epoch</th>
0041  *  </tr>
0042  *
0043  *  <tr>
0044  *    <td>UDTS_JAVA_TIME</td>
0045  *    <td>int64_t</td>
0046  *    <td>milliseconds</td>
0047  *    <td>Jan 1, 1970</td>
0048  *  </tr>
0049  *  <tr>
0050  *
0051  *    <td>UDTS_UNIX_TIME</td>
0052  *    <td>int32_t or int64_t</td>
0053  *    <td>seconds</td>
0054  *    <td>Jan 1, 1970</td>
0055  *  </tr>
0056  *  <tr>
0057  *    <td>UDTS_ICU4C_TIME</td>
0058  *
0059  *    <td>double</td>
0060  *    <td>milliseconds</td>
0061  *    <td>Jan 1, 1970</td>
0062  *  </tr>
0063  *  <tr>
0064  *    <td>UDTS_WINDOWS_FILE_TIME</td>
0065  *    <td>int64_t</td>
0066  *
0067  *    <td>ticks (100 nanoseconds)</td>
0068  *    <td>Jan 1, 1601</td>
0069  *  </tr>
0070  *  <tr>
0071  *    <td>UDTS_DOTNET_DATE_TIME</td>
0072  *    <td>int64_t</td>
0073  *    <td>ticks (100 nanoseconds)</td>
0074  *
0075  *    <td>Jan 1, 0001</td>
0076  *  </tr>
0077  *  <tr>
0078  *    <td>UDTS_MAC_OLD_TIME</td>
0079  *    <td>int32_t or int64_t</td>
0080  *    <td>seconds</td>
0081  *    <td>Jan 1, 1904</td>
0082  *
0083  *  </tr>
0084  *  <tr>
0085  *    <td>UDTS_MAC_TIME</td>
0086  *    <td>double</td>
0087  *    <td>seconds</td>
0088  *    <td>Jan 1, 2001</td>
0089  *  </tr>
0090  *
0091  *  <tr>
0092  *    <td>UDTS_EXCEL_TIME</td>
0093  *    <td>?</td>
0094  *    <td>days</td>
0095  *    <td>Dec 31, 1899</td>
0096  *  </tr>
0097  *  <tr>
0098  *
0099  *    <td>UDTS_DB2_TIME</td>
0100  *    <td>?</td>
0101  *    <td>days</td>
0102  *    <td>Dec 31, 1899</td>
0103  *  </tr>
0104  *
0105  *  <tr>
0106  *    <td>UDTS_UNIX_MICROSECONDS_TIME</td>
0107  *    <td>int64_t</td>
0108  *    <td>microseconds</td>
0109  *    <td>Jan 1, 1970</td>
0110  *  </tr>
0111  * </table>
0112  *
0113  * <p>
0114  * All of the epochs start at 00:00 am (the earliest possible time on the day in question),
0115  * and are assumed to be UTC.
0116  *
0117  * <p>
0118  * The ranges for different datatypes are given in the following table (all values in years).
0119  * The range of years includes the entire range expressible with positive and negative
0120  * values of the datatype. The range of years for double is the range that would be allowed
0121  * without losing precision to the corresponding unit.
0122  *
0123  * <table border="1" cellspacing="0" cellpadding="4">
0124  *  <tr>
0125  *    <th align="left">Units</th>
0126  *    <th align="left">int64_t</th>
0127  *    <th align="left">double</th>
0128  *    <th align="left">int32_t</th>
0129  *  </tr>
0130  *
0131  *  <tr>
0132  *    <td>1 sec</td>
0133  *    <td align="right">5.84542x10<sup>11</sup></td>
0134  *    <td align="right">285,420,920.94</td>
0135  *    <td align="right">136.10</td>
0136  *  </tr>
0137  *  <tr>
0138  *
0139  *    <td>1 millisecond</td>
0140  *    <td align="right">584,542,046.09</td>
0141  *    <td align="right">285,420.92</td>
0142  *    <td align="right">0.14</td>
0143  *  </tr>
0144  *  <tr>
0145  *    <td>1 microsecond</td>
0146  *
0147  *    <td align="right">584,542.05</td>
0148  *    <td align="right">285.42</td>
0149  *    <td align="right">0.00</td>
0150  *  </tr>
0151  *  <tr>
0152  *    <td>100 nanoseconds (tick)</td>
0153  *    <td align="right">58,454.20</td>
0154  *    <td align="right">28.54</td>
0155  *    <td align="right">0.00</td>
0156  *  </tr>
0157  *  <tr>
0158  *    <td>1 nanosecond</td>
0159  *    <td align="right">584.5420461</td>
0160  *    <td align="right">0.2854</td>
0161  *    <td align="right">0.00</td>
0162  *  </tr>
0163  * </table>
0164  *
0165  * <p>
0166  * These functions implement a universal time scale which can be used as a 'pivot',
0167  * and provide conversion functions to and from all other major time scales.
0168  * This datetimes to be converted to the pivot time, safely manipulated,
0169  * and converted back to any other datetime time scale.
0170  *
0171  *<p>
0172  * So what to use for this pivot? Java time has plenty of range, but cannot represent
0173  * .NET <code>System.DateTime</code> values without severe loss of precision. ICU4C time addresses this by using a
0174  * <code>double</code> that is otherwise equivalent to the Java time. However, there are disadvantages
0175  * with <code>doubles</code>. They provide for much more graceful degradation in arithmetic operations.
0176  * But they only have 53 bits of accuracy, which means that they will lose precision when
0177  * converting back and forth to ticks. What would really be nice would be a
0178  * <code>long double</code> (80 bits -- 64 bit mantissa), but that is not supported on most systems.
0179  *
0180  *<p>
0181  * The Unix extended time uses a structure with two components: time in seconds and a
0182  * fractional field (microseconds). However, this is clumsy, slow, and
0183  * prone to error (you always have to keep track of overflow and underflow in the
0184  * fractional field). <code>BigDecimal</code> would allow for arbitrary precision and arbitrary range,
0185  * but we do not want to use this as the normal type, because it is slow and does not
0186  * have a fixed size.
0187  *
0188  *<p>
0189  * Because of these issues, we ended up concluding that the .NET framework's
0190  * <code>System.DateTime</code> would be the best pivot. However, we use the full range
0191  * allowed by the datatype, allowing for datetimes back to 29,000 BC and up to 29,000 AD.
0192  * This time scale is very fine grained, does not lose precision, and covers a range that
0193  * will meet almost all requirements. It will not handle the range that Java times do,
0194  * but frankly, being able to handle dates before 29,000 BC or after 29,000 AD is of very limited interest.
0195  *
0196  */
0197 
0198 /**
0199  * <code>UDateTimeScale</code> values are used to specify the time scale used for
0200  * conversion into or out if the universal time scale.
0201  *
0202  * @stable ICU 3.2
0203  */
0204 typedef enum UDateTimeScale {
0205     /**
0206      * Used in the JDK. Data is a Java <code>long</code> (<code>int64_t</code>). Value
0207      * is milliseconds since January 1, 1970.
0208      *
0209      * @stable ICU 3.2
0210      */
0211     UDTS_JAVA_TIME = 0,
0212 
0213     /**
0214      * Used on Unix systems. Data is <code>int32_t</code> or <code>int64_t</code>. Value
0215      * is seconds since January 1, 1970.
0216      *
0217      * @stable ICU 3.2
0218      */
0219     UDTS_UNIX_TIME,
0220     
0221     /**
0222      * Used in IUC4C. Data is a <code>double</code>. Value
0223      * is milliseconds since January 1, 1970.
0224      *
0225      * @stable ICU 3.2
0226      */
0227     UDTS_ICU4C_TIME,
0228     
0229     /**
0230      * Used in Windows for file times. Data is an <code>int64_t</code>. Value
0231      * is ticks (1 tick == 100 nanoseconds) since January 1, 1601.
0232      *
0233      * @stable ICU 3.2
0234      */
0235     UDTS_WINDOWS_FILE_TIME,
0236     
0237     /**
0238      * Used in the .NET framework's <code>System.DateTime</code> structure. Data is an <code>int64_t</code>. Value
0239      * is ticks (1 tick == 100 nanoseconds) since January 1, 0001.
0240      *
0241      * @stable ICU 3.2
0242      */
0243     UDTS_DOTNET_DATE_TIME,
0244     
0245     /**
0246      * Used in older Macintosh systems. Data is <code>int32_t</code> or <code>int64_t</code>. Value
0247      * is seconds since January 1, 1904.
0248      *
0249      * @stable ICU 3.2
0250      */
0251     UDTS_MAC_OLD_TIME,
0252     
0253     /**
0254      * Used in newer Macintosh systems. Data is a <code>double</code>. Value
0255      * is seconds since January 1, 2001.
0256      *
0257      * @stable ICU 3.2
0258      */
0259     UDTS_MAC_TIME,
0260     
0261     /**
0262      * Used in Excel. Data is an <code>?unknown?</code>. Value
0263      * is days since December 31, 1899.
0264      *
0265      * @stable ICU 3.2
0266      */
0267     UDTS_EXCEL_TIME,
0268     
0269     /**
0270      * Used in DB2. Data is an <code>?unknown?</code>. Value
0271      * is days since December 31, 1899.
0272      *
0273      * @stable ICU 3.2
0274      */
0275     UDTS_DB2_TIME,
0276 
0277     /**
0278      * Data is a <code>long</code>. Value is microseconds since January 1, 1970.
0279      * Similar to Unix time (linear value from 1970) and struct timeval
0280      * (microseconds resolution).
0281      *
0282      * @stable ICU 3.8
0283      */
0284     UDTS_UNIX_MICROSECONDS_TIME,
0285 
0286 #ifndef U_HIDE_DEPRECATED_API
0287     /**
0288      * The first unused time scale value. The limit of this enum
0289      * @deprecated ICU 59 The numeric value may change over time, see ICU ticket #12420.
0290      */
0291     UDTS_MAX_SCALE
0292 #endif  /* U_HIDE_DEPRECATED_API */
0293 
0294 } UDateTimeScale;
0295 
0296 /**
0297  * <code>UTimeScaleValue</code> values are used to specify the time scale values
0298  * to <code>utmscale_getTimeScaleValue</code>.
0299  *
0300  * @see utmscale_getTimeScaleValue
0301  *
0302  * @stable ICU 3.2
0303  */
0304 typedef enum UTimeScaleValue {
0305     /**
0306      * The constant used to select the units vale
0307      * for a time scale.
0308      * 
0309      * @see utmscale_getTimeScaleValue
0310      *
0311      * @stable ICU 3.2
0312      */
0313     UTSV_UNITS_VALUE = 0,
0314 
0315     /**
0316      * The constant used to select the epoch offset value
0317      * for a time scale.
0318      * 
0319      * @see utmscale_getTimeScaleValue
0320      *
0321      * @stable ICU 3.2
0322      */
0323     UTSV_EPOCH_OFFSET_VALUE=1,
0324 
0325     /**
0326      * The constant used to select the minimum from value
0327      * for a time scale.
0328      * 
0329      * @see utmscale_getTimeScaleValue
0330      *
0331      * @stable ICU 3.2
0332      */
0333     UTSV_FROM_MIN_VALUE=2,
0334 
0335     /**
0336      * The constant used to select the maximum from value
0337      * for a time scale.
0338      * 
0339      * @see utmscale_getTimeScaleValue
0340      *
0341      * @stable ICU 3.2
0342      */
0343     UTSV_FROM_MAX_VALUE=3,
0344 
0345     /**
0346      * The constant used to select the minimum to value
0347      * for a time scale.
0348      * 
0349      * @see utmscale_getTimeScaleValue
0350      *
0351      * @stable ICU 3.2
0352      */
0353     UTSV_TO_MIN_VALUE=4,
0354 
0355     /**
0356      * The constant used to select the maximum to value
0357      * for a time scale.
0358      * 
0359      * @see utmscale_getTimeScaleValue
0360      *
0361      * @stable ICU 3.2
0362      */
0363     UTSV_TO_MAX_VALUE=5,
0364 
0365 #ifndef U_HIDE_INTERNAL_API
0366     /**
0367      * The constant used to select the epoch plus one value
0368      * for a time scale.
0369      * 
0370      * NOTE: This is an internal value. DO NOT USE IT. May not
0371      * actually be equal to the epoch offset value plus one.
0372      * 
0373      * @see utmscale_getTimeScaleValue
0374      *
0375      * @internal ICU 3.2
0376      */
0377     UTSV_EPOCH_OFFSET_PLUS_1_VALUE=6,
0378 
0379     /**
0380      * The constant used to select the epoch plus one value
0381      * for a time scale.
0382      * 
0383      * NOTE: This is an internal value. DO NOT USE IT. May not
0384      * actually be equal to the epoch offset value plus one.
0385      * 
0386      * @see utmscale_getTimeScaleValue
0387      *
0388      * @internal ICU 3.2
0389      */
0390     UTSV_EPOCH_OFFSET_MINUS_1_VALUE=7,
0391 
0392     /**
0393      * The constant used to select the units round value
0394      * for a time scale.
0395      * 
0396      * NOTE: This is an internal value. DO NOT USE IT.
0397      * 
0398      * @see utmscale_getTimeScaleValue
0399      *
0400      * @internal ICU 3.2
0401      */
0402     UTSV_UNITS_ROUND_VALUE=8,
0403 
0404     /**
0405      * The constant used to select the minimum safe rounding value
0406      * for a time scale.
0407      * 
0408      * NOTE: This is an internal value. DO NOT USE IT.
0409      * 
0410      * @see utmscale_getTimeScaleValue
0411      *
0412      * @internal ICU 3.2
0413      */
0414     UTSV_MIN_ROUND_VALUE=9,
0415 
0416     /**
0417      * The constant used to select the maximum safe rounding value
0418      * for a time scale.
0419      * 
0420      * NOTE: This is an internal value. DO NOT USE IT.
0421      * 
0422      * @see utmscale_getTimeScaleValue
0423      *
0424      * @internal ICU 3.2
0425      */
0426     UTSV_MAX_ROUND_VALUE=10,
0427 
0428 #endif /* U_HIDE_INTERNAL_API */
0429 
0430 #ifndef U_HIDE_DEPRECATED_API
0431     /**
0432      * The number of time scale values, in other words limit of this enum.
0433      * 
0434      * @see utmscale_getTimeScaleValue
0435      * @deprecated ICU 59 The numeric value may change over time, see ICU ticket #12420.
0436      */
0437     UTSV_MAX_SCALE_VALUE=11
0438 #endif  /* U_HIDE_DEPRECATED_API */
0439 
0440 } UTimeScaleValue;
0441 
0442 /**
0443  * Get a value associated with a particular time scale.
0444  * 
0445  * @param timeScale The time scale
0446  * @param value A constant representing the value to get
0447  * @param status The status code. Set to <code>U_ILLEGAL_ARGUMENT_ERROR</code> if arguments are invalid.
0448  * @return - the value.
0449  * 
0450  * @stable ICU 3.2
0451  */
0452 U_CAPI int64_t U_EXPORT2
0453     utmscale_getTimeScaleValue(UDateTimeScale timeScale, UTimeScaleValue value, UErrorCode *status);
0454 
0455 /* Conversion to 'universal time scale' */
0456 
0457 /**
0458  * Convert a <code>int64_t</code> datetime from the given time scale to the universal time scale.
0459  *
0460  * @param otherTime The <code>int64_t</code> datetime
0461  * @param timeScale The time scale to convert from
0462  * @param status The status code. Set to <code>U_ILLEGAL_ARGUMENT_ERROR</code> if the conversion is out of range.
0463  * 
0464  * @return The datetime converted to the universal time scale
0465  *
0466  * @stable ICU 3.2
0467  */
0468 U_CAPI int64_t U_EXPORT2
0469     utmscale_fromInt64(int64_t otherTime, UDateTimeScale timeScale, UErrorCode *status);
0470 
0471 /* Conversion from 'universal time scale' */
0472 
0473 /**
0474  * Convert a datetime from the universal time scale to a <code>int64_t</code> in the given time scale.
0475  *
0476  * @param universalTime The datetime in the universal time scale
0477  * @param timeScale The time scale to convert to
0478  * @param status The status code. Set to <code>U_ILLEGAL_ARGUMENT_ERROR</code> if the conversion is out of range.
0479  * 
0480  * @return The datetime converted to the given time scale
0481  *
0482  * @stable ICU 3.2
0483  */
0484 U_CAPI int64_t U_EXPORT2
0485     utmscale_toInt64(int64_t universalTime, UDateTimeScale timeScale, UErrorCode *status);
0486 
0487 #endif /* #if !UCONFIG_NO_FORMATTING */
0488 
0489 #endif
0490