为什么Calendar.SEPTEMBER不工作?

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

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,Google日历.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)。 忘记在需要它的方法中调用重写的方法(通过超级方法)调用需要权限但未在清单中声明该权限的方法将资源颜色引用传递给期望RGB整数值的方法。 ...还有很多。 有关更多信息,请参阅developer.android.com/tools/debugging/annotations.html上的文档

当我运行它尽管红线,它显示复杂的日期,如:看到

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


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

假设你迭代了几个月,你需要改变Calendar.MONTH


正如@迈克尔的答案中所解释的,您不能在add方法中使用Calendar.SEPTEMBER

如果您想添加或减去指定的月份数量,只需使用Calendar.MONTH 。 如果您想添加/减去天数,则可以使用Calendar.DAY_OF_MONTH等。

Calendar API有时可能会引起混淆(大多数时候是IMO),并且存在很多问题和设计问题。

在Android中,有更好的选择:您可以使用ThreeTen Backport,这是Java 8新日期/时间类的一个很好的后端。 为了使它工作,你还需要ThreeTenABP(更多关于如何在这里使用它)。

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

我还使用minusMonths方法在当前日期前5个月获取日期,并在循环内部使用toInstant()方法获取plusMonths值,并使用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字母缩写(如CSTPST ),因为它们不明确而不是标准。

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

链接地址: http://www.djcxy.com/p/6287.html

上一篇: Why Calendar.SEPTEMBER is not working?

下一篇: What's the simplest way to print a Java array?