-5

我想看到一个包含一整天的月份。

private void createRandomData(InMemoryCursor cursor) {
    List<Object[]> data = new ArrayList<>();
    Calendar today = Calendar.getInstance(TimeZone.getDefault(), Locale.getDefault());
    today.set(Calendar.HOUR_OF_DAY,0);
    today.set(Calendar.MINUTE, 0);
    today.set(Calendar.SECOND, 0);
    today.set(Calendar.MILLISECOND, 0);
    mStart = (Calendar) today.clone();
    mStart.add(Calendar.SEPTEMBER, -5);
    while (mStart.compareTo(today) <= 0) {
        data.add(createItem(mStart.getTimeInMillis()));
        mStart.add(Calendar.SEPTEMBER, 1);
    }
    cursor.addAll(data);
}

当我写 Calendar.SEPTEMBER(或其他月份)时,我在 Calendar.SEPTEMBER 上看到红线,其中包含:

必须是以下之一:Calendar.ERA、Calendar.YEAR、Calendar.MONTH、Calendar.WEEK_OF_YEAR、Calendar.WEEK_OF_MONTH、Calendar.DATE、Calendar.DAY_OF_MONTH、Calendar.DAY_OF_YEAR、Calendar.DAY_OF_WEEK、Calendar.DAY_OF_WEEK_IN_MONTH、Calendar.AM_PM、Calendar .HOUR、Calendar.HOUR_OF_DAY、Calendar.MINUTE、Calendar.SECOND、Calendar.MILLISECOND、Calendar.ZONE_OFFSET、Calendar.DST_OFFSET less... (Ctrl+F1) 此检查着眼于已使用各种支持注释进行注释的 Android API 调用(例如 RequiresPermission 或 UiThread)并标记任何未按照注释指定的正确使用 API 的调用。此检查标记的错误示例:将错误类型的资源整数(例如 R.string)传递给需要不同类型的 API(例如 R.dimen)。忘记在需要它的方法中调用被覆盖的方法(通过 super)调用需要权限的方法而没有在清单中声明该权限将资源颜色引用传递给需要 RGB 整数值的方法。...还有很多。有关更多信息,请参阅 developer.android.com/tools/debugging/annotations.html 上的文档

当我不顾红线运行它时,它会显示复杂的日期,例如: 请参阅

我使用来自 GitHub 的这个库:https ://github.com/jruesga/timeline-chart-view 问题与库有关吗?或者它是关于 Java 日历的?

4

2 回答 2

3

正如@Michael's answer中所解释的,您不能Calendar.SEPTEMBER在该add方法中使用。

如果要添加或减去指定的月数,只需使用Calendar.MONTH. 如果要添加/减去天数,请使用Calendar.DAY_OF_MONTH等等。

CalendarAPI 有时可能会令人困惑(大多数时候,IMO),并且有很多问题设计问题

在 Android 中,有一个更好的选择:您可以使用ThreeTen Backport,它是 Java 8 新日期/时间类的一个很好的反向端口。要使其工作,您还需要ThreeTenABP(更多关于如何使用它的信息)。

当您Calendar在默认时区中获得 a 时,一个很好的替换候选者是 a org.threeten.bp.ZonedDateTime(它代表特定时区中的日期和时间)。首先,我使用该now()方法(采用 JVM 默认时区的当前日期/时间)。然后我使用 aorg.threeten.bp.LocalTime将时间设置为午夜。

我还使用该minusMonths方法获取当前日期前 5 个月的日期,在循环中我使用该toInstant()方法获取毫秒值,以及plusMonths获取下个月的方法:

// get today at default timezone, at midnight
ZonedDateTime today = ZonedDateTime.now().with(LocalTime.MIDNIGHT);
// 5 months ago
ZonedDateTime start = today.minusMonths(5);
while (start.compareTo(today) <= 0) {
    data.add(createItem(start.toInstant().toEpochMilli()));
    start = start.plusMonths(1);
}

例如,如果你想加/减分钟而不是月份,你可以使用方法minusMinutesplusMinutes. 其他单位也有其他方法(例如小时、天等),请查看 javadoc以查看所有选项。


使用默认时区的问题是它可以在没有通知的情况下更改,即使在运行时也是如此,因此最好始终明确说明您正在使用哪个时区。

使用Calendar,您可以使用TimeZone.getTimeZone(zoneName)

Calendar todayCal = Calendar.getInstance(TimeZone.getTimeZone("Europe/London"), Locale.getDefault());

使用 ThreeTen Backport,您可以使用ZoneId.of(zoneName)

ZonedDateTime today = ZonedDateTime.now(ZoneId.of("Europe/London")).with(LocalTime.MIDNIGHT);

在上面的示例中,我使用了Europe/London,但您可以将其更改为您想要的任何时区。API 使用IANA 时区名称(始终采用格式Region/City,例如America/Sao_PauloEurope/Berlin)。避免使用 3 个字母的缩写(如CSTor PST),因为它们模棱两可且不标准

ZoneId.getAvailableZoneIds()您可以通过调用或获取可用时区列表(并选择最适合您系统的时区)TimeZone.getAvailableIDs()

于 2017-09-06T17:23:39.673 回答
2

您正在使用不兼容的选项。的第一个参数Calendar.add()是时间单位(天、周、小时等),由错误中列出的可能选项定义。Calendar.SEPTEMBER不是时间单位,它是代表MONTH九月的便利常数,通常在set()方法中使用。

假设您要迭代数月,Calendar.MONTH则需要。

于 2017-09-06T16:21:24.093 回答