繁体   English   中英

如何获取某个月的所有日期

[英]How to get all the dates in a certain month

当我使用这些代码时,会得到我们所在月份的日期。例如,我可以看到介于01/09/201721/09/2017之间的日期。

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.set(Calendar.DAY_OF_MONTH, 1);
while (mStart.compareTo(today) <= 0) {
    data.add(createItem(mStart.getTimeInMillis()));
    mStart.add(Calendar.DAY_OF_MONTH, 1);
}
    cursor.addAll(data);
}

但是,我需要特定月份的日期。 如何查看其他月份中的其他日期? 例如,我想查看四月的日期。 应该是九月。 (我知道它与today.clone()有关,但我不知道如何更改它)。

我计划在Android Studio中使用对话框将月份分开,当我选择任何月份时,我应该看到月份的所有日期。

我只需要一个月的日期即可完成此操作,例如4月。 如何获得四月的日期? (如果我得到四月的日期,那么我可以在所有月份中都这样做)

编辑一些变化和结果:

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.set(Calendar.MONTH, Calendar.APRIL);
mStart.set(Calendar.DAY_OF_MONTH, 1);
data.add(createItem(mStart.getTimeInMillis()));
cursor.addAll(data);
}

我刚到01/04/2017

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.set(Calendar.MONTH, Calendar.APRIL);
int daysInMonth = today.getActualMaximum(Calendar.DAY_OF_MONTH);
for(int i=0; i<daysInMonth; i++ ){
mStart.set(Calendar.DAY_OF_MONTH, i);}
data.add(createItem(mStart.getTimeInMillis()));
cursor.addAll(data);
}

我只有29/04/2017 ,如果我将mStart.set(Calendar.DAY_OF_MONTH, i)更改为mStart.set(Calendar.DAY_OF_MONTH, 1)结果将是01/04/2017

要获取特定月份的所有日期,请将“ Calendar设置为该月中的某个日期,例如1号,向Calendar询问该月中的日期数,然后获取日期。

您也可以获取日期直到月份更改为止,但是下面的代码要求输入月份中的天数,以显示如何执行此操作。

此代码仅打印日期。 当然,您可以选择与他们一起做任何事情。

public static void printDatesInMonth(int year, int month) {
    SimpleDateFormat fmt = new SimpleDateFormat("dd/MM/yyyy");
    Calendar cal = Calendar.getInstance();
    cal.clear();
    cal.set(year, month - 1, 1);
    int daysInMonth = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
    for (int i = 0; i < daysInMonth; i++) {
        System.out.println(fmt.format(cal.getTime()));
        cal.add(Calendar.DAY_OF_MONTH, 1);
    }
}

测试

printDatesInMonth(2017, 2);

产量

01/02/2017
02/02/2017
03/02/2017
04/02/2017
05/02/2017
06/02/2017
07/02/2017
08/02/2017
09/02/2017
10/02/2017
11/02/2017
12/02/2017
13/02/2017
14/02/2017
15/02/2017
16/02/2017
17/02/2017
18/02/2017
19/02/2017
20/02/2017
21/02/2017
22/02/2017
23/02/2017
24/02/2017
25/02/2017
26/02/2017
27/02/2017
28/02/2017

您是从今天的日期开始的,因此假设您想要从那里开始的月份,只需使用:

cal.add(Calendar.MONTH, 1)移至下个月或

cal.add(Calendar.MONTH, -1)移至上个月。

@Andreas的答案提供了使用Calendar 我只想添加另一种方法。

旧的类( DateCalendarSimpleDateFormat )存在很多问题设计问题 ,并且已被新的API取代。

在Android中,您可以使用ThreeTen Backport ,这是Java 8的新日期/时间类的绝佳反向端口 为了使其工作,您还需要ThreeTenABP (更多有关如何在此处使用它的信息 )。

首先,您可以使用org.threeten.bp.YearMonth表示月份和年份(在本例中为2017年4月)。 然后,您将循环浏览本月的所有日子。

getTimeInMillis()方法采用自纪元( 1970-01-01T00:00Z )以来的毫秒数,并且在您的代码中,它是从JVM默认时区中午夜的日期开始获取的。

在ThreeTen Backport中,您可以通过将YearMonth转换为org.threeten.bp.LocalDate ,然后将其转换为JVM默认时区(使用org.threeten.bp.ZoneId ),然后使用生成的org.threeten.bp.ZonedDateTime获取纪元毫秒值:

// April 2017
YearMonth ym = YearMonth.of(2017, 4);
// get the last day of month
int lastDay = ym.lengthOfMonth();
// loop through the days
for(int day = 1; day <= lastDay; day++) {
    // create the day
    LocalDate dt = ym.atDay(day);
    // set to midnight at JVM default timezone
    ZonedDateTime z = dt.atStartOfDay(ZoneId.systemDefault());
    // get epoch millis value
    data.add(createItem(z.toInstant().toEpochMilli()));
}

如果还需要检查日期是否在当前日期之前,则可以添加其他检查:

....
// today
LocalDate today = LocalDate.now();
// loop through the days
for (int day = 1; day <= lastDay; day++) {
    // create the day
    LocalDate dt = ym.atDay(day);
    if (dt.isBefore(today)) {
        ....

尽管看起来很方便,但使用TimeZone.getDefault()ZoneId.systemDefault()也很棘手,因为即使在运行也可以在不通知的情况下更改 JVM默认时区,所以最好始终使它明确您正在使用的一个。

该API使用IANA时区名称 (格式始终为Region/City ,例如America/Sao_PauloEurope/Berlin )。 避免使用3字母缩写(例如CSTPST ),因为它们是模棱两可的,不是标准的

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

示例:要使用纽约时区 ,您可以执行以下操作:

....
// New York timezone
ZoneId ny = ZoneId.of("America/New_York");
// today in New York timezone
LocalDate today = LocalDate.now(ny);
// loop through the days
for (int day = 1; day <= lastDay; day++) {
    // create the day
    LocalDate dt = ym.atDay(day);
    if (dt.isBefore(today)) {
        // set to midnight at New York timezone
        ZonedDateTime z = dt.atStartOfDay(ny);
        ....

America/New_YorkZoneId.getAvailableZoneIds()返回的有效名称之一。


java.util.Calendar中

关于代码,从零天开始,然后将项目添加到循环外的data中(因此,您只添加最后一个-缩进代码,您将看到data.addfor循环外)。 代码应该是这样的:

Calendar mStart = (Calendar) today.clone();
// set day to 1
mStart.set(Calendar.DAY_OF_MONTH, 1);
// set month to April
mStart.set(Calendar.MONTH, Calendar.APRIL);
// now mStart is April 1st, we can begin the loop

// get the number of days in April
int daysInMonth = today.getActualMaximum(Calendar.DAY_OF_MONTH);
// loop from day 1 to daysInMonth
for (int i = 1; i <= daysInMonth; i++) {
    // set the day
    mStart.set(Calendar.DAY_OF_MONTH, i);
    // add item for the day
    data.add(createItem(mStart.getTimeInMillis()));
}
// add all items to cursor
cursor.addAll(data);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM