以 HOUR 作为 Calendar returns 12 in Java 参数的 getActualMinimum

getActualMinimum with HOUR as argument of Calendar returns 12 in Java

我正在尝试通过调用方法 calendar.set(Calendar.HOUR, calendar.getActualMinimum(Calendar.HOUR)); 来设置 calendar 的时间,但是 getActualMinimum(Calendar.HOUR) returns 12 而不是 0。

尝试使用 Calendar.HOUR_OF_DAY .

tl;博士

使用java.time类而不是问题重重的遗产类.

要获取一天的第一个时刻,请调用 LocalDate.atStartOfDay( ZoneId )

LocalDate.now(                       // Represent the date alone, without time-of-day and without time zone.
    ZoneId.of( "Africa/Tunis" )      // Specify the time zone in which to determine the current date.
)
.withDayOfYear( 1 )                  // Or `.withDayOfMonth(1)` or `.with( TemporalAdjusters.previousOrSame( DayOfWeek.MONDAY) )`.
.atStartOfDay(                       // Determine the first moment of the day on that particular date in that particular zone.
    ZoneId.of( "Africa/Tunis" )
)                                    // Returns a `ZonedDateTime` object.
.toInstant()                         // Same moment, as seen in UTC.
.toEpochMilli()                      // Extract a count of milliseconds since the epoch reference of 1970-01-01T00:00:00Z. 

java.time

您正在使用麻烦的旧日期时间 类,现在已成为遗留问题,已被 java.time 类.[=50 取代=]

获取当前日期和时间需要时区。对于任何给定时刻,全球各地的日期和时间因地区而异。

ZoneId z = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime zdt = ZonedDateTime.now( z ) ;

提取该日期和时间的仅日期部分。

LocalDate ld = zdt.toLocalDate() ;

从那个日期开始,让java.time确定当天的第一个时刻。永远不要假设一天从 00:00:00 开始。夏令时 (DST) 等异常意味着这一天可能会在另一个时间开始,例如 01:00:00.

java.time类使用immutable objects。不是改变对象上的 属性(“变异”),而是根据原始值创建一个全新的新对象。

ZonedDateTime zdtResult = null ;

对于您的 switch 语句,请使用现有的 ChronoUnit 枚举。由于一个奇怪的技术问题,switch 语句不能使用限定的枚举名称。所以我们必须使用 YEARS 而不是 ChronoUnit.YEARS,例如,作为开关变量。使用静态导入访问枚举。

import static java.time.temporal.ChronoUnit ;
…

switch ( unit ) {
    case YEARS : 
        zdtResult = ld.withDayOfYear( 1 )
                      .atStartOfDay( z ) ;
        break;

    case MONTHS : 
        zdtResult = ld.withDayOfMonth( 1 )
                      .atStartOfDay( z ) ;
        break;

    case WEEKS : 
        zdtResult = ld.with( TemporalAdjusters.previousOrSame( DayOfWeek.MONDAY) )
                      .atStartOfDay( z ) ;
        break;

    default: …
}

从生成的 ZonedDateTime, extract an Instant 对象中查看 UTC 中的同一时刻。

Instant instant = zdtResult.toInstant() ;

你的问题的目标似乎是从 UTC 1970 年第一时刻的纪元参考算起的毫秒数。我强烈建议不要仅使用 long 整数来跟踪日期时间值。使调试和跟踪变得很麻烦,错误很可能会被忽视。转而传递并存储 Instant 个对象。

但如果你坚持要计数,这里是代码。当心数据丢失,因为 Instant 的分辨率为纳秒,因此此调用将忽略任何现有的微秒或纳秒。

long millisSinceEpoch = instant.toEpochMillis() ;

请注意如何使用 java.time 使代码更短、更整洁、更易读。


关于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.

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

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

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

java.time类在哪里获取?

  • Java SE 8, Java SE 9, Java SE 10,及以后
    • 内置。
    • 标准 Java API 的一部分,带有捆绑实施。
    • Java 9 添加了一些小功能和修复。
  • Java SE 6 and Java SE 7
  • Android
    • Android java.time 类.
    • 捆绑实施的更高版本
    • 对于较早的 Android (<26),ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See .

ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.