1 8 9 package com.ibm.icu.util; 10 11 import com.ibm.icu.math.BigDecimal; 12 import java.lang.IllegalArgumentException ; 13 14 54 55 public final class UniversalTimeScale 56 { 57 64 public static final int JAVA_TIME = 0; 65 66 73 public static final int UNIX_TIME = 1; 74 75 82 public static final int ICU4C_TIME = 2; 83 84 91 public static final int WINDOWS_FILE_TIME = 3; 92 93 100 public static final int DOTNET_DATE_TIME = 4; 101 102 109 public static final int MAC_OLD_TIME = 5; 110 111 118 public static final int MAC_TIME = 6; 119 120 127 public static final int EXCEL_TIME = 7; 128 129 136 public static final int DB2_TIME = 8; 137 138 144 public static final int MAX_SCALE = 9; 145 146 154 public static final int UNITS_VALUE = 0; 155 156 165 public static final int EPOCH_OFFSET_VALUE = 1; 166 167 176 public static final int FROM_MIN_VALUE = 2; 177 178 187 public static final int FROM_MAX_VALUE = 3; 188 189 198 public static final int TO_MIN_VALUE = 4; 199 200 209 public static final int TO_MAX_VALUE = 5; 210 211 223 public static final int EPOCH_OFFSET_PLUS_1_VALUE = 6; 224 225 237 public static final int EPOCH_OFFSET_MINUS_1_VALUE = 7; 238 239 250 public static final int UNITS_ROUND_VALUE = 8; 251 252 263 public static final int MIN_ROUND_VALUE = 9; 264 265 276 public static final int MAX_ROUND_VALUE = 10; 277 278 288 public static final int MAX_SCALE_VALUE = 11; 289 290 private static final long ticks = 1; 291 private static final long microseconds = ticks * 10; 292 private static final long milliseconds = microseconds * 1000; 293 private static final long seconds = milliseconds * 1000; 294 private static final long minutes = seconds * 60; 295 private static final long hours = minutes * 60; 296 private static final long days = hours * 24; 297 298 305 private static final class TimeScaleData 306 { 307 TimeScaleData(long theUnits, long theEpochOffset, 308 long theToMin, long theToMax, 309 long theFromMin, long theFromMax) 310 { 311 units = theUnits; 312 unitsRound = theUnits / 2; 313 314 minRound = Long.MIN_VALUE + unitsRound; 315 maxRound = Long.MAX_VALUE - unitsRound; 316 317 epochOffset = theEpochOffset / theUnits; 318 319 if (theUnits == 1) { 320 epochOffsetP1 = epochOffsetM1 = epochOffset; 321 } else { 322 epochOffsetP1 = epochOffset + 1; 323 epochOffsetM1 = epochOffset - 1; 324 } 325 326 toMin = theToMin; 327 toMax = theToMax; 328 329 fromMin = theFromMin; 330 fromMax = theFromMax; 331 } 332 333 long units; 334 long epochOffset; 335 long fromMin; 336 long fromMax; 337 long toMin; 338 long toMax; 339 340 long epochOffsetP1; 341 long epochOffsetM1; 342 long unitsRound; 343 long minRound; 344 long maxRound; 345 } 346 347 private static final TimeScaleData[] timeScaleTable = { 348 new TimeScaleData(milliseconds, 621355968000000000L, -9223372036854774999L, 9223372036854774999L, -984472800485477L, 860201606885477L), new TimeScaleData(seconds, 621355968000000000L, -9223372036854775808L, 9223372036854775807L, -984472800485L, 860201606885L), new TimeScaleData(milliseconds, 621355968000000000L, -9223372036854774999L, 9223372036854774999L, -984472800485477L, 860201606885477L), new TimeScaleData(ticks, 504911232000000000L, -8718460804854775808L, 9223372036854775807L, -9223372036854775808L, 8718460804854775807L), new TimeScaleData(ticks, 000000000000000000L, -9223372036854775808L, 9223372036854775807L, -9223372036854775808L, 9223372036854775807L), new TimeScaleData(seconds, 600527520000000000L, -9223372036854775808L, 9223372036854775807L, -982389955685L, 862284451685L), new TimeScaleData(seconds, 631139040000000000L, -9223372036854775808L, 9223372036854775807L, -985451107685L, 859223299685L), new TimeScaleData(days, 599265216000000000L, -9223372036854775808L, 9223372036854775807L, -11368793L, 9981605L), new TimeScaleData(days, 599265216000000000L, -9223372036854775808L, 9223372036854775807L, -11368793L, 9981605L) }; 358 359 360 363 private UniversalTimeScale() 364 { 365 } 367 368 379 public static long from(long otherTime, int timeScale) 380 { 381 TimeScaleData data = fromRangeCheck(otherTime, timeScale); 382 383 return (otherTime + data.epochOffset) * data.units; 384 } 385 386 399 public static BigDecimal bigDecimalFrom(double otherTime, int timeScale) 400 { 401 TimeScaleData data = getTimeScaleData(timeScale); 402 BigDecimal other = new BigDecimal(String.valueOf(otherTime)); 403 BigDecimal units = new BigDecimal(data.units); 404 BigDecimal epochOffset = new BigDecimal(data.epochOffset); 405 406 return other.add(epochOffset).multiply(units); 407 } 408 409 422 public static BigDecimal bigDecimalFrom(long otherTime, int timeScale) 423 { 424 TimeScaleData data = getTimeScaleData(timeScale); 425 BigDecimal other = new BigDecimal(otherTime); 426 BigDecimal units = new BigDecimal(data.units); 427 BigDecimal epochOffset = new BigDecimal(data.epochOffset); 428 429 return other.add(epochOffset).multiply(units); 430 } 431 432 445 public static BigDecimal bigDecimalFrom(BigDecimal otherTime, int timeScale) 446 { 447 TimeScaleData data = getTimeScaleData(timeScale); 448 449 BigDecimal units = new BigDecimal(data.units); 450 BigDecimal epochOffset = new BigDecimal(data.epochOffset); 451 452 return otherTime.add(epochOffset).multiply(units); 453 } 454 455 496 public static long toLong(long universalTime, int timeScale) 497 { 498 TimeScaleData data = toRangeCheck(universalTime, timeScale); 499 500 if (universalTime < 0) { 501 if (universalTime < data.minRound) { 502 return (universalTime + data.unitsRound) / data.units - data.epochOffsetP1; 503 } 504 505 return (universalTime - data.unitsRound) / data.units - data.epochOffset; 506 } 507 508 if (universalTime > data.maxRound) { 509 return (universalTime - data.unitsRound) / data.units - data.epochOffsetM1; 510 } 511 512 return (universalTime + data.unitsRound) / data.units - data.epochOffset; 513 } 514 515 526 public static BigDecimal toBigDecimal(long universalTime, int timeScale) 527 { 528 TimeScaleData data = getTimeScaleData(timeScale); 529 BigDecimal universal = new BigDecimal(universalTime); 530 BigDecimal units = new BigDecimal(data.units); 531 BigDecimal epochOffset = new BigDecimal(data.epochOffset); 532 533 return universal.divide(units, BigDecimal.ROUND_HALF_UP).subtract(epochOffset); 534 } 535 536 547 public static BigDecimal toBigDecimal(BigDecimal universalTime, int timeScale) 548 { 549 TimeScaleData data = getTimeScaleData(timeScale); 550 BigDecimal units = new BigDecimal(data.units); 551 BigDecimal epochOffset = new BigDecimal(data.epochOffset); 552 553 return universalTime.divide(units, BigDecimal.ROUND_HALF_UP).subtract(epochOffset); 554 } 555 556 567 private static TimeScaleData getTimeScaleData(int scale) 568 { 569 if (scale < 0 || scale >= MAX_SCALE) { 570 throw new IllegalArgumentException ("scale out of range: " + scale); 571 } 572 573 return timeScaleTable[scale]; 574 } 575 576 587 public static long getTimeScaleValue(int scale, int value) 588 { 589 TimeScaleData data = getTimeScaleData(scale); 590 591 switch (value) 592 { 593 case UNITS_VALUE: 594 return data.units; 595 596 case EPOCH_OFFSET_VALUE: 597 return data.epochOffset; 598 599 case FROM_MIN_VALUE: 600 return data.fromMin; 601 602 case FROM_MAX_VALUE: 603 return data.fromMax; 604 605 case TO_MIN_VALUE: 606 return data.toMin; 607 608 case TO_MAX_VALUE: 609 return data.toMax; 610 611 case EPOCH_OFFSET_PLUS_1_VALUE: 612 return data.epochOffsetP1; 613 614 case EPOCH_OFFSET_MINUS_1_VALUE: 615 return data.epochOffsetM1; 616 617 case UNITS_ROUND_VALUE: 618 return data.unitsRound; 619 620 case MIN_ROUND_VALUE: 621 return data.minRound; 622 623 case MAX_ROUND_VALUE: 624 return data.maxRound; 625 626 default: 627 throw new IllegalArgumentException ("value out of range: " + value); 628 } 629 } 630 631 private static TimeScaleData toRangeCheck(long universalTime, int scale) 632 { 633 TimeScaleData data = getTimeScaleData(scale); 634 635 if (universalTime >= data.toMin && universalTime <= data.toMax) { 636 return data; 637 } 638 639 throw new IllegalArgumentException ("universalTime out of range:" + universalTime); 640 } 641 642 private static TimeScaleData fromRangeCheck(long otherTime, int scale) 643 { 644 TimeScaleData data = getTimeScaleData(scale); 645 646 if (otherTime >= data.fromMin && otherTime <= data.fromMax) { 647 return data; 648 } 649 650 throw new IllegalArgumentException ("otherTime out of range:" + otherTime); 651 } 652 653 667 public static BigDecimal toBigDecimalTrunc(BigDecimal universalTime, int timeScale) 668 { 669 TimeScaleData data = getTimeScaleData(timeScale); 670 BigDecimal units = new BigDecimal(data.units); 671 BigDecimal epochOffset = new BigDecimal(data.epochOffset); 672 673 return universalTime.divide(units, BigDecimal.ROUND_DOWN).subtract(epochOffset); 674 } 675 } 676 | Popular Tags |