使用 Java GregorianCalendar 类打印正确的日期

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12592600/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 09:27:37  来源:igfitidea点击:

Printing the correct date with Java GregorianCalendar Class

java

提问by user1696162

I'm trying to print a few things, such as today's date, the day of the week, the date that it will be 100 days from now, the day of the week one hundred days from now, my birthday and day of the week, and 10,000 days after my birthday and that day of the week. Now, I understand that the GregorianCalendar starts at 0 for January and goes to 11 for December. I get that, so it makes sense that when I attempt to print the date it says today's date is 8/25/12 rather than 9/25/12, but I have no idea how to correct this without setting the date ahead an extra month and then actually putting the month into October rather than September.

我正在尝试打印一些内容,例如今天的日期,星期几,从现在起 100 天后的日期,从现在起一百天后的星期几,我的生日和星期几,以及我生日后的 10,000 天和一周中的那一天。现在,我知道 GregorianCalendar 一月从 0 开始,十二月从 11 开始。我明白了,所以当我尝试打印日期时,它说今天的日期是 8/25/12 而不是 9/25/12,这是有道理的,但我不知道如何在不提前设置日期的情况下更正这一点月,然后实际上将月份放入 10 月而不是 9 月。

Here is what I'm dealing with currently.

这是我目前正在处理的。

        GregorianCalendar cal = new GregorianCalendar();
        int dayOfMonth = cal.get(Calendar.DAY_OF_MONTH);
        int month = cal.get(Calendar.MONTH);
        int year = cal.get(Calendar.YEAR);
        int weekday = cal.get(Calendar.DAY_OF_WEEK);
        cal.add(Calendar.DAY_OF_MONTH, 100);
        int dayOfMonth2 = cal.get(Calendar.DAY_OF_MONTH);
        int month2 = cal.get(Calendar.MONTH);
        int year2 = cal.get(Calendar.YEAR);
        int weekday2 = cal.get(Calendar.DAY_OF_WEEK);
        GregorianCalendar birthday = new GregorianCalendar(1994, Calendar.JANUARY, 1);
        int dayOfMonth3 = birthday.get(Calendar.DAY_OF_MONTH);
        int month3 = birthday.get(Calendar.MONTH);
        int year3 = birthday.get(Calendar.YEAR);
        int weekday3 = birthday.get(Calendar.DAY_OF_WEEK);
        birthday.add(Calendar.DAY_OF_MONTH, 10000);
        int weekday4 = birthday.get(Calendar.DAY_OF_WEEK);
        int dayOfMonth4 = birthday.get(Calendar.DAY_OF_MONTH);
        int month4 = birthday.get(Calendar.MONTH);
        int year4 = birthday.get(Calendar.YEAR);
        System.out.printf("Todays date is " +month + "/" +dayOfMonth +"/" +year +".");
        System.out.printf(" It is day " +weekday +" of the week");
        System.out.println("");
        System.out.printf("In 100 days it will be " +month2 + "/" +dayOfMonth2 +"/" +year2 +". ");
        System.out.printf("Day " +weekday2 +" of the week");
        System.out.println("");
        System.out.printf("My Birthday is " +month3 + "/" +dayOfMonth3 +"/" +year3 +". "+"Day " +weekday3 +" of the week");
        System.out.println("");
        System.out.printf("10,000 days after my birthday is " +month4 + "/" +dayOfMonth4 +"/" +year4 +". " +"Day " +weekday4 +" of the week");

So I need help correcting the month for today's date, the date in 100 days, the date of my birthday, and 10,000 days after my birthday. Any help or insight is much appreciated.

所以我需要帮助更正今天的日期、100 天后的日期、我的生日日期和我生日后 10,000 天的月份。非常感谢任何帮助或见解。

回答by matt b

I get that, so it makes sense that when I attempt to print the date it says today's date is 8/25/12 rather than 9/25/12, but I have no idea how to correct this without setting the date ahead an extra month

我明白了,所以当我尝试打印日期时,它说今天的日期是 8/25/12 而不是 9/25/12,这是有道理的,但我不知道如何在不提前设置日期的情况下更正这一点月

If you are going to print the month by doing

如果您要通过执行以下操作来打印月份

int month = cal.get(Calendar.MONTH);
...
 System.out.printf("Todays date is " + month + ...

Then you want to print month + 1, not just month.

然后你想打印month + 1,而不仅仅是month.

Ultimately though you are going to save a lot more time and headache by just using SimpleDateFormatfor formatting Dates as Strings.

最终,尽管您将通过仅使用SimpleDateFormat将日期格式化为字符串来节省更多时间和头痛。

回答by duffymo

Yes, you need to know that Calendar.JANUARY equals zero. Months are zero-based for Calendar.

是的,您需要知道 Calendar.JANUARY 等于零。日历的月份是从零开始的。

You're working far too hard here. You're dealing too much with primitives.

你在这里工作太辛苦了。你处理太多原始类型。

Here's how to print today's date:

以下是打印今天日期的方法:

DateFormat formatter = new SimpleDateFormat("yyyy-MMM-dd");
formatter.setLenient(false);
Date today = new Date();
System.out.println(formatter.format(today));  

Here's how to get 100 days from now:

以下是从现在起获得 100 天的方法:

Calendar calendar = Calendar.getInstance();
calendar.setTime(today);
calendar.add(Calendar.DAY_OF_YEAR, 100);
Date oneHundredDaysFromToday = calendar.getTime();
System.out.println(formatter.format(oneHundredDaysFromToday));

Stop dealing with all those intvalues.

停止处理所有这些int值。

回答by Basil Bourque

tl;dr

tl;博士

LocalDate.now()
         .toString()  // Expecting January 23, 2018.

2018-01-23

2018-01-23

LocalDate.now()
         .plusDays( 10 )
         .toString()  // Expecting February 2, 2018.

2018-02-02

2018-02-02

Avoid legacy date-time classes

避免遗留的日期时间类

The Calendarand GregorianCalendarclasses are confusing, poorly-designed, and troublesome. Avoid these classes and the related old legacy date-time classes. Now supplanted by the java.timeclasses.

CalendarGregorianCalendar类混淆,设计拙劣的,又麻烦。避免使用这些类和相关的旧遗留日期时间类。现在被java.time类取代。

java.time

时间

today's date,

今天的日期,

LocalDate

LocalDate

The LocalDateclass represents a date-only value without time-of-day and without time zone.

LocalDate级表示没有时间一天和不同时区的日期,唯一的价值。

A time zone is crucial in determining a date. For any given moment, the date varies around the globe by zone. For example, a few minutes after midnight in Paris Franceis a new day while still “yesterday” in Montréal Québec.

时区对于确定日期至关重要。对于任何给定时刻,日期因地区而异。例如,在法国巴黎午夜过后几分钟是新的一天,而在魁北克蒙特利尔仍然是“昨天” 。

If no time zone is specified, the JVM implicitly applies its current default time zone. That default may change at any moment, so your results may vary. Better to specify your desired/expected time zone explicitly as an argument.

如果未指定时区,JVM 会隐式应用其当前默认时区。该默认值可能随时更改,因此您的结果可能会有所不同。最好将您想要/预期的时区明确指定为参数。

Specify a proper time zone namein the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 3-4 letter abbreviation such as ESTor ISTas they are nottrue time zones, not standardized, and not even unique(!).

以、、 或等格式指定正确的时区名称。永远不要使用 3-4 个字母的缩写,例如或因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。continent/regionAmerica/MontrealAfrica/CasablancaPacific/AucklandESTIST

ZoneId z = ZoneId.of( "America/Montreal" ) ;  
LocalDate today = LocalDate.now( z ) ;

If you want to use the JVM's current default time zone, ask for it and pass as an argument. If omitted, the JVM's current default is applied implicitly. Better to be explicit, as the default may be changed at any moment during runtimeby any code in any thread of any app within the JVM.

如果您想使用 JVM 的当前默认时区,请询问它并作为参数传递。如果省略,则隐式应用 JVM 的当前默认值。最好是明确的,因为JVM 中任何应用程序的任何线程中的任何代码都可能在运行时随时更改默认值。

ZoneId z = ZoneId.systemDefault() ;  // Get JVM's current default time zone.

Or specify a date. You may set the month by a number, with sane numbering 1-12 for January-December.

或指定日期。您可以通过数字设置月份,对于 1 月至 12 月,合理的编号为 1-12。

LocalDate ld = LocalDate.of( 1986 , 2 , 23 ) ;  // Years use sane direct numbering (1986 means year 1986). Months use sane numbering, 1-12 for January-December.

Or, better, use the Monthenum objects pre-defined, one for each month of the year. Tip: Use these Monthobjects throughout your codebase rather than a mere integer number to make your code more self-documenting, ensure valid values, and provide type-safety.

或者,更好的是使用Month预定义的枚举对象,一年中的每个月一个。提示:Month在整个代码库中使用这些对象而不仅仅是整数,以使您的代码更具自文档性、确保有效值并提供类型安全

LocalDate ld = LocalDate.of( 1986 , Month.FEBRUARY , 23 ) ;

Day of week

星期几

the day of the week,

星期几,

The DayOfWeekclass represents a day-of-week from Monday to Sunday. Pass these objects around your code rather than a mere integer 1-7.

DayOfWeek级代表一天的一周,从周一到周日。在您的代码周围传递这些对象,而不仅仅是整数 1-7。

DayOfWeek dow = ld.getDayOfWeek() ;

If you must have a number, get 1-7 for Monday-Sunday per ISO 8601 standard.

如果您必须有一个数字,请根据 ISO 8601 标准在周一至周日获得 1-7。

int dowNumber = ld.getDayOfWeek().getValue() ;  // Number 1-7 for Monday-Sunday.

Adding days

添加天数

the date that it will be 100 days from now, the day of the week one hundred days from now, my birthday and day of the week, and 10,000 days after my birthday and that day of the week.

从现在起 100 天后的日期,从现在起一百天后的星期几,我的生日和星期几,以及我生日后的 10,000 天和一周中的那一天。

Add and subtracting days is simple, using plus…and minus…methods.

加减天数简单,用途plus…minus…方法。

LocalDate later = ld.plusDays( 10 ) ;  // Ten days later.

Alternatively, use a Periodto represent a number of years-months-days.

或者,使用 aPeriod来表示年-月-日的数量。

Period p = Period.ofDays( 10 ) ;
LocalDate later = ld.plus( p ) ;

One hundred days or 10,000 days would be added the same way.

一百天或一万天会以同样的方式添加。

LocalDate later = ld.plusDays( 10_000 ) ;

Numbering

编号

Now, I understand that the GregorianCalendar starts at 0 for January and goes to 11 for December

现在,我知道 GregorianCalendar 一月从 0 开始,十二月从 11 开始

The java.time classes use sane numbering, unlike the legacy classes.

与遗留类不同,java.time 类使用合理的编号。

  • The number 2018is the year 2018. No math with 1900.
  • Months are numbered 1-12 for January-December.
  • Days of the week are numbered 1-7 for Monday-Sunday, per the ISO 8601standard.
  • 数字2018是 2018 年。没有数学1900
  • 一月至十二月的月份编号为 1-12。
  • 根据ISO 8601标准,星期一至星期日的星期几编号为 1-7 。


About java.time

关于java.time

The java.timeframework is built into Java 8 and later. These classes supplant the troublesome old legacydate-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

java.time框架是建立在Java 8和更高版本。这些类取代了麻烦的旧的遗留日期时间类,例如java.util.Date, Calendar, & SimpleDateFormat

The Joda-Timeproject, now in maintenance mode, advises migration to the java.timeclasses.

现在处于维护模式Joda-Time项目建议迁移到java.time类。

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

要了解更多信息,请参阅Oracle 教程。并在 Stack Overflow 上搜索许多示例和解释。规范是JSR 310

Where to obtain the java.time classes?

从哪里获得 java.time 类?

The ThreeTen-Extraproject extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

ThreeTen-额外项目与其他类扩展java.time。该项目是未来可能添加到 java.time 的试验场。你可能在这里找到一些有用的类,比如IntervalYearWeekYearQuarter,和更多