Java 将日历设置为特定日期?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27835229/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 05:07:28  来源:igfitidea点击:

Set the Calendar to a specific date?

javaandroiddatecalendar

提问by user1579019

I want to set a reminder with notification on a specific date. Then I am using AlarmManager with NotificationManager currently. When I set selected date from dateDialog, the reminder is working. How can I put calendar value on alarm set with fixed time? I get the current date and time from this :

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

Calendar calendar =  Calendar.getInstance();

and then I can set the calendar manually like below and it's working:

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

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();

But my question is how can I set the calendar to tomorrow and 9:00 AM or set the calendar exactly to a particular month (or year) later from the current date? I mean something like this :

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

calendar.add(Calendar.DAY_OF_MONTH, 1);

but it does not work.

但它不起作用。

采纳答案by Basil Bourque

Joda-Time

乔达时间

UPDATE:The Joda-Timeproject is now in maintenance mode, with the team advising migration to the java.timeclasses. See Tutorial by Oracle.

UPDATE:乔达时间的项目现在处于维护模式,与团队的建议迁移java.time类。请参阅Oracle 教程

Try using a better date-time library, such as Joda-Time.

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

In Joda-Time you can change the date while keeping the time of day. Or, vice-versa, keep the time of day while keeping the date.

在 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 );

回答by Tr4X

To add an hour by example, you can do something like this :

要通过示例添加一个小时,您可以执行以下操作:

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

回答by tringel

For me this works just fine on the desktop, couldn't test it on Android though.
Update:just tested this on my Android phone using AIDE, getting the exact same results.

对我来说,这在桌面上工作得很好,但无法在 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());
    }

For this test my output is just what you would expect:

对于此测试,我的输出正是您所期望的:

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

回答by Basil Bourque

tl;dr

tl;博士

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

1420697580000

1420697580000

java.time

时间

The modern approach uses the java.timeclasses that supplant the troublesome old legacy date-time classes. Somuch easier and cleaner now.

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

Your code is ambiguous, as you do not address the crucial issue of time zone. As you did not specify a time zone explicitly, your JVM's current default time zone will be applied implicitly. I strongly recommend alwaysspecifying your desired/expected time zone.

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

Specify a proper time zone namein the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 3-4 letter pseudo-zones such as ESTor ISTas they are nottrue time zones, not standardized, and not even unique(!).

以、、 或等格式指定正确的时区名称。永远不要使用 3-4 个字母的伪区域,例如或因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。continent/regionAmerica/MontrealAfrica/CasablancaPacific/AucklandESTIST

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 ) ;

You could use a combo factor method, alternatively.

或者,您可以使用组合因子方法。

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

I generally recommend against tracking date-time as a count-from-epoch. But it seems to be requirement in your case.

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

First we can extract a Instant, a moment in UTC. The Instantclass represents a moment on the timeline in UTCwith a resolution of nanoseconds(up to nine (9) digits of a decimal fraction).

首先,我们可以Instant在 UTC 中提取一个时刻。该Instant级表示时间轴上的时刻UTC,分辨率为纳秒(最多小数的9个位数)。

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

You can then ask for the count of milliseconds since the epoch reference of first moment of 1970 in UTC, 1970-01-01T00:00:00Z. Beware of possible data loss, as any microseconds or nanoseconds in the Instantwill be ignored when reporting mere milliseconds.

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

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


About java.time

关于java.time

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

java.time框架是建立在Java 8和更高版本。这些类取代了麻烦的旧的遗留日期时间类,例如java.util.Date, Calendar, & SimpleDateFormat

The Joda-Timeproject, now in maintenance mode, advises migration to the java.timeclasses.

现在处于维护模式Joda-Time项目建议迁移到java.time类。

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

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

Using a JDBC drivercompliant with JDBC 4.2or later, you may exchange java.timeobjects directly with your database. No need for strings nor java.sql.* classes.

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

Where to obtain the java.time classes?

从哪里获得 java.time 类?

The ThreeTen-Extraproject 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.

ThreeTen-额外项目与其他类扩展java.time。该项目是未来可能添加到 java.time 的试验场。你可能在这里找到一些有用的类,比如IntervalYearWeekYearQuarter,和更多