Java 公历返回错误的月份

Java Gregorian Calendar Returns Wrong Month(Java 公历返回错误的月份)

本文介绍了Java 公历返回错误的月份的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我现在在这里待了几个小时,它返回了正确的年份和日期,但由于某些奇怪的原因,它返回了错误的月份.我确定这是一个简单的解决方法,但我似乎无法弄清楚.

package gregoriancalendar;导入 java.util.GregorianCalendar;公共课 Calendar8_5 {公共静态无效主要(字符串[]参数){GregorianCalendar 日历 = new GregorianCalendar();System.out.println("当前年月日:");System.out.println("年份是" + calendar.get(1));System.out.println("月份是" + calendar.get(2));System.out.println("今天是" + calendar.get(5));calendar.setTimeInMillis(1234567898765L);//经过时间System.out.println("设置值为1234567898765L");System.out.println("年份是" + calendar.get(1));System.out.println("月份是" + calendar.get(2));System.out.println("今天是" + calendar.get(5));}}

解决方案

tl;dr

要获取当前月份的数字 1-12:

LocalDate.now().getMonthValue()

最好指定您想要/预期的时区.

LocalDate.now(ZoneId.of("美国/蒙特利尔")).getMonthValue()

类似调用.getYear().getDayOfMonth().

详情

<块引用>

返回错误的月份

正如其他人所说,在 Calendar 中,1 月至 12 月的月份疯狂地编号为 0-11,而不是 1-12.旧日期时间类中许多糟糕的设计决策之一.这些类现在是遗留的,被 java.time 类所取代.

<块引用>

那么有办法解决这个问题吗?

是的,有一个解决方法.使用一个好的日期时间库而不是 java.util.Date/Calendar 的混乱.现代方式是使用 java.time 类.

当前时刻

时区对于获取当前日期和时间至关重要.对于任何给定的时刻,日期和挂钟时间因地区而异.

ZoneId z = ZoneId.of("美国/蒙特利尔");ZonedDateTime zdt = ZonedDateTime.now(z);

您可以通过 Month 枚举和日期.

System.out.println("当前:" + zdt);System.out.println("年份是" + zdt.getYear());System.out.println("月份是" + zdt.getMonthValue());System.out.println( "月份名称为 " + zdt.getMonth().getDisplayName( TextStyle.FULL , Locale.CANADA_FRENCH ) );//或 Locale.US、Locale.ITALY 等.System.out.println("天是" + zdt.getDayOfMonth());

<块引用>

当前:2016-12-14T04:54:44.802-05:00[美国/蒙特利尔]

2016 年

月份是 12

月份名称是十二月

第 14 天

查看 IdeOne.com 中的实时代码.

如果您只关心日期而不关心时间,请使用 LocalDate 类.

LocalDate.now(z);

特定时刻

您可以将时刻指定为自 epoch 以来的毫秒数1970 年 UTC 的第一刻.

长输入 = 1_234_567_898_765L ;Instant Instant = Instant.ofEpochMilli( 输入 );

<块引用>

instant.toString(): 2009-02-13T23:31:38.765Z

该输出中的 ZZulu 的缩写,意思是 UTC.

您可以指定时区以调整到特定的挂钟时间.

ZoneId z = ZoneId.of("美国/蒙特利尔");ZonedDateTime zdt = instant.atZone(z);

<块引用>

zdt.toString(): 2009-02-13T18:31:38.765-05:00[美国/蒙特利尔]

查看IdeOne.com 中的实时代码.

我确实建议以这种方式交换日期时间数据.最好序列化为 ISO 8601 格式的文本.例如:2009-02-13T23:31:38.765Z

<小时>

关于java.time

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

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

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

从哪里获得 java.time 类?

  • Java SE 8SE 9 及更高版本
    • 内置.
    • 标准 Java API 的一部分,带有捆绑实现.
    • Java 9 添加了一些小功能和修复.
  • Java SE 6SE 7
    • 大部分 java.time 功能都向后移植到 Java 6 &7 在 ThreeTen-Backport.
  • Android
    • ThreeTenABP 项目采用 ThreeTen-专门针对 Android 的反向移植(如上所述).
    • 请参阅如何使用…….

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

<小时>

旧答案 - Joda-Time

更新:Joda-Time 项目,现在在 维护模式,建议迁移到 java.time 类.

  • 现在使用 Joda-Time 2.3.
  • 未来,在 Java 8 中,考虑迁移到 JSR 310:日期和时间API 取代了 Date/Calendar 类,并受到 Joda-Time 的启发.

示例代码

今天

//© 2013 Basil Bourque.任何为此承担全部责任的人都可以永远免费使用此源代码.//导入 o​​rg.joda.time.*;//通常最好明确时区而不是依赖默认值.DateTimeZone denverTimeZone = DateTimeZone.forID("美国/丹佛");java.util.Locale locale = Locale.FRANCE;现在日期时间 = 新日期时间(denverTimeZone);System.out.println("当前年月日:" + now );System.out.println("年份是" + now.year().getAsText(locale));System.out.println("月份是" + now.monthOfYear().getAsText(locale));System.out.println("今天是" + now.dayOfMonth().getAsText(locale));System.out.println();//空行.

运行时……

当前年月&日期:2013-12-04T01:58:24.322-07:00年份是 2013 年月份是十二月天是 4

有一天

//专注于整数来处理日期时间通常不是一个好主意,但你要求它.日期时间 someDateTime = new DateTime(1234567898765L, DateTimeZone.UTC);System.out.println("1234567898765L的设置值为:" + someDateTime );System.out.println("年份是" + someDateTime.year().getAsText(locale));System.out.println("月份是" + someDateTime.monthOfYear().getAsText(locale));System.out.println("月份是" + someDateTime.dayOfMonth().getAsText(locale));System.out.println("星期几是" + someDateTime.dayOfWeek().getAsText(locale));System.out.println("一年中的哪一天是" + someDateTime.dayOfYear().getAsText(locale));

运行时……

1234567898765L的设置值为:2009-02-13T23:31:38.765Z年份是 2009月份是 février一个月中的第 13 天星期几是 vendredi一年中的第 44 天

<小时>

附:当我注意到你随意选择的龙导致了十三号星期五时,我的背脊发凉!

So I been at this for a few hours now and it returns the correct Year, and Day but for some odd reason it returns the wrong month. I'm sure its a simple fix but I can't seem to figure it out.

package gregoriancalendar;

import java.util.GregorianCalendar;

public class Calendar8_5 {



public static void main(String[] args){

GregorianCalendar calendar = new GregorianCalendar();
System.out.println("Current Year, Month & Date: ");
System.out.println("Year is " + calendar.get(1));
System.out.println("Month is " + calendar.get(2));
System.out.println("Day is " + calendar.get(5));


calendar.setTimeInMillis(1234567898765L);
//Elapse Time
System.out.println("Set Value of 1234567898765L");
System.out.println("Year is " + calendar.get(1));
System.out.println("Month is " + calendar.get(2));
System.out.println("Day is " + calendar.get(5));
   }
  }

解决方案

tl;dr

To get a number 1-12 for current month:

LocalDate.now()
         .getMonthValue()

Better to specify your desired/expected time zone.

LocalDate.now( 
    ZoneId.of( "America/Montreal" ) 
).getMonthValue()

Similarly call .getYear() and .getDayOfMonth().

Details

it returns the wrong month

As others said, in Calendar the months January-December are crazily numbered 0-11 rather than 1-12. One of many poor design decisions in the old date-time classes. Those classes are now legacy, supplanted by the java.time classes.

So is there a work around this?

Yes, there is a workaround. Use a good date-time library rather than the mess that is java.util.Date/Calendar. The modern way is with the java.time classes.

Current moment

Time zone is crucial in getting the current date and time. For any given moment the date and wall-clock time vary by zone.

ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.now( z );

You can interrogate for the various components such as year, month number, localized name of month via Month enum, and day-of-month.

System.out.println ( "Current: " + zdt );
System.out.println( "Year is " + zdt.getYear() );
System.out.println( "Month is " + zdt.getMonthValue() );
System.out.println( "Month name is " + zdt.getMonth().getDisplayName( TextStyle.FULL , Locale.CANADA_FRENCH ) );  // Or Locale.US, Locale.ITALY, etc.
System.out.println( "Day is " + zdt.getDayOfMonth() );

Current: 2016-12-14T04:54:44.802-05:00[America/Montreal]

Year is 2016

Month is 12

Month name is décembre

Day is 14

See live code in IdeOne.com.

If you only care about the date and not the time-of-day, use the LocalDate class.

LocalDate.now( z );

Specific moment

You can specify a moment as a count of milliseconds since the epoch of first moment of 1970 in UTC.

long input = 1_234_567_898_765L ;
Instant instant = Instant.ofEpochMilli( input );

instant.toString(): 2009-02-13T23:31:38.765Z

The Z in that output is short for Zulu and means UTC.

You can assign a time zone to adjust into a particular wall-clock time.

ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone( z );

zdt.toString(): 2009-02-13T18:31:38.765-05:00[America/Montreal]

See live code in IdeOne.com.

I do not recommend exchanging date-time data this way. Better to serialize to text in ISO 8601 formats. For example: 2009-02-13T23:31:38.765Z


About java.time

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

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

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

Where to obtain the java.time classes?

  • Java SE 8 and SE 9 and later
    • Built-in.
    • Part of the standard Java API with a bundled implementation.
    • Java 9 adds some minor features and fixes.
  • Java SE 6 and SE 7
    • Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
  • Android
    • The ThreeTenABP project adapts ThreeTen-Backport (mentioned above) for Android specifically.
    • See How to use….

The ThreeTen-Extra project 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.


Old Answer - Joda-Time

Update: The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

  • Use Joda-Time 2.3 now.
  • In the future, with Java 8, consider moving to JSR 310: Date and Time API which supplants the Date/Calendar classes and is inspired by Joda-Time.

Example Code

Today

// © 2013 Basil Bourque. This source code may be used freely forever by anyone taking full responsibility for doing so.
// import org.joda.time.*;

// Generally best to be explicit about time zone rather than depend on default.
DateTimeZone denverTimeZone = DateTimeZone.forID( "America/Denver" );
java.util.Locale locale = Locale.FRANCE;

DateTime now = new DateTime( denverTimeZone );

System.out.println( "Current Year, Month & Day for: " + now );
System.out.println( "Year is " + now.year().getAsText( locale ) );
System.out.println( "Month is " + now.monthOfYear().getAsText( locale ) );
System.out.println( "Day is " + now.dayOfMonth().getAsText( locale ) );
System.out.println(); // blank line.

When run…

Current Year, Month & Day for: 2013-12-04T01:58:24.322-07:00
Year is 2013
Month is décembre
Day is 4

Some Day

// Not generally a good idea to focus on integers for working with date-time, but you asked for it.
DateTime someDateTime = new DateTime( 1234567898765L, DateTimeZone.UTC );

System.out.println( "Set Value of 1234567898765L is: " + someDateTime );
System.out.println( "Year is " + someDateTime.year().getAsText( locale ) );
System.out.println( "Month is " + someDateTime.monthOfYear().getAsText( locale ) );
System.out.println( "Day of month is " + someDateTime.dayOfMonth().getAsText( locale ) );
System.out.println( "Day of week is " + someDateTime.dayOfWeek().getAsText( locale ) );
System.out.println( "Day of year is " + someDateTime.dayOfYear().getAsText( locale ) );

When run…

Set Value of 1234567898765L is: 2009-02-13T23:31:38.765Z
Year is 2009
Month is février
Day of month is 13
Day of week is vendredi
Day of year is 44


P.S. I just got the chills down my back when I noticed your arbitrarily chosen Long resulted in Friday The Thirteenth!

这篇关于Java 公历返回错误的月份的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本文标题为:Java 公历返回错误的月份

基础教程推荐