【问题标题】:Printing the correct date with Java GregorianCalendar Class使用 Java GregorianCalendar 类打印正确的日期
【发布时间】:2012-09-25 23:34:13
【问题描述】:

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

这是我目前正在处理的问题。

        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");

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

【问题讨论】:

  • 添加示例输出会有所帮助。

标签: java


【解决方案1】:

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

如果你要打印月份

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

那么你想打印month + 1,而不仅仅是month

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

【讨论】:

  • 谢谢,正是我想要的。我应该想到这一点,因为它是如此简单。我一直在尝试使用 cal.add,这弄乱了代码的其他部分。
【解决方案2】:

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

你在这里工作太辛苦了。你在处理原语太多了。

打印今天日期的方法如下:

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

以下是如何获得 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));

停止处理所有这些int 值。

【讨论】:

    【解决方案3】:

    tl;博士

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

    2018-01-23

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

    2018-02-02

    避免使用旧的日期时间类

    CalendarGregorianCalendar 类令人困惑、设计不佳且很麻烦。避免使用这些类和相关的旧旧日期时间类。现在被 java.time 类所取代。

    java.time

    今天的日期,

    LocalDate

    LocalDate 类表示没有时间和时区的仅日期值。

    时区对于确定日期至关重要。对于任何给定的时刻,日期在全球范围内因区域而异。例如,Paris France 中午夜后几分钟是新的一天,而 Montréal Québec 中仍然是“昨天”。

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

    continent/region 的格式指定proper time zone name,例如America/MontrealAfrica/CasablancaPacific/Auckland。切勿使用 3-4 个字母的缩写,例如 ESTIST,因为它们不是真正的时区,没有标准化,甚至不是唯一的 (!)。

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

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

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

    或者指定一个日期。您可以通过数字设置月份,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.
    

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

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

    星期几

    星期几,

    DayOfWeek 类表示从星期一到星期日的一周中的某一天。在您的代码中传递这些对象,而不仅仅是整数 1-7。

    DayOfWeek dow = ld.getDayOfWeek() ;
    

    如果您必须有数字,请按照 ISO 8601 标准为周一至周日获取 1-7。

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

    添加天数

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

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

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

    或者,使用Period 来表示若干年-月-日。

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

    一百天或一万天将以同样的方式相加。

    LocalDate later = ld.plusDays( 10_000 ) ;
    

    编号

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

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

    • 2018 的数字是 2018 年。1900 没有数学运算。
    • 1 月至 12 月的月份编号为 1-12。
    • 根据ISO 8601 标准,周一至周日将一周中的日子编号为 1-7。

    关于java.time

    java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧 legacy 日期时间类,例如 java.util.DateCalendarSimpleDateFormat

    Joda-Time 项目现在位于maintenance mode,建议迁移到java.time 类。

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

    从哪里获得 java.time 类?

    ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。您可以在这里找到一些有用的类,例如IntervalYearWeekYearQuartermore

    【讨论】:

      猜你喜欢
      • 2019-06-18
      • 2020-06-26
      • 2014-09-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多