Android-GregorianCalendar显示错误的月份

问题描述 投票:2回答:2

[我尝试搜索互联网,并在StackOverlflow上找到了很多有关同一主题的问题,但找不到我能理解的任何东西...

所以,我有这个数据类,其中包含GregorianCalendar类型的dateOfOrigin。使用gson,我将转换所有json并返回包含所有位置的Observable数组。在json文件中,我将dateOfOrigin添加为这样的对象:

{
    "id": 6,
    "name": "Fuse",
    "image": "fuse.jpg",
    "street": "Blaesstraat 208",
    "city": "Brussels Hoofdstedelijk Gewest",
    "zip": 1000,
    "date_of_origin": {"year":1994,"month":4,"dayOfMonth":16},
    "parking": true
}

这就是我的数据类的样子:

数据类位置(val id:整数val名称:字符串,val image:字符串,val street:字符串,val city:字符串,val zip:整数,@SerializedName(“ date_of_origin”)val originDate:GregorianCalendar ?,val parking:布尔值= true,var imageBitmap:位图? =空)

每当我尝试这样设置dateText时:

originDate?.let {
    dateText = "${it.get(Calendar.DAY_OF_MONTH)} ${it.getDisplayName(Calendar.MONTH, Calendar.SHORT, Locale.getDefault())} ${it.get(Calendar.YEAR)}"

    dateText = resources.getString(R.string.origin_date, dateText)
}

它输出16 May 1994而不是16 Apr 1994

我不知道如何解决此问题...

编辑在大多数情况下,从月份中减去1似乎可以解决此问题。仍然,我有一个结果应该输出30 Jan 2016但显示1 Feb 2016

"date_of_origin": {"year":2016,"month":1,"dayOfMonth":30}
java android kotlin gregorian-calendar
2个回答
2
投票

GregorianCalendar代表月份,数字范围为011。这意味着数字0表示为1月,11表示为12月。

因此,如果您的API使用的逻辑与Java实现不同,则需要减去1

更新:GregorianCalendar(2016, 1, 30)被理解为2月30日。这是内部转换为3月1日的日期,因此当您从日期中减去一个月时,便是2月1日。您需要已经创建一个GregorianCalendar类的实例,并且已经减去了月份号。一月为0,二月为1,依此类推。


0
投票

Answer by Hawklike是正确的。您被GregorianCalendar类使用的疯狂月份编号所欺骗。避免此类的许多原因之一。


请勿使用GregorianCalendar。此类是与最早的Java版本捆绑在一起的日期时间类的一部分。几年前,这些类被JSR 310中定义的现代java.time类所取代。

如果必须与尚未更新为java.time的代码进行互操作,请进行转换。调用添加到旧类中的新转换方法。

GregorianCalendar替换为GregorianCalendar

ZonedDateTime

朝另一个方向。

ZonedDateTime

或将整数分解为多个部分。

ZonedDateTime zdt = myGregCal.toZonedDateTime() ;  // From legacy class to modern class.

或使用月份号而不是月份的ZonedDateTime zdt = ZonedDateTime.of( 2021 , Month.JANUARY , 23 , 12 , 0 , 0 , 0 , ZoneId.of( "America/Montreal" ) ) ; GregorianCalendar myGregCal = GregorianCalendar.from( zdt ) ; 枚举。请注意,与LocalDate ld = LocalDate.of( 2021 , Month.JANUARY , 23 ) ; LocalTime lt = LocalTime.of( 12 , 0 ) ; ZoneId z = ZoneId.of( "America/Montreal" ) ; ZonedDateTime zdt = ZonedDateTime.of( ld , lt , z ) ; GregorianCalendar myGregCal = GregorianCalendar.from( zdt ) ; 不同,java.time使用理智的编号,1月至12月为1-12。

Month

关于java.time

GregorianCalendar框架内置于Java 8及更高版本中。这些类取代了麻烦的旧LocalDate.of( 2021 , 1 , 23 ) // Same effect as Month.JANUARY. 日期时间类,例如java.timelegacyjava.util.Date

要了解更多信息,请参见java.util.Date。并在Stack Overflow中搜索许多示例和说明。规格为Calendar

Calendar项目现在位于SimpleDateFormat中,建议迁移到SimpleDateFormat类。

您可以直接与数据库交换java.time对象。使用兼容Oracle Tutorial或更高版本的JSR 310。不需要字符串,不需要Joda-Time类。 Hibernate 5和JPA 2.2支持java.time

从哪里获取java.time类?

  • ThreeTen-Backport
  • © www.soinside.com 2019 - 2024. All rights reserved.