嗨,我发生了一些奇怪的事情。我只是拿一个日历对象,将其转换为各个部分,并将其放回日历中(有或没有任何更改。在这种情况下,我不做任何更改)。我的意思是,这应该是剪切和粘贴。我还尝试使用calendar = Calendar.getInstance()创建日历并手动设置所有内容。 calendar.set(Calendar.YEAR,mStartYear);等等。仍然提供错误的Calendar对象。我也尝试过设置毫秒,似乎总是有一些垃圾毫秒......但是这种或那种方式的时间完全是关闭的。也许有人看到了愚蠢的疏忽,但我很难过。
这也是一个Android应用程序,但对于基本的Java库对象无关紧要。
注意Weekview是我正在使用的其中一个库的数据包装器。它有一个开始和结束日历。
这是调试器在内存中列出的内容..
mEndDay = 19
mEndHour = 9
mEndMinute = 30
mEndMonth = 8
mEndYear = 2015
mSeekAmount = 0
mStartDay = 18
mStartHour = 23
mStartMinute = 0
mStartMonth = 8
mStartYear = 2015
Calendar calendarStart = Calendar.getInstance();
calendarStart.set(mStartYear,mStartMonth,mStartDay,mStartHour,mStartMinute);
Calendar calendarEnd = Calendar.getInstance();
calendarEnd.set(mEndYear,mEndMonth,mEndDay,mEndHour,mEndMinute);
我最终得到了
Start 1442363359161
End 1442363359161
calendarStart = {GregorianCalendar@20968} "java.util.GregorianCalendar[time=?,areFieldsSet=false,lenient=true,zone=America/Denver,firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2015,MONTH=8,WEEK_OF_YEAR=38,WEEK_OF_MONTH=3,DAY_OF_MONTH=18,DAY_OF_YEAR=258,DAY_OF_WEEK=3,DAY_OF_WEEK_IN_MONTH=3,AM_PM=1,HOUR=6,HOUR_OF_DAY=23,MINUTE=0,SECOND=19,MILLISECOND=161,ZONE_OFFSET=-25200000,DST_OFFSET=3600000]"
calendarEnd = {GregorianCalendar@20969} "java.util.GregorianCalendar[time=?,areFieldsSet=false,lenient=true,zone=America/Denver,firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2015,MONTH=8,WEEK_OF_YEAR=38,WEEK_OF_MONTH=3,DAY_OF_MONTH=19,DAY_OF_YEAR=258,DAY_OF_WEEK=3,DAY_OF_WEEK_IN_MONTH=3,AM_PM=1,HOUR=6,HOUR_OF_DAY=9,MINUTE=30,SECOND=19,MILLISECOND=161,ZONE_OFFSET=-25200000,DST_OFFSET=3600000]"
EXPECT
Start 1442638800000
End 1442676600000
mEndTime = {GregorianCalendar@20990} "java.util.GregorianCalendar[time=1442676600000,areFieldsSet=true,lenient=true,zone=America/Denver,firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2015,MONTH=8,WEEK_OF_YEAR=38,WEEK_OF_MONTH=3,DAY_OF_MONTH=19,DAY_OF_YEAR=262,DAY_OF_WEEK=7,DAY_OF_WEEK_IN_MONTH=3,AM_PM=0,HOUR=9,HOUR_OF_DAY=9,MINUTE=30,SECOND=0,MILLISECOND=0,ZONE_OFFSET=-25200000,DST_OFFSET=3600000]"
mName = {String@20991} "sleep"
mStartTime = {GregorianCalendar@20992} "java.util.GregorianCalendar[time=1442638800000,areFieldsSet=true,lenient=true,zone=America/Denver,firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2015,MONTH=8,WEEK_OF_YEAR=38,WEEK_OF_MONTH=3,DAY_OF_MONTH=18,DAY_OF_YEAR=261,DAY_OF_WEEK=6,DAY_OF_WEEK_IN_MONTH=3,AM_PM=1,HOUR=11,HOUR_OF_DAY=23,MINUTE=0,SECOND=0,MILLISECOND=0,ZONE_OFFSET=-25200000,DST_OFFSET=3600000]"
这是我最初设置的地方..
WeekViewEvent weekViewEvent = dateWrapperParam.getWeekViewEvent();
Calendar endCalendar = weekViewEvent.getEndTime();
Calendar startCalendar = weekViewEvent.getStartTime();
Date endDate = endCalendar.getTime();
Date startDate = startCalendar.getTime();
mStartHour = startCalendar.get(Calendar.HOUR_OF_DAY);
mStartMinute = startCalendar.get(Calendar.MINUTE);
mStartDay = startCalendar.get(Calendar.DAY_OF_MONTH);
mStartMonth = startCalendar.get(Calendar.MONTH);
mStartYear = startCalendar.get(Calendar.YEAR);
mEndHour = endCalendar.get(Calendar.HOUR_OF_DAY);
mEndMinute = endCalendar.get(Calendar.MINUTE);
mEndDay = endCalendar.get(Calendar.DAY_OF_MONTH);
mEndMonth = endCalendar.get(Calendar.MONTH);
mEndYear = endCalendar.get(Calendar.YEAR);
答案 0 :(得分:0)
根据您在我的问题下的评论,startCalendar
和calendarStart
时间之间只有秒和毫秒的差异,因为这些值未重置。
请参阅DEMO
答案 1 :(得分:0)
在Calendar.set
的文档中,有人说:
设置字段YEAR,MONTH,DAY_OF_MONTH,HOUR,MINUTE和SECOND的值。保留其他字段的先前值。如果不需要,请先致电clear()。
原因是并非所有字段都使用此方法设置,在您的情况下,您没有设置MILLISECOND
。因此它在创建实例时保留值。
设置此Calendar的所有日历字段值和时间值(与Epoch的毫秒偏移量)undefined。
一个简单的例子:
Calendar c = GregorianCalendar.getInstance();
c.clear();
c.set(2019, Calendar.NOVEMBER, 03, 16, 15, 03);
System.out.println(c.getTime());
System.out.println(c.getTimeInMillis());
Sun Nov 03 16:15:03 CET 2019
1572794103000
未定义的毫秒数将为0
答案 2 :(得分:0)
我建议您使用java.time(现代的Java日期和时间API)进行日期和时间工作。例如:
ZonedDateTime start = ZonedDateTime.now(ZoneId.systemDefault());
ZonedDateTime end = start;
System.out.println("Start: " + start);
System.out.println("End: " + end);
我刚才在时区运行代码时的输出:
Start: 2020-06-24T19:24:04.811+02:00[Europe/Copenhagen] End: 2020-06-24T19:24:04.811+02:00[Europe/Copenhagen]
ZonedDateTime
是某个时区中的日期和时间。这是我们最接近的等效于GregorianCalendar
(您的代码为您提供的Calendar
的子类)的现代形式。使用哪种现代类随更精确的要求而变化,因此有时您会更喜欢使用LocalDate
,OffsetDateTime
甚至是LocalTime
。
要将值截断为整分钟(将秒和秒的秒数设置为0):
ZonedDateTime start = ZonedDateTime.now(ZoneId.systemDefault())
.truncatedTo(ChronoUnit.MINUTES);
Start: 2020-06-24T19:24+02:00[Europe/Copenhagen]
ZonedDateTime
和其他java.time类提供了许多方法来修改获得的值。例如:
ZonedDateTime end = start.plusDays(2).withHour(13);
End: 2020-06-26T13:24+02:00[Europe/Copenhagen]
如果您要仅使用开始时间中的选定字段手动创建结束时间:
ZonedDateTime end = ZonedDateTime.of(
2021, start.getMonthValue(), start.getDayOfMonth(),
start.getHour(), 30, 0, 0, start.getZone());
End: 2021-06-24T19:30+02:00[Europe/Copenhagen]
部分答案已经在其他答案中:set
的{{1}}方法仅设置他们承诺设置的字段,并在可能的情况下保持其他字段不变。尽管这可能是Calendar
方法所期望的,但它常常使set(int field, int value)
方法感到惊讶,甚至使set(int year, int month, int date)
和set(int year, int month, int date, int hourOfDay, int minute)
更加令人惊讶。通常,虽然set(int year, int month, int date, int hourOfDay, int minute, int second)
类及其子类的意图很好,但它们的设计很差且令人困惑,使用起来很麻烦。这就是我推荐上述java.time的主要原因。
答案的另一部分是Calendar
宽大地计算其字段。因此,当您在调用Calendar
后在调试器中查看Calendar
对象时,它将包含很多垃圾值。调用set
会强制getTime()
计算其字段,因此在调用之后,它在调试器中的显示方式应该更有意义。再次,这令人困惑,并且有时也可以在不使用调试器的情况下观察到它。
java.time在较新和较旧的Android设备上均可正常运行。它只需要至少 Java 6 。
Calendar
导入日期和时间类。org.threeten.bp
。java.time
向Java 6和7(JSR-310的ThreeTen)的反向端口。答案 3 :(得分:0)
初始化Calendar对象时,它将获取当前时间,包括当前的秒和毫秒。提供的代码设置小时和分钟,但不设置秒和毫秒,而是保留设置Calendar对象初始化时的时间。 为了将秒和纳秒设置为零,请使用:
StartCalendar.set(Year, Month, DayofMonth, Hour, Minute, 0,0);