如何在Java中从月份和年份生成日期?

时间:2012-09-19 16:36:27

标签: java date

我需要为信用卡到期日期生成一个新的Date对象,我只有一个月和一年,我怎样才能根据这两个生成一个Date?我需要最简单的方法。我在这里阅读其他一些答案,但它们看起来都太复杂了。

6 个答案:

答案 0 :(得分:41)

您可以使用java.util.Calendar

Calendar calendar = Calendar.getInstance();
calendar.clear();
calendar.set(Calendar.MONTH, month);
calendar.set(Calendar.YEAR, year);
Date date = calendar.getTime();

答案 1 :(得分:21)

java.time

使用Java 8中内置的java.time框架

import java.time.YearMonth;

int year = 2015;
int month = 12;
YearMonth.of(year,month); // 2015-12

来自String

YearMonth.parse("2015-12"); // 2015-12

使用自定义DateTimeFormatter

import java.time.format.DateTimeFormatter;

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM yyyy");
YearMonth.parse("12 2015", formatter); // 2015-12

<强>转化 要将YearMonth转换为LocalDate的更标准日期表示。

LocalDate startMonth = date.atDay(1); //2015-12-01
LocalDate endMonth = date.atEndOfMonth(); //2015-12-31

答案 2 :(得分:5)

因为你要求java.util.Date,所以可能是一个非答案,但这似乎是一个很好的机会,可以指出Java中日期,时间和日历的大部分工作都应该用{{3}完成。 } library,在这种情况下

new LocalDate(year, month, 1)
想到了。

Joda-Time在本月的日子里有很多其他好处。例如,如果您想知道当月的第一天,可以写

LocalDate firstOfThisMonth = new LocalDate().withDayOfMonth(1);

在评论中,您询问是否将字符串传递给java.util.Date构造函数,例如:

new Date("2012-09-19")

此版本的构造函数已弃用,因此请勿使用它。您应该创建日期格式化程序并调用parse。这是一个很好的建议,因为你可能会将yearmonth作为整数值,并且需要制作一个好的字符串,正确填充和分隔以及所有这些,这在所有方面都难以理解案例。因此,请使用日期格式化程序,它知道如何完美地处理所有这些内容。

其他早期的答案显示了如何做到这一点。

答案 3 :(得分:4)

SimpleDateFormat formatter = new SimpleDateFormat("yyyy/MM");
Date utilDate = formatter.parse(year + "/" + month);

Create a java.util.Date Object from a Year, Month, Day Forma复制 或者可能喜欢

DateTime aDate = new DateTime(year, month, 1, 0, 0, 0);

What's the Right Way to Create a Date in Java?

复制

答案 4 :(得分:0)

最常见的方法是使用Date(“YYYY-MM-DD”)构造函数,即使它已被弃用。这是即时创建日期的最简单方法。任何人决定弃用它。万岁日期(“YYYY-MM-DD”)!!!

答案 5 :(得分:0)

请勿使用此答案。使用PrzemekRay Toel的答案。正如Przemek所说,更喜欢用YearMonth表示年份和月份。如前所述,如果您必须使用日期,请使用LocalDate,这是一个没有时间的日期。

如果你绝对不可缺少地需要一个老式的java.util.Date对象用于你无法改变的遗留API,这里有一个简单的方法来获得一个。它可能无法正常工作,它可能无法准确提供您所需的日期,具体取决于您的具体要求。

    YearMonth expiration = YearMonth.of(2021, 8); // or .of(2021, Month.AUGUST);
    Date oldFashionedDateObject = Date.from(expiration
            .atDay(1)
            .atStartOfDay(ZoneId.systemDefault())
            .toInstant());
    System.out.println(oldFashionedDateObject);

在我的电脑上打印

Sun Aug 01 00:00:00 CEST 2021

我们得到的是我当地时区午夜的第一个月 - 更准确地说,是我的JVM的时区设置。这是对遗留API预期的一个很好的猜测,但它也很危险。 JVM的时区设置可能由程序的其他部分或在同一JVM中运行的其他程序在我们的脚下更改。换句话说,我们无法确定我们得到了什么。

如果将日期传输到运行不同时区的计算机(例如从客户端到服务器,反之亦然)或运行到自己的时区的数据库,则时区问题会变得更糟。您的Date将在上个月的时间内出现约50%的风险。

如果您知道最后所需的时区,则有助于指定例如ZoneId.of("America/New_York")而不是上述代码段中的系统默认值。

如果你的API很宽松而且在正确的月份内只需要一些点,那么你最好在本月的第二个月或你自己时区的第三个月给它。以下是如何做前者:

    Date oldFashionedDateObject = Date.from(expiration
            .atDay(2)
            .atStartOfDay(ZoneOffset.UTC)
            .toInstant());