23

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

4

6 回答 6

44

你可以使用java.util.Calendar

Calendar calendar = Calendar.getInstance();
calendar.clear();
calendar.set(Calendar.MONTH, month);
calendar.set(Calendar.YEAR, year);
Date date = calendar.getTime();
于 2012-09-19T16:39:17.390 回答
33

java.time

使用java.timeJava 8 内置的框架

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
于 2015-11-24T11:09:07.607 回答
5

自从您要求 a 以来可能没有答案java.util.Date,但这似乎是一个很好的机会来指出 Java 中大多数日期和时间以及日历的工作可能应该使用Joda-Time库来完成,在这种情况下

new LocalDate(year, month, 1)

想到了。

Joda-Time 在一个月中的日子里还有许多其他的好东西。例如,如果你想知道当月的第一天,你可以写

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

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

new Date("2012-09-19")

此版本的构造函数已弃用,因此不要使用它。您应该创建一个日期格式化程序并调用parse. 这是一个很好的建议,因为您可能将yearmonth作为整数值,并且需要制作一个好的字符串,正确填充和分隔等等,这在所有情况下都很难做到。出于这个原因,请使用知道如何完美处理所有这些内容的日期格式化程序。

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

于 2012-09-19T16:47:43.213 回答
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?

于 2012-09-19T16:42:17.143 回答
0

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

于 2012-09-19T16:58:00.740 回答
0

不要使用这个答案。使用PrzemekRay Toel的答案。正如 Przemek 所说,更喜欢使用 aYearMonth来表示年份和月份。正如两者所说,如果您必须使用日期,请使用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 中的其他程序更改。换句话说,我们不能真正确定我们得到了什么。

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

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

如果您的 API 是宽松的,并且只需要在正确的月份内的某个时间点,您最好在每月 2 号 UTC 或您自己的时区的每月 3 号给它。前者的方法如下:

    Date oldFashionedDateObject = Date.from(expiration
            .atDay(2)
            .atStartOfDay(ZoneOffset.UTC)
            .toInstant());
于 2017-11-25T17:21:05.550 回答