简体   繁体   English

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

[英]Printing the correct date with Java GregorianCalendar Class

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. 我正在尝试打印一些东西,例如今天的日期,星期几,从现在起100天的日期,从现在开始的一周的一天,我的生日和星期几,以及我生日后一万天和一周中的那一天。 Now, I understand that the GregorianCalendar starts at 0 for January and goes to 11 for December. 现在,据我所知,GregorianCalendar从1月份的0开始到12月份的11岁。 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. 我知道了,所以当我尝试打印日期时,它说今天的日期是2012年8月25日而不是9/25/12,这是有道理的,但是我不知道如何在没有提前确定日期的情况下纠正这个问题。一个月,然后实际把月份放到十月而不是九月。

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. 因此,我需要帮助更正今天的日期,100天的日期,生日的日期以及生日后的10,000天。 Any help or insight is much appreciated. 非常感谢任何帮助或见解。

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 我知道了,所以当我尝试打印日期时,它说今天的日期是2012年8月25日而不是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 SimpleDateFormat for formatting Dates as Strings. 最终,通过使用SimpleDateFormat将Dates格式化为字符串,您将节省更多时间和头痛。

Yes, you need to know that Calendar.JANUARY equals zero. 是的,你需要知道Calendar.JANUARY等于零。 Months are zero-based for Calendar. 日历的月份从零开始。

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 int values. 停止处理所有这些int值。

tl;dr TL;博士

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

2018-01-23 2018年1月23日

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

2018-02-02 2018年2月2日

Avoid legacy date-time classes 避免遗留日期时间类

The Calendar and GregorianCalendar classes are confusing, poorly-designed, and troublesome. CalendarGregorianCalendar类令人困惑,设计不佳,麻烦。 Avoid these classes and the related old legacy date-time classes. 避免使用这些类和相关的旧旧日期时间类。 Now supplanted by the java.time classes. 现在取代了java.time类。

java.time java.time

today's date, 今天的日期,

LocalDate

The LocalDate class 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 France is 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. 如果未指定时区,则JVM会隐式应用其当前的默认时区。 That default may change at any moment, so your results may vary. 该默认值可能随时更改,因此您的结果可能会有所不同。 Better to specify your desired/expected time zone explicitly as an argument. 最好明确指定您期望/预期的时区作为参数。

Specify a proper time zone name in the format of continent/region , such as America/Montreal , Africa/Casablanca , or Pacific/Auckland . continent/region的格式指定适当的时区名称 ,例如America/MontrealAfrica/CasablancaPacific/Auckland Never use the 3-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!). 切勿使用3-4字母缩写,例如ESTIST因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。

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. 如果要使用JVM的当前默认时区,请求它并作为参数传递。 If omitted, the JVM's current default is applied implicitly. 如果省略,则隐式应用JVM的当前默认值。 Better to be explicit, as the default may be changed at any moment during runtime by any code in any thread of any app within the 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 Month enum objects pre-defined, one for each month of the year. 或者,更好的是,使用预定义的Month枚举对象,一年中的每个月一个。 Tip: Use these Month objects throughout your codebase rather than a mere integer number to make your code more self-documenting, ensure valid values, and provide type-safety . 提示:在整个代码库中使用这些Month对象而不仅仅是整数,以使代码更加自我记录,确保有效值并提供类型安全性

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

Day of week 星期几

the day of the week, 一周中的哪一天

The DayOfWeek class represents a day-of-week from Monday to Sunday. DayOfWeek类表示从星期一到星期日的星期几。 Pass these objects around your code rather than a mere integer 1-7. 将这些对象传递给代码,而不仅仅是整数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天,从现在起一百天的一周,我的生日和星期几,以及生日后一周和一周中的那一天的日期。

Add and subtracting days is simple, using plus… and minus… methods. 使用plus…minus…方法添加和减去天数很简单。

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

Alternatively, use a Period to represent a number of years-months-days. 或者,使用Period表示若干年 - 月 - 天。

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从1月份的0开始到12月份的11岁

The java.time classes use sane numbering, unlike the legacy classes. 与遗留类不同,java.time类使用合理的编号。

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

About java.time 关于java.time

The java.time framework is built into Java 8 and later. java.time框架内置于Java 8及更高版本中。 These classes supplant the troublesome old legacy date-time classes such as java.util.Date , Calendar , & SimpleDateFormat . 这些类取代了麻烦的旧遗留日期时间类,如java.util.DateCalendarSimpleDateFormat

The Joda-Time project, now in maintenance mode , advises migration to the java.time classes. 现在处于维护模式Joda-Time项目建议迁移到java.time类。

To learn more, see the Oracle Tutorial . 要了解更多信息,请参阅Oracle教程 And search Stack Overflow for many examples and explanations. 并搜索Stack Overflow以获取许多示例和解释。 Specification is JSR 310 . 规范是JSR 310

Where to obtain the java.time classes? 从哪里获取java.time类?

The ThreeTen-Extra project extends java.time with additional classes. ThreeTen-Extra项目使用其他类扩展了java.time。 This project is a proving ground for possible future additions to java.time. 该项目是未来可能添加到java.time的试验场。 You may find some useful classes here such as Interval , YearWeek , YearQuarter , and more . 您可以在这里找到一些有用的类,比如IntervalYearWeekYearQuarter ,和更多

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

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