Home | History | Annotate | Download | only in util
      1 /*
      2  * Copyright (C) 2010 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package libcore.java.util;
     18 
     19 import java.time.Instant;
     20 import java.util.Calendar;
     21 import java.util.Date;
     22 import java.util.Locale;
     23 import java.util.TimeZone;
     24 import junit.framework.TestCase;
     25 
     26 public class DateTest extends TestCase {
     27     // http://code.google.com/p/android/issues/detail?id=6013
     28     public void test_toString_us() throws Exception {
     29         // Ensure that no matter where this is run, we know what time zone to expect.
     30         Locale.setDefault(Locale.US);
     31         TimeZone.setDefault(TimeZone.getTimeZone("America/Chicago"));
     32         assertEquals("Wed Dec 31 18:00:00 CST 1969", new Date(0).toString());
     33     }
     34 
     35     // https://code.google.com/p/android/issues/detail?id=81924
     36     public void test_toString_nonUs() {
     37         // The string for the timezone depends on what the default locale is. Not every locale
     38         // has a short-name for America/Chicago -> CST.
     39         Locale.setDefault(Locale.CHINA);
     40         TimeZone.setDefault(TimeZone.getTimeZone("America/Chicago"));
     41         assertEquals("Wed Dec 31 18:00:00 CST 1969", new Date(0).toString());
     42     }
     43 
     44     public void test_toGMTString_us() throws Exception {
     45         // Based on https://issues.apache.org/jira/browse/HARMONY-501
     46         TimeZone.setDefault(TimeZone.getTimeZone("America/Los_Angeles"));
     47         Locale.setDefault(Locale.US);
     48 
     49         Calendar c = Calendar.getInstance();
     50         c.clear();
     51         c.set(Calendar.YEAR, 21);
     52         assertEquals("Wed Jan 01 00:00:00 PST 21", c.getTime().toString());
     53         assertEquals("1 Jan 21 08:00:00 GMT", c.getTime().toGMTString());
     54         c.set(Calendar.YEAR, 321);
     55         assertEquals("Sun Jan 01 00:00:00 PST 321", c.getTime().toString());
     56         assertEquals("1 Jan 321 08:00:00 GMT", c.getTime().toGMTString());
     57     }
     58 
     59     public void test_toGMTString_nonUs() throws Exception {
     60         TimeZone.setDefault(TimeZone.getTimeZone("America/Los_Angeles"));
     61         Locale.setDefault(Locale.UK);
     62 
     63         Calendar c = Calendar.getInstance();
     64         c.clear();
     65         c.set(Calendar.YEAR, 21);
     66         assertEquals("Wed Jan 01 00:00:00 PST 21", c.getTime().toString());
     67         assertEquals("1 Jan 21 08:00:00 GMT", c.getTime().toGMTString());
     68         c.set(Calendar.YEAR, 321);
     69         assertEquals("Sun Jan 01 00:00:00 PST 321", c.getTime().toString());
     70         assertEquals("1 Jan 321 08:00:00 GMT", c.getTime().toGMTString());
     71     }
     72 
     73     public void test_parse_timezones() {
     74        assertEquals(
     75                Date.parse("Wed, 06 Jan 2016 11:55:59 GMT+05:00"),
     76                Date.parse("Wed, 06 Jan 2016 11:55:59 GMT+0500"));
     77 
     78         assertEquals(
     79                 Date.parse("Wed, 06 Jan 2016 11:55:59 GMT+05:00"),
     80                 Date.parse("Wed, 06 Jan 2016 11:55:59 GMT+05"));
     81     }
     82 
     83     /**
     84      * Test that conversion between Date and Instant works when the
     85      * Instant is based on a millisecond value (and thus can be
     86      * represented as a Date).
     87      */
     88     public void test_convertFromAndToInstant_milliseconds() {
     89         check_convertFromAndToInstant_milliseconds(Long.MIN_VALUE);
     90         check_convertFromAndToInstant_milliseconds(Long.MAX_VALUE);
     91 
     92         check_convertFromAndToInstant_milliseconds(-1);
     93         check_convertFromAndToInstant_milliseconds(0);
     94         check_convertFromAndToInstant_milliseconds(123456789);
     95     }
     96 
     97     private static void check_convertFromAndToInstant_milliseconds(long millis) {
     98         assertEquals(new Date(millis), Date.from(Instant.ofEpochMilli(millis)));
     99         assertEquals(new Date(millis).toInstant(), Instant.ofEpochMilli(millis));
    100     }
    101 
    102     /**
    103      * Checks the minimum/maximum Instant values (based on seconds and
    104      * nanos) that can be converted to a Date, i.e. that can be converted
    105      * to milliseconds without overflowing a long. Note that the rounding
    106      * is such that the lower bound is exactly Long.MIN_VALUE msec whereas
    107      * the upper bound is 999,999 nanos beyond Long.MAX_VALUE msec. This
    108      * makes some sense in that the magnitude of the upper/lower bound
    109      * nanos differ only by 1, just like the magnitude of Long.MIN_VALUE /
    110      * MAX_VALUE differ only by 1.
    111      */
    112     public void test_convertFromInstant_secondsAndNanos() {
    113         // Documentation for how the below bounds relate to long boundaries for milliseconds
    114         assertEquals(-808, Long.MIN_VALUE % 1000);
    115         assertEquals(807, Long.MAX_VALUE % 1000);
    116 
    117         // Lower bound
    118         long minSecond = Long.MIN_VALUE / 1000;
    119         Date.from(Instant.ofEpochSecond(minSecond));
    120         // This instant exactly corresponds to Long.MIN_VALUE msec because
    121         // Long.MIN_VALUE % 1000 == -808 == (-1000 + 192)
    122         Date.from(Instant.ofEpochSecond(minSecond - 1, 192000000));
    123         assertArithmeticOverflowDateFrom(Instant.ofEpochSecond(minSecond - 1, 0));
    124         assertArithmeticOverflowDateFrom(Instant.ofEpochSecond(minSecond - 1, 191999999));
    125 
    126         // Upper bound
    127         long maxSecond = Long.MAX_VALUE / 1000;
    128         Date.from(Instant.ofEpochSecond(maxSecond, 0));
    129         // This Instant is 999,999 nanos beyond Long.MAX_VALUE msec because
    130         // (Long.MAX_VALUE % 1000) == 807
    131         Date.from(Instant.ofEpochSecond(maxSecond, 807999999));
    132         assertArithmeticOverflowDateFrom(Instant.ofEpochSecond(maxSecond + 1, 0));
    133         assertArithmeticOverflowDateFrom(Instant.ofEpochSecond(maxSecond, 808000000));
    134     }
    135 
    136     private static void assertArithmeticOverflowDateFrom(Instant instant) {
    137         try {
    138             Date.from(instant);
    139             fail(instant + " should not have been convertible to Date");
    140         } catch (IllegalArgumentException expected) {
    141         }
    142     }
    143 
    144     /**
    145      * Checks conversion between long, Date and Instant.
    146      */
    147     public void test_convertToInstantAndBack() {
    148         check_convertToInstantAndBack(0);
    149         check_convertToInstantAndBack(-1);
    150         check_convertToInstantAndBack( 999999999);
    151         check_convertToInstantAndBack(1000000000);
    152         check_convertToInstantAndBack(1000000001);
    153         check_convertToInstantAndBack(1000000002);
    154         check_convertToInstantAndBack(1000000499);
    155         check_convertToInstantAndBack(1000000500);
    156         check_convertToInstantAndBack(1000000999);
    157         check_convertToInstantAndBack(1000001000);
    158         check_convertToInstantAndBack(Long.MIN_VALUE + 808); // minimum ofEpochMilli argument
    159         check_convertToInstantAndBack(Long.MAX_VALUE);
    160         check_convertToInstantAndBack(System.currentTimeMillis());
    161         check_convertToInstantAndBack(Date.parse("Wed, 06 Jan 2016 11:55:59 GMT+0500"));
    162     }
    163 
    164     private static void check_convertToInstantAndBack(long millis) {
    165         Date date = new Date(millis);
    166         Instant instant = date.toInstant();
    167         assertEquals(date, Date.from(instant));
    168 
    169         assertEquals(instant, Instant.ofEpochMilli(millis));
    170         assertEquals("Millis should be a millions of nanos", 0, instant.getNano() % 1000000);
    171 
    172         assertEquals(millis, date.getTime());
    173         assertEquals(millis, instant.toEpochMilli());
    174     }
    175 }
    176