在 Android 中使用 `Calendar` 指定日期时间范围

Specify a date-time range with `Calendar` in Android

Whosebug 社区,

我目前正在处理我的新项目,我是 Java 和 Android Studio 的新手。 我用两个 Calendar 变量编写了自己的 Entry class。 是否有更短更清晰的方法来创建新的 Entry 对象,如以下代码所示?

//MainActivity.java    
//....
private ArrayList<Entry> initEntrys() {
        ArrayList<Entry> list = new ArrayList<>();
        Calendar calendar = Calendar.getInstance();

        Calendar mStartDate = calendar;
        Calendar mEndDate = calendar;
        mStartDate.set(2019, 12, 20, 7, 0);
        mEndDate.set(2019, 12, 20, 10, 0);
        list.add(new Entry(mStartDate, mEndDate));

        return list;
    }

任何帮助将不胜感激。 :)

tl;博士

切勿使用遗留日期时间 classes,例如 Calendar仅使用 java.time classes.

对于带有时间但缺少时区或与 UTC 的偏移量的日期,使用 java.time.LocalDateTime class.

LocalDateTime.of( 2019 , 12 , 20 , 7 , 0 )  // year, month, day , hour , minute. 

避免遗留日期时间 classes

永远不要使用 Calendar. 那 class 太糟糕了,它的设计有缺陷。它在多年前被 JSR 310 中定义的现代 java.time classes 所取代。

java.time

与传统的 classes 相比,java.time classes 在设计上是不可变的,因此是线程安全的。

我们不使用 new 的构造函数,而是通过调用 LocalDateTime.of.[=40 等静态工厂方法来实例化 java.time 对象=]

一刻也没有

如果你有意识地在没有 time zone or offset-from-UTC, use LocalDateTime 个对象的情况下工作。

LocalDateTime start = LocalDateTime.of( 2019 , 12 , 20 , 7 , 0 ) ;  // Passing year, month, day , hour , minute. The second and fractional-second both default to zero.
LocalDateTime stop = LocalDateTime.of( 2019 , 12 , 20 , 10 , 0 ) ;

瞬间

如果您试图表示时刻、时间轴上的特定点,那么 LocalDateTime 错误的 class。

对于跟踪时刻,您需要时区的上下文(或者更不理想的是,与 UTC 的偏移量)。为此,使用 ZonedDateTime as seen in the .



关于java.time

java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

要了解更多信息,请参阅 Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310

Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

您可以直接与数据库交换 java.time 对象。使用 JDBC driver compliant with JDBC 4.2 或更高版本。不需要字符串,不需要 java.sql.* classes.

从哪里获得java.time classes?


我会努力完成 by covering a time zoned date using the ZonedDateTimeclass。

我在示例中使用了 UTC 时区,但您可以根据需要自定义时区。

LocalDateTime ldtStart = LocalDateTime.of( 2019 , 12 , 20 , 7 , 0 , 0 , 0 ) ;
ZonedDateTime ldtZonedStart = ldtStart.atZone(ZoneId.systemDefault());
ZonedDateTime utcZonedStart = ldtZonedStart.withZoneSameInstant(ZoneOffset.UTC);


LocalDateTime ldtStop = LocalDateTime.of( 2019 , 12 , 20 , 10 , 0 , 0 , 0 ) ;
ZonedDateTime ldtStopZoned = ldtStop.atZone(ZoneId.systemDefault());
ZonedDateTime utcZonedStop = ldtStopZoned.withZoneSameInstant(ZoneOffset.UTC);