17935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/* 27935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ********************************************************************************* 37935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Copyright (C) 2004-2014, International Business Machines Corporation and * 47935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * others. All Rights Reserved. * 57935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ********************************************************************************* 67935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 77935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 87935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 97935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertpackage com.ibm.icu.util; 107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.math.BigDecimal; 127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/** 147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * There are quite a few different conventions for binary datetime, depending on different 157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * platforms and protocols. Some of these have severe drawbacks. For example, people using 167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Unix time (seconds since Jan 1, 1970, usually in a 32-bit integer) 177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * think that they are safe until near the year 2038. 187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * But cases can and do arise where arithmetic manipulations causes serious problems. Consider 197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * the computation of the average of two datetimes, for example: if one calculates them with 207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <code>averageTime = (time1 + time2)/2</code>, there will be overflow even with dates 217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * beginning in 2004. Moreover, even if these problems don't occur, there is the issue of 227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * conversion back and forth between different systems. 237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <p>Binary datetimes differ in a number of ways: the datatype, the unit, 257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * and the epoch (origin). We refer to these as time scales.</p> 267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <p>ICU implements a universal time scale that is similar to the 287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * .NET framework's System.DateTime. The universal time scale is a 297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 64-bit integer that holds ticks since midnight, January 1st, 0001. 307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * (One tick is 100 nanoseconds.) 317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Negative values are supported. This has enough range to guarantee that 327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * calculations involving dates around the present are safe.</p> 337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <p>The universal time scale always measures time according to the 357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * proleptic Gregorian calendar. That is, the Gregorian calendar's 367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * leap year rules are used for all times, even before 1582 when it was 377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * introduced. (This is different from the default ICU calendar which 387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * switches from the Julian to the Gregorian calendar in 1582. 397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * See GregorianCalendar.setGregorianChange() and ucal_setGregorianChange().)</p> 407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * ICU provides conversion functions to and from all other major time 427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * scales, allowing datetimes in any time scale to be converted to the 437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * universal time scale, safely manipulated, and converted back to any other 447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * datetime time scale.</p> 457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <p>For more details and background, see the 477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <a href="http://www.icu-project.org/userguide/universalTimeScale.html">Universal Time Scale</a> 487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * chapter in the ICU User Guide.</p> 497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @stable ICU 3.2 517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertpublic final class UniversalTimeScale 547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert{ 557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Used in the JDK. Data is a <code>long</code>. Value 577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * is milliseconds since January 1, 1970. 587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @stable ICU 3.2 607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public static final int JAVA_TIME = 0; 627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Used in Unix systems. Data is an <code>int</code> or a <code>long</code>. Value 657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * is seconds since January 1, 1970. 667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @stable ICU 3.2 687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public static final int UNIX_TIME = 1; 707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Used in the ICU4C. Data is a <code>double</code>. Value 737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * is milliseconds since January 1, 1970. 747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @stable ICU 3.2 767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public static final int ICU4C_TIME = 2; 787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Used in Windows for file times. Data is a <code>long</code>. Value 817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * is ticks (1 tick == 100 nanoseconds) since January 1, 1601. 827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @stable ICU 3.2 847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public static final int WINDOWS_FILE_TIME = 3; 867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Used in the .NET framework's <code>System.DateTime</code> structure. 897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Data is a <code>long</code>. Value is ticks (1 tick == 100 nanoseconds) since January 1, 0001. 907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @stable ICU 3.2 927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public static final int DOTNET_DATE_TIME = 4; 947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Used in older Macintosh systems. Data is an <code>int</code>. Value 977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * is seconds since January 1, 1904. 987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @stable ICU 3.2 1007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 1017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public static final int MAC_OLD_TIME = 5; 1027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 1047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Used in the JDK. Data is a <code>double</code>. Value 1057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * is milliseconds since January 1, 2001. 1067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 1077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @stable ICU 3.2 1087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 1097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public static final int MAC_TIME = 6; 1107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 1127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Used in Excel. Data is a <code>?unknown?</code>. Value 1137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * is days since December 31, 1899. 1147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 1157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @stable ICU 3.2 1167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 1177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public static final int EXCEL_TIME = 7; 1187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 1207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Used in DB2. Data is a <code>?unknown?</code>. Value 1217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * is days since December 31, 1899. 1227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 1237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @stable ICU 3.2 1247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 1257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public static final int DB2_TIME = 8; 1267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 1287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Data is a <code>long</code>. Value is microseconds since January 1, 1970. 1297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Similar to Unix time (linear value from 1970) and struct timeval 1307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * (microseconds resolution). 1317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 1327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @stable ICU 3.8 1337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 1347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public static final int UNIX_MICROSECONDS_TIME = 9; 1357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 1377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * This is the first unused time scale value. 1387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 1397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @stable ICU 3.2 1407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 1417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public static final int MAX_SCALE = 10; 1427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 1447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * The constant used to select the units value 1457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * for a time scale. 1467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 1477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 1487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @stable ICU 3.2 1497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 1507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public static final int UNITS_VALUE = 0; 1517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 1537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * The constant used to select the epoch offset value 1547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * for a time scale. 1557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 1567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @see #getTimeScaleValue 1577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 1587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @stable ICU 3.2 1597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 1607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public static final int EPOCH_OFFSET_VALUE = 1; 1617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 1637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * The constant used to select the minimum from value 1647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * for a time scale. 1657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 1667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @see #getTimeScaleValue 1677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 1687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @stable ICU 3.2 1697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 1707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public static final int FROM_MIN_VALUE = 2; 1717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 1737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * The constant used to select the maximum from value 1747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * for a time scale. 1757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 1767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @see #getTimeScaleValue 1777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 1787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @stable ICU 3.2 1797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 1807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public static final int FROM_MAX_VALUE = 3; 1817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 1837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * The constant used to select the minimum to value 1847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * for a time scale. 1857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 1867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @see #getTimeScaleValue 1877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 1887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @stable ICU 3.2 1897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 1907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public static final int TO_MIN_VALUE = 4; 1917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 1937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * The constant used to select the maximum to value 1947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * for a time scale. 1957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 1967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @see #getTimeScaleValue 1977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 1987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @stable ICU 3.2 1997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 2007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public static final int TO_MAX_VALUE = 5; 2017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 2027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 2037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * The constant used to select the epoch plus one value 2047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * for a time scale. 2057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 2067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * NOTE: This is an internal value. DO NOT USE IT. May not 2077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * actually be equal to the epoch offset value plus one. 2087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 2097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @see #getTimeScaleValue 2107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 2117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @stable ICU 3.2 2127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 2137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public static final int EPOCH_OFFSET_PLUS_1_VALUE = 6; 2147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 2157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 2167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * The constant used to select the epoch offset minus one value 2177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * for a time scale. 2187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 2197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * NOTE: This is an internal value. DO NOT USE IT. May not 2207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * actually be equal to the epoch offset value minus one. 2217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 2227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @see #getTimeScaleValue 2237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 2247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @internal 2257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @deprecated This API is ICU internal only. 2267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 2277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert @Deprecated 2287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public static final int EPOCH_OFFSET_MINUS_1_VALUE = 7; 2297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 2307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 2317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * The constant used to select the units round value 2327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * for a time scale. 2337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 2347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * NOTE: This is an internal value. DO NOT USE IT. 2357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 2367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @see #getTimeScaleValue 2377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 2387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @internal 2397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @deprecated This API is ICU internal only. 2407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 2417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert @Deprecated 2427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public static final int UNITS_ROUND_VALUE = 8; 2437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 2447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 2457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * The constant used to select the minimum safe rounding value 2467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * for a time scale. 2477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 2487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * NOTE: This is an internal value. DO NOT USE IT. 2497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 2507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @see #getTimeScaleValue 2517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 2527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @internal 2537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @deprecated This API is ICU internal only. 2547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 2557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert @Deprecated 2567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public static final int MIN_ROUND_VALUE = 9; 2577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 2587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 2597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * The constant used to select the maximum safe rounding value 2607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * for a time scale. 2617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 2627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * NOTE: This is an internal value. DO NOT USE IT. 2637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 2647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @see #getTimeScaleValue 2657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 2667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @internal 2677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @deprecated This API is ICU internal only. 2687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 2697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert @Deprecated 2707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public static final int MAX_ROUND_VALUE = 10; 2717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 2727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 2737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * The number of time scale values. 2747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 2757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * NOTE: This is an internal value. DO NOT USE IT. 2767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 2777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @see #getTimeScaleValue 2787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 2797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @internal 2807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @deprecated This API is ICU internal only. 2817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 2827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert @Deprecated 2837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public static final int MAX_SCALE_VALUE = 11; 2847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 2857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private static final long ticks = 1; 2867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private static final long microseconds = ticks * 10; 2877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private static final long milliseconds = microseconds * 1000; 2887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private static final long seconds = milliseconds * 1000; 2897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private static final long minutes = seconds * 60; 2907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private static final long hours = minutes * 60; 2917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private static final long days = hours * 24; 2927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 2937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 2947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * This class holds the data that describes a particular 2957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * time scale. 2967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 2977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private static final class TimeScaleData 2987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert { 2997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert TimeScaleData(long theUnits, long theEpochOffset, 3007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert long theToMin, long theToMax, 3017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert long theFromMin, long theFromMax) 3027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert { 3037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert units = theUnits; 3047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert unitsRound = theUnits / 2; 3057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert minRound = Long.MIN_VALUE + unitsRound; 3077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert maxRound = Long.MAX_VALUE - unitsRound; 3087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert epochOffset = theEpochOffset / theUnits; 3107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (theUnits == 1) { 3127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert epochOffsetP1 = epochOffsetM1 = epochOffset; 3137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else { 3147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert epochOffsetP1 = epochOffset + 1; 3157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert epochOffsetM1 = epochOffset - 1; 3167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 3177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert toMin = theToMin; 3197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert toMax = theToMax; 3207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert fromMin = theFromMin; 3227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert fromMax = theFromMax; 3237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 3247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert long units; 3267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert long epochOffset; 3277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert long fromMin; 3287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert long fromMax; 3297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert long toMin; 3307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert long toMax; 3317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert long epochOffsetP1; 3337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert long epochOffsetM1; 3347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert long unitsRound; 3357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert long minRound; 3367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert long maxRound; 3377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 3387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private static final TimeScaleData[] timeScaleTable = { 3407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert new TimeScaleData(milliseconds, 621355968000000000L, -9223372036854774999L, 9223372036854774999L, -984472800485477L, 860201606885477L), // JAVA_TIME 3417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert new TimeScaleData(seconds, 621355968000000000L, -9223372036854775808L, 9223372036854775807L, -984472800485L, 860201606885L), // UNIX_TIME 3427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert new TimeScaleData(milliseconds, 621355968000000000L, -9223372036854774999L, 9223372036854774999L, -984472800485477L, 860201606885477L), // ICU4C_TIME 3437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert new TimeScaleData(ticks, 504911232000000000L, -8718460804854775808L, 9223372036854775807L, -9223372036854775808L, 8718460804854775807L), // WINDOWS_FILE_TIME 3447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert new TimeScaleData(ticks, 000000000000000000L, -9223372036854775808L, 9223372036854775807L, -9223372036854775808L, 9223372036854775807L), // DOTNET_DATE_TIME 3457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert new TimeScaleData(seconds, 600527520000000000L, -9223372036854775808L, 9223372036854775807L, -982389955685L, 862284451685L), // MAC_OLD_TIME 3467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert new TimeScaleData(seconds, 631139040000000000L, -9223372036854775808L, 9223372036854775807L, -985451107685L, 859223299685L), // MAC_TIME 3477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert new TimeScaleData(days, 599265216000000000L, -9223372036854775808L, 9223372036854775807L, -11368793L, 9981605L), // EXCEL_TIME 3487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert new TimeScaleData(days, 599265216000000000L, -9223372036854775808L, 9223372036854775807L, -11368793L, 9981605L), // DB2_TIME 3497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert new TimeScaleData(microseconds, 621355968000000000L, -9223372036854775804L, 9223372036854775804L, -984472800485477580L, 860201606885477580L) // UNIX_MICROSECONDS_TIME 3507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert }; 3517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /* 3547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Prevent construction of this class. 3557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 3567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ///CLOVER:OFF 3577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private UniversalTimeScale() 3587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert { 3597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // nothing to do 3607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 3617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ///CLOVER:ON 3627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 3647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Convert a <code>long</code> datetime from the given time scale to the universal time scale. 3657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 3667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param otherTime The <code>long</code> datetime 3677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param timeScale The time scale to convert from 3687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 3697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @return The datetime converted to the universal time scale 3707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 3717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @stable ICU 3.2 3727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 3737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public static long from(long otherTime, int timeScale) 3747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert { 3757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert TimeScaleData data = fromRangeCheck(otherTime, timeScale); 3767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return (otherTime + data.epochOffset) * data.units; 3787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 3797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 3817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Convert a <code>double</code> datetime from the given time scale to the universal time scale. 3827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * All calculations are done using <code>BigDecimal</code> to guarantee that the value 3837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * does not go out of range. 3847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 3857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param otherTime The <code>double</code> datetime 3867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param timeScale The time scale to convert from 3877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 3887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @return The datetime converted to the universal time scale 3897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 3907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @stable ICU 3.2 3917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 3927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public static BigDecimal bigDecimalFrom(double otherTime, int timeScale) 3937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert { 3947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert TimeScaleData data = getTimeScaleData(timeScale); 3957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert BigDecimal other = new BigDecimal(String.valueOf(otherTime)); 3967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert BigDecimal units = new BigDecimal(data.units); 3977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert BigDecimal epochOffset = new BigDecimal(data.epochOffset); 3987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return other.add(epochOffset).multiply(units); 4007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 4027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 4037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Convert a <code>long</code> datetime from the given time scale to the universal time scale. 4047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * All calculations are done using <code>BigDecimal</code> to guarantee that the value 4057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * does not go out of range. 4067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 4077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param otherTime The <code>long</code> datetime 4087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param timeScale The time scale to convert from 4097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 4107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @return The datetime converted to the universal time scale 4117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 4127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @stable ICU 3.2 4137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 4147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public static BigDecimal bigDecimalFrom(long otherTime, int timeScale) 4157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert { 4167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert TimeScaleData data = getTimeScaleData(timeScale); 4177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert BigDecimal other = new BigDecimal(otherTime); 4187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert BigDecimal units = new BigDecimal(data.units); 4197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert BigDecimal epochOffset = new BigDecimal(data.epochOffset); 4207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 4217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return other.add(epochOffset).multiply(units); 4227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 4247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 4257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Convert a <code>BigDecimal</code> datetime from the given time scale to the universal time scale. 4267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * All calculations are done using <code>BigDecimal</code> to guarantee that the value 4277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * does not go out of range. 4287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 4297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param otherTime The <code>BigDecimal</code> datetime 4307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param timeScale The time scale to convert from 4317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 4327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @return The datetime converted to the universal time scale 4337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 4347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @stable ICU 3.2 4357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 4367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public static BigDecimal bigDecimalFrom(BigDecimal otherTime, int timeScale) 4377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert { 4387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert TimeScaleData data = getTimeScaleData(timeScale); 4397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 4407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert BigDecimal units = new BigDecimal(data.units); 4417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert BigDecimal epochOffset = new BigDecimal(data.epochOffset); 4427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 4437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return otherTime.add(epochOffset).multiply(units); 4447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 4467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 4477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Convert a datetime from the universal time scale stored as a <code>BigDecimal</code> to a 4487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <code>long</code> in the given time scale. 4497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 4507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Since this calculation requires a divide, we must round. The straight forward 4517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * way to round by adding half of the divisor will push the sum out of range for values 4527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * within have the divisor of the limits of the precision of a <code>long</code>. To get around this, we do 4537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * the rounding like this: 4547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 4557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <p><code> 4567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * (universalTime - units + units/2) / units + 1 4577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * </code> 4587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 4597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <p> 4607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * (i.e. we subtract units first to guarantee that we'll still be in range when we 4617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * add <code>units/2</code>. We then need to add one to the quotent to make up for the extra subtraction. 4627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * This simplifies to: 4637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 4647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <p><code> 4657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * (universalTime - units/2) / units - 1 4667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * </code> 4677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 4687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <p> 4697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * For negative values to round away from zero, we need to flip the signs: 4707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 4717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <p><code> 4727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * (universalTime + units/2) / units + 1 4737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * </code> 4747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 4757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <p> 4767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Since we also need to subtract the epochOffset, we fold the <code>+/- 1</code> 4777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * into the offset value. (i.e. <code>epochOffsetP1</code>, <code>epochOffsetM1</code>.) 4787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 4797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param universalTime The datetime in the universal time scale 4807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param timeScale The time scale to convert to 4817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 4827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @return The datetime converted to the given time scale 4837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 4847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @stable ICU 3.2 4857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 4867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public static long toLong(long universalTime, int timeScale) 4877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert { 4887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert TimeScaleData data = toRangeCheck(universalTime, timeScale); 4897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 4907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (universalTime < 0) { 4917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (universalTime < data.minRound) { 4927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return (universalTime + data.unitsRound) / data.units - data.epochOffsetP1; 4937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 4957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return (universalTime - data.unitsRound) / data.units - data.epochOffset; 4967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 4987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (universalTime > data.maxRound) { 4997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return (universalTime - data.unitsRound) / data.units - data.epochOffsetM1; 5007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 5017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 5027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return (universalTime + data.unitsRound) / data.units - data.epochOffset; 5037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 5047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 5057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 5067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Convert a datetime from the universal time scale to a <code>BigDecimal</code> in the given time scale. 5077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 5087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param universalTime The datetime in the universal time scale 5097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param timeScale The time scale to convert to 5107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 5117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @return The datetime converted to the given time scale 5127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 5137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @stable ICU 3.2 5147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 5157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public static BigDecimal toBigDecimal(long universalTime, int timeScale) 5167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert { 5177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert TimeScaleData data = getTimeScaleData(timeScale); 5187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert BigDecimal universal = new BigDecimal(universalTime); 5197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert BigDecimal units = new BigDecimal(data.units); 5207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert BigDecimal epochOffset = new BigDecimal(data.epochOffset); 5217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 5227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return universal.divide(units, BigDecimal.ROUND_HALF_UP).subtract(epochOffset); 5237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 5247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 5257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 5267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Convert a datetime from the universal time scale to a <code>BigDecimal</code> in the given time scale. 5277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 5287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param universalTime The datetime in the universal time scale 5297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param timeScale The time scale to convert to 5307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 5317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @return The datetime converted to the given time scale 5327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 5337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @stable ICU 3.2 5347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 5357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public static BigDecimal toBigDecimal(BigDecimal universalTime, int timeScale) 5367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert { 5377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert TimeScaleData data = getTimeScaleData(timeScale); 5387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert BigDecimal units = new BigDecimal(data.units); 5397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert BigDecimal epochOffset = new BigDecimal(data.epochOffset); 5407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 5417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return universalTime.divide(units, BigDecimal.ROUND_HALF_UP).subtract(epochOffset); 5427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 5437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 5447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 5457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Return the <code>TimeScaleData</code> object for the given time 5467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * scale. 5477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 5487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param scale - the time scale 5497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @return the <code>TimeScaleData</code> object for the given time scale 5507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 5517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private static TimeScaleData getTimeScaleData(int scale) 5527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert { 5537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (scale < 0 || scale >= MAX_SCALE) { 5547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert throw new IllegalArgumentException("scale out of range: " + scale); 5557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 5567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 5577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return timeScaleTable[scale]; 5587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 5597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 5607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 5617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Get a value associated with a particular time scale. 5627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 5637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param scale - the time scale 5647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param value - a constant representing the value to get 5657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 5667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @return - the value. 5677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 5687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @stable ICU 3.2 5697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 5707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public static long getTimeScaleValue(int scale, int value) 5717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert { 5727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert TimeScaleData data = getTimeScaleData(scale); 5737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 5747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert switch (value) 5757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert { 5767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert case UNITS_VALUE: 5777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return data.units; 5787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 5797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert case EPOCH_OFFSET_VALUE: 5807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return data.epochOffset; 5817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 5827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert case FROM_MIN_VALUE: 5837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return data.fromMin; 5847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 5857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert case FROM_MAX_VALUE: 5867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return data.fromMax; 5877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 5887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert case TO_MIN_VALUE: 5897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return data.toMin; 5907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 5917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert case TO_MAX_VALUE: 5927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return data.toMax; 5937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 5947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert case EPOCH_OFFSET_PLUS_1_VALUE: 5957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return data.epochOffsetP1; 5967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 5977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert case EPOCH_OFFSET_MINUS_1_VALUE: 5987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return data.epochOffsetM1; 5997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 6007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert case UNITS_ROUND_VALUE: 6017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return data.unitsRound; 6027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 6037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert case MIN_ROUND_VALUE: 6047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return data.minRound; 6057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 6067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert case MAX_ROUND_VALUE: 6077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return data.maxRound; 6087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 6097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert default: 6107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert throw new IllegalArgumentException("value out of range: " + value); 6117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 6127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 6137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 6147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private static TimeScaleData toRangeCheck(long universalTime, int scale) 6157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert { 6167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert TimeScaleData data = getTimeScaleData(scale); 6177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 6187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (universalTime >= data.toMin && universalTime <= data.toMax) { 6197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return data; 6207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 6217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 6227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert throw new IllegalArgumentException("universalTime out of range:" + universalTime); 6237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 6247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 6257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private static TimeScaleData fromRangeCheck(long otherTime, int scale) 6267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert { 6277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert TimeScaleData data = getTimeScaleData(scale); 6287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 6297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (otherTime >= data.fromMin && otherTime <= data.fromMax) { 6307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return data; 6317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 6327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 6337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert throw new IllegalArgumentException("otherTime out of range:" + otherTime); 6347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 6357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 6367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 6377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Convert a time in the Universal Time Scale into another time 6387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * scale. The division used to do the conversion rounds down. 6397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 6407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * NOTE: This is an internal routine used by the tool that 6417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * generates the to and from limits. Use it at your own risk. 6427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 6437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param universalTime the time in the Universal Time scale 6447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param timeScale the time scale to convert to 6457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @return the time in the given time scale 6467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 6477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @internal 6487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @deprecated This API is ICU internal only. 6497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 6507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert @Deprecated 6517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public static BigDecimal toBigDecimalTrunc(BigDecimal universalTime, int timeScale) 6527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert { 6537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert TimeScaleData data = getTimeScaleData(timeScale); 6547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert BigDecimal units = new BigDecimal(data.units); 6557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert BigDecimal epochOffset = new BigDecimal(data.epochOffset); 6567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 6577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return universalTime.divide(units, BigDecimal.ROUND_DOWN).subtract(epochOffset); 6587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 6597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert} 660