【问题标题】:get startday of month and endday of month using calendar class in Java使用Java中的日历类获取月份的开始日期和结束日期
【发布时间】:2014-02-04 20:48:32
【问题描述】:

给定一年零一个月;我想要两个Date Objects。一个用于当月的startDate,一个用于当月的end Date。我在这里实现了它并且它有效。但这看起来太冗长了,我想知道是否有一个巧妙的解决方案;

例如,给定 2014 年 3 月, 开始日期为 3 月 1 日,结束日期为 3 月 31 日(Date objects,精度为毫秒)

public setDates(int month,int year) {

        Calendar calendar = Calendar.getInstance();


        // Use the calendar to get the startDate and endDate of this Invoice.
        calendar.set(Calendar.YEAR, year);
        calendar.set(Calendar.MONTH,month);

        //set start date
        calendar.set(Calendar.DAY_OF_MONTH,
                     calendar.getActualMinimum(Calendar.DAY_OF_MONTH));
        calendar.set(Calendar.HOUR_OF_DAY,
                     calendar.getActualMinimum(Calendar.HOUR_OF_DAY));
        calendar.set(Calendar.MINUTE,
                     calendar.getActualMinimum(Calendar.MINUTE));
        calendar.set(Calendar.SECOND,
                     calendar.getActualMinimum(Calendar.SECOND));
        calendar.set(Calendar.MILLISECOND,
                     calendar.getActualMinimum(Calendar.MILLISECOND));
        this.startDate = calendar.getTime();

        //endDate start date
        calendar.set(Calendar.DAY_OF_MONTH,
                     calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
        calendar.set(Calendar.HOUR_OF_DAY,
                     calendar.getActualMaximum(Calendar.HOUR_OF_DAY));
        calendar.set(Calendar.MINUTE,
                     calendar.getActualMaximum(Calendar.MINUTE));
        calendar.set(Calendar.SECOND,
                     calendar.getActualMaximum(Calendar.SECOND));
        calendar.set(Calendar.MILLISECOND,
                     calendar.getActualMaximum(Calendar.MILLISECOND));
        this.endDate = calendar.getTime();
}

【问题讨论】:

  • 你可以使用 Joda Time 吗?它会让事情变得简单很多。此外,请考虑您对哪个时区感兴趣 - 对于不同的时区,该月将在不同的时间开始和结束。最后,考虑使用独占上限而不是包容上限 - 所以基本上是下个月的开始。
  • 以什么方式使用独占上界?我不知道乔达时间是什么。所以我需要一些时间来阅读和理解..
  • 我认为 Joda Time 将成为这个的基础:download.java.net/jdk8/docs/api/java/time/package-summary.html
  • 它没有那么复杂(对于你的任务),你可以试试。但是如果你坚持使用 JDK 7 的内置功能,你也可以。
  • @user1988876:有了独占上界,您无需担心您是取当月最后一天的开始还是end 一个月的最后一天,等等 - 一个间隔的唯一上限是下一个间隔的包含下限。

标签: java date calendar


【解决方案1】:

您可以通过一些假设使这段代码变得相当简单:

  • 每月的第一天总是第一天
  • 最小小时数始终为 0
  • ...等

然后,您可以通过加一个月并减一毫秒来找到该月的最后一毫秒。

所以代码可能如下所示:

// Note year/month reversal: try to consistently use larger units first. It
// makes for a cleaner API.
public setDates(int year, int month, TimeZone zone) {
    Calendar calendar = Calendar.getInstance(zone);

    // Do you really want 0-based months, like Java has? Consider month - 1.
    calendar.set(year, month, 1, 0, 0, 0);
    calendar.clear(Calendar.MILLISECOND);
    startDate = calendar.getTime();

    // Get to the last millisecond in the month
    calendar.add(Calendar.MONTH, 1);
    calendar.add(Calendar.MILLISECOND, -1);
    endDate = calendar.getTime();
}

要使用独占上限(我建议),只需去掉接近末尾的 calendar.add(Calendar.MILLISECOND, -1)

哦,我强烈推荐使用 Joda Time 而不是 java.util.Date 等 - 这是一个更清洁的 API。

【讨论】:

  • 正如我在下面评论的那样,当您添加月份时,您最终会更改日历对象。如果你想完整地引用这个对象而不修改它怎么办?为什么需要calendar.clear(Calendar.MILLISECOND);
  • 创建另一个 Calendar 实例以获得您的下限和上限。
  • @user1988876:那就不要使用那个对象了!此方法创建一个新的Calendar 对象,在该方法完成后,它将有资格进行垃圾回收。如果您有一个不想更改的Calendar,请不要更改它...
  • Calendar 上调用getTime() 并拥有自己的Date 后,对Calendar 的后续更改不会影响Date...仅供参考。跨度>
  • 好的,知道了。你为什么用calendar.clear(Calendar.MILLISECOND)calendar.set(year, month, 1, 0, 0, 0);而不是calendar.set(Calendar.YEAR, year); calendar.set(Calendar.MONTH,month);
【解决方案2】:

以 3 月 1 日为准。将 1 添加到月份字段。然后减去 1 天。
这是您本月的最后一天。

第一天是明确的,它是一年中的第一个月。

冗长是可以的,没有太多冗长的代码版本
(在 JDK

【讨论】:

  • 我建议我的方法算作“不那么冗长”的代码——而且也更简单,IMO。
  • 我不想修改我的日历对象,因为我将使用它来计算开始和结束日期;如果我做 calendar.add(Calendar.MONTH, 1);我正在更改我的日历对象。
  • 您可以随时创建副本。
【解决方案3】:

请使用 JODA。

import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;

import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.Period;


public class Dates {

    /**
     * @param args
     */
    public static void main(String[] args) {
        //without JODA

        Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("Europe/Helsinki"));

        calendar.set(1921, 4, 1, 0, 0, 0);
        calendar.clear(Calendar.MILLISECOND);
        Date startDate = calendar.getTime();

        System.out.println(startDate);

        calendar.add(Calendar.MONTH, 1);
        calendar.add(Calendar.MILLISECOND, -1);
        Date endDate = calendar.getTime();

        System.out.println(endDate);

        /*
         * Sat Apr 30 19:20:08 BRT 1921
         * Tue May 31 19:20:07 BRT 1921
         */

        //with JODA
        DateTimeZone zone = DateTimeZone.forTimeZone(TimeZone.getTimeZone("Europe/Helsinki"));
        DateTime dt = new DateTime(1921, 4, 1, 0, 0, 0, 0, zone);
        DateTime plusPeriod = dt.plus(Period.months(1)).minus(Period.millis(1));

        System.out.println(dt);
        System.out.println(plusPeriod);

        /*
         * 1921-04-01T00:00:00.000+01:39:52
         * 1921-04-30T23:59:59.999+01:39:52
         */
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-09
    • 1970-01-01
    • 1970-01-01
    • 2019-07-07
    • 1970-01-01
    相关资源
    最近更新 更多