为什么Calendar.SEPTEMBER不工作?

问题描述:

我想看一个包含整个日子的月份。为什么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,日历.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) 此检查查看已用各种su注释的Android API调用pport注释(例如RequiresPermission或UiThread),并标记任何未按注释指定正确使用API​​的调用。此检查标记的错误示例: 将错误类型的资源整数(例如R.string)传递给期望不同类型的API(例如R.dimen)。 忘记在需要它的方法中调用重写的方法 调用需要权限但未在清单中声明权限的方法 将资源颜色引用传递给期望RGB整数值的方法。 ...还有更多。欲了解更多信息,请参阅developer.android.com/tools/debugging/annotations.html

当我运行它,尽管红线的文档,它显示复杂的日期,如: see

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

+3

您已经回答说:'必须是一个: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' –

+0

不可能看到我想要的吗?@ModularSynth – BatuZ

+0

你看到它列在可用选项中吗? –

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

假设您正在迭代数月,则需要改为Calendar.MONTH

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

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

Calendar API有时可能会引起混淆(大多数时候是IMO),并且有lots of problemsdesign issues

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

如果在默认时区中获得Calendar,则替换的一个好候选是org.threeten.bp.ZonedDateTime(它表示特定时区中的日期和时间)。首先我使用now()方法(在JVM默认时区取当前日期/时间)。然后我使用org.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); 
} 

例如,如果您想添加/减去分钟而不是几个月,则可以使用方法minusMinutes和​​。还有其他单位的其他方法(例如小时,天等),check the javadoc可查看所有选项。


使用默认时区的问题是,它can be changed without notice, even at runtime,所以最好总是让它明确你使用哪一个。

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

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

而且随着ThreeTen反向移植,你可以使用ZoneId.of(zoneName):以上

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

在这个例子中,我用Europe/London,但你可以改变它到任何你想要的时区。该API使用IANA timezones names(始终格式为Region/City,如America/Sao_PauloEurope/Berlin)。 避免使用3字母缩写(如CST或),因为它们是ambiguous and not standard

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