【问题标题】:Set the Calendar to a specific date?将日历设置为特定日期?
【发布时间】:2015-03-06 06:41:16
【问题描述】:

我想在特定日期设置一个带有通知的提醒。然后我目前正在使用带有 NotificationManager 的 AlarmManager。当我从 dateDialog 设置选定日期时,提醒正在工作。如何将日历值放在固定时间的闹钟上?我从中得到当前的日期和时间:

Calendar calendar =  Calendar.getInstance();

然后我可以像下面这样手动设置日历并且它正在工作:

calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MINUTE, 13);
calendar.set(Calendar.HOUR, 7);
calendar.set(Calendar.AM_PM, Calendar.AM);
calendar.set(Calendar.MONTH, Calendar.JANUARY);
calendar.set(Calendar.DAY_OF_MONTH, 8);
calendar.set(Calendar.YEAR,2015);
long when = calendar.getTimeInMillis();

但我的问题是如何将日历设置为明天和上午 9:00,或者将日历准确设置为当前日期之后的特定月份(或年份)?我的意思是这样的:

calendar.add(Calendar.DAY_OF_MONTH, 1);

但它不起作用。

【问题讨论】:

  • but it does not work是什么意思?

标签: java android date calendar


【解决方案1】:

tl;博士

ZonedDateTime.of(
    LocalDate.of( 2015 , Month.JANUARY , 8 ) ,
    LocalTime.of( 7 , 13 , 0 ) ,
    ZoneId.of( "Africa/Tunis" ) 
)
.toInstant()
.toEpochMilli()

1420697580000

java.time

现代方法使用 java.time 类来取代麻烦的旧旧日期时间类。 所以现在更容易和更清洁了。

您的代码不明确,因为您没有解决时区的关键问题。由于您没有明确指定时区,因此您的 JVM 当前的默认时区将被隐式应用。我强烈建议始终指定您想要/预期的时区。

continent/region 的格式指定proper time zone name,例如America/MontrealAfrica/CasablancaPacific/Auckland。切勿使用 3-4 个字母的伪时区,例如 ESTIST,因为它们不是真正的时区,没有标准化,甚至不是唯一的(!)。

LocalDate ld = LocalDate.of( 2015 , Month.JANUARY , 8 ) ;
LocalTime lt = LocalTime.of( 7 , 13 , 0 ) ;
ZoneId z = ZoneId.of( "Pacific/Auckland" ) ;
ZonedDateTime zdt = ZonedDateTime.of( ld , lt , z ) ;

您也可以使用组合因子方法。

ZonedDateTime zdt = ZonedDateTime.of( 2015 , Month.JANUARY , 8 , 7 , 13 , 0 , 0 , ZoneId.of( "Pacific/Auckland" ) ) ;

我通常建议不要将日期时间作为从纪元开始的计数。但这似乎是您的情况的要求。

首先我们可以提取Instant,UTC 时刻。 Instant 类代表UTC 时间线上的时刻,分辨率为nanoseconds(最多九 (9) 位小数)。

Instant instant = zdt.toInstant() ;  // Convert from a zoned value to a UTC value.

然后,您可以询问自 1970 年第一刻(UTC,1970-01-01T00:00:00Z)的纪元参考以来的毫秒数。请注意可能的数据丢失,因为Instant 中的任何微秒或纳秒在报告毫秒时都将被忽略。

long millis = instant.toEpochMilli() ;  // Count of milliseconds since 1970-01-01T00:00:00Z.

关于java.time

java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧 legacy 日期时间类,例如 java.util.DateCalendarSimpleDateFormat

Joda-Time 项目现在位于maintenance mode,建议迁移到java.time 类。

要了解更多信息,请参阅Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310

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

从哪里获得 java.time 类?

ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。您可以在这里找到一些有用的类,例如IntervalYearWeekYearQuartermore

【讨论】:

    【解决方案2】:

    乔达时间

    更新:Joda-Time 项目现在位于maintenance mode,团队建议迁移到java.time 类。见Tutorial by Oracle

    尝试使用更好的日期时间库,例如 Joda-Time。

    在 Joda-Time 中,您可以在保持时间的同时更改日期。或者,反之亦然,在保持日期的同时保持时间。

    DateTime now = DateTime.now( DateTimeZone.forID( "America/Montreal" ) ) ;
    DateTime todayNoon = now.withTime( 12, 0, 0, 0 ) ;
    DateTime midMarchSameYearSameTimeAsNow = now.withDate(  now.getYear(), DateTimeConstants.MARCH, 15 );
    DateTime tomorrowSameTime = now.plusDays( 1 );
    

    【讨论】:

      【解决方案3】:

      对我来说,这在桌面上运行良好,虽然无法在 Android 上测试
      更新:刚刚使用 AIDE 在我的 Android 手机上进行了测试,得到了完全相同的结果。

      import java.util.Calendar;
      
      public class CalendarTest {
      
          public static void main(String[] args) {
      
              Calendar calendar = Calendar.getInstance();
      
              System.out.println(calendar.getTimeInMillis() + " -> " + calendar.getTime());
      
              calendar.set(Calendar.SECOND, 0);
              calendar.set(Calendar.MINUTE, 13);
              calendar.set(Calendar.HOUR, 7);
              calendar.set(Calendar.AM_PM, Calendar.AM);
              calendar.set(Calendar.MONTH, Calendar.JANUARY);
              calendar.set(Calendar.DAY_OF_MONTH, 9);
              calendar.set(Calendar.YEAR, 2015);
      
              System.out.println(calendar.getTimeInMillis() + " -> " + calendar.getTime());
      
              calendar.add(Calendar.DAY_OF_MONTH, 1);
              calendar.add(Calendar.YEAR, 1);
      
              System.out.println(calendar.getTimeInMillis() + " -> " + calendar.getTime());
          }
      

      对于这个测试,我的输出正是你所期望的:

      1420705649927 -> Thu Jan 08 09:27:29 CET 2015
      1420783980927 -> Fri Jan 09 07:13:00 CET 2015
      1452406380927 -> Sun Jan 10 07:13:00 CET 2016
      

      【讨论】:

      【解决方案4】:

      要增加一个小时的例子,你可以这样做:

      calendar.set(Calendar.HOUR, calendar.get(Calendar.HOUR) + 1);
      

      【讨论】:

        猜你喜欢
        • 2015-04-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-05-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-11-21
        相关资源
        最近更新 更多