Java 公历返回错误的月份

标签 java calendar gregorian-calendar

所以我已经花了几个小时了,它返回了正确的年份和日期,但由于某种奇怪的原因,它返回了错误的月份。我确信这是一个简单的修复,但我似乎无法弄清楚。

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;博士

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

LocalDate.now()
         .getMonthValue()

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

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

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

详细信息

it returns the wrong month

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

So is there a work around this?

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

当前时刻

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

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

您可以通过 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

参见 live code in IdeOne.com

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

LocalDate.now( z );

特定时刻

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

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

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

该输出中的 ZZulu 的缩写,表示 UTC

您可以指定时区以适应特定的挂钟时间。

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

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

参见 live code in IdeOne.com

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

<小时/>

关于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 future 可能添加的内容的试验场。您可能会在这里找到一些有用的类,例如 IntervalYearWeekYearQuartermore

<小时/>

旧答案 - Joda-Time

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

示例代码

今天

// © 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.

运行时...

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

有一天

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

运行时...

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
<小时/>

附注当我注意到你随意选择的“长”结果是“十三号星期五”时,我感到后背发冷!

关于Java 公历返回错误的月份,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20367546/

相关文章:

java - 如何从 View 模型更改 flowScope 对象?

java - 如何从菜单按键调用上下文菜单?

java - Intellij Idea NoClassDefFoundError : com/intellij/util/messages/Topic

c# - 在工具提示中显示 Web 表单

java - Java GregorianCalendar 中的 DAY_OF_WEEK 始终返回 7

java - 对 Path2D 的绘图进行动画处理

android - 如何在 Android 中使用滑动手势创建一个简单的日历 View

java - Android 日历 API 与事件

java - 为什么我的日期不能正确添加天数?

java - 字符串到 XMLGregorianCalendar 问题