当前位置: 首页 > 面试题库 >

Java公历返回错误的月份

朱鹏
2023-03-14
问题内容

所以我在这里呆了几个小时,它返回正确的Year和Day,但是由于某种奇怪的原因,它返回了错误的月份。我确定它是一个简单的修复程序,但我似乎无法弄清楚。

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

问题答案:

要获得本月的1-12数字:

LocalDate.now()
         .getMonthValue()

最好指定所需/预期的时区。

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

类似地,呼叫.getYear().getDayOfMonth()

细节

它返回错误的月份

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

那么有没有解决的办法?

是的,有一种解决方法。使用良好的日期时间库,而不要使用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() );

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

年份是2016

月是12

月的名字是décembre

一天是14

请参阅IdeOne.com中的实时代码。

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

LocalDate.now( z );

具体时刻

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

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

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

Z输出中的in
Zulu表示UTC。

您可以分配时区以调整为特定的挂钟时间。

ZoneId z = ZoneId.of( "America/Montreal" );
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和更高版本。这些类取代麻烦的老传统日期时间类,如java.util.DateCalendar,和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的许多功能在 ThreeTen- Backport中都被反向移植到Java 6和7 。
  • 安卓系统
    • 所述 ThreeTenABP 项目适应 ThreeTen-反向移植 (上述)为Android特异性。
    • 请参阅 如何使用…

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

旧答案-乔达时间

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

  • 立即使用Joda-Time 2.3。
  • 将来,使用Java 8,可以考虑迁移到JSR 310:Date and Time API,该API取代了Date / Calendar类,并且受Joda-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

PS:当我注意到您任意选择的Long导致了第十三星期五时,我感到不寒而栗!



 类似资料:
  • 所以我已经研究了几个小时了,它返回了正确的年和日,但是由于一些奇怪的原因,它返回了错误的月份。我确信这是一个简单的修复,但我似乎无法解决这个问题。

  • 问题内容: 执行以上代码段后,month的值为10而不是11。 问题答案: 月份从0而不是1索引,因此10是11月,而11是12月。

  • 问题内容: 我尝试使用日历设置若干年后的简单日期: 字符串日期是此方法的参数。 我的问题是,否则日期返回还可以,但是月份数字完全错误,并且每次运行时看起来都越来越大!我想念的是什么? 问题答案: 测试

  • 我有一个验证方法,将两个输入作为开始日期和结束日期,并检查结束日期是否有效,即在开始日期之后。我使用Calendar方法获取两个日期的毫秒数并得到差值。如果差值为负值,则其无效的结束日期,即结束日期早于开始日期。结束日期的毫秒值应始终大于开始日期。但在某些情况下,在开始日期的情况下,getTimeInMillis()会提供更大的值。 这是我的代码: 输出为: 这里2015-01-31是开始日期,2

  • 问题内容: 我正在使用和函数在下拉列表中显示接下来的3个月。 PHP代码: 但是,如果脚本在服务器日期为30日或31日时运行,则下个月(二月)将显示为三月。即上面的脚本应该返回 但是,相反,它实际上显示 那是因为2月没有30号或31号,所以脚本将“ 31/02”转换为“ 01/03”。 我已经阅读了php.net上的页面,此问题已经提出,但是还没有任何有用的解决方案。因此,有人可以帮助我找到解决此

  • 我想在将一周的第一天设置为周日后,将2018年10月9日这一周作为一年中的42周。我仍然从下面的代码片段中得到41的输出 我错过了什么吗? 背景:我们一周的开始可能是可变的。我们的配置能够让用户决定一周的第一天。