将日期转换为GregorianCalendar日期格式

时间:2016-10-14 02:09:23

标签: java gregorian-calendar localdate

我想将org.joda.time.LocalDate对象转换为java.util.GregorianCalendar。 java.util.GregorianCalendar月份从索引0到11显示。所以十月用数字9表示,十一月用数字10表示....而对于LocalDate十月则用数字10表示,十一月用11 ......表示。

我正在使用GregorianCalendar的现有应用程序。现在我想将我通过方法调用收到的LocalDate值转换为GregorianCalendar格式,以便匹配月份值。

我已经搜索了很多博客,但无法转换价值。下面是我尝试过的代码,但仍然无法将日期格式更改为GregorianCalendar格式。

java代码:

import java.text.SimpleDateFormat;
import java.util.GregorianCalendar;
import org.joda.time.DateTime;
import org.joda.time.LocalDate;
class Convert{
    public static String format(GregorianCalendar calendar){
        SimpleDateFormat fmt = new SimpleDateFormat("dd-M-yyyy");
        fmt.setCalendar(calendar);
        String dateFormatted = fmt.format(calendar.getTime());
        System.out.println("--date formatted--- " + dateFormatted);
        return dateFormatted;
    }
    void convertLocalDateToGregorianCalendar(){
        LocalDate localDate = new LocalDate();
        DateTime dateTimeObj = localDate.toDateTimeAtStartOfDay();
        GregorianCalendar gc = new GregorianCalendar();
        gc.setTimeInMillis(dateTimeObj.getMillis());
        String formattedGCDate = format(gc);
        System.out.println("converted LocalDate to GregorianDate date value " + formattedGCDate);
    }
    public static void main(String[] args) {
                new Convert().convertLocalDateToGregorianCalendar();         
} }

输出:

--date formatted--- 13-10-2016
converted LocalDate to GregorianDate date value 13-10-2016

输出中的预期日期值: 13-9-2016(GregorianCalendar 10月份用数字9表示。)

PS:java5是我正在使用的版本。

3 个答案:

答案 0 :(得分:1)

我认为您不能直接使用SimpleDateFormat来格式化格里高利日期。 我有两个建议可以解决:

1.如果您不关心重复使用calendar.getTime(),您可以在fmt.format之前将月份滚动(或添加)-1:

SimpleDateFormat fmt = new SimpleDateFormat("dd-M-yyyy");
fmt.setCalendar(calendar);    
calendar.roll(Calendar.MONTH, -1); //or add
String dateFormatted = fmt.format(calendar.getTime());
System.out.println("--date formatted--- " + dateFormatted);

2.不使用SimpleDateFormat,calendar.get(Calendar.MONTH)将返回9作为您的期望:

public static String format(GregorianCalendar calendar){
    String dateFormatted = String.format("%s-%s-%s", calendar.get(Calendar.DATE),
                            calendar.get(Calendar.MONTH), calendar.get(Calendar.YEAR));
    System.out.println("--date formatted--- " + dateFormatted);
    return dateFormatted;
}

答案 1 :(得分:1)

TL;博士

java.util.GregorianCalendar.from( 
    java.time.LocalDate.parse( myJodaLocalDate.toString() )
    .atStartOfDay( ZoneId.of( "America/Montreal" ) )
)

详细

您正在混合两个截然不同的日期时间库:

  • Joda-Time
  • 与Java捆绑的旧版日期时间类

旧的遗留日期时间类设计不当,令人困惑且麻烦;避免他们。被java.time类取代。

Joda-Time项目非常出色,为java.time提供了灵感。但现在该项目位于maintenance mode,团队建议迁移到java.time类。

java.time

通过浏览字符串将org.joda.time.LocalDate转换为java.time.LocalDate。两者都默认使用标准ISO 8601格式,因此无需指定格式化模式。

java.time.LocalDate ld = java.time.LocalDate.parse( myJodaLocalDate.toString() );

您显然需要日期时间值,因此我们需要将日期时间添加到仅限日期LocalDate。显然你想要在一天中的第一时刻。不要假设第一个时刻是00:00:00,因为夏令时(DST)等异常可能意味着另一个时间,例如01:00:00。让java.time确定当下。您需要指定所需/预期的时区以解决此类异常并调整wall-clock time

您的问题中的代码忽略了时区的这个关键问题。如果忽略,则会隐式应用JVM的当前默认时区。在运行时期间,此默认值可随时更改。最好明确一点。

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

我强烈建议您坚持使用java.time类。但是如果你绝对需要旧的遗留类,比如用于与尚未更新到java.time的旧代码接口,那么你可以转换。查看添加到旧类的新方法。

GregorianCalendar gc = java.util.GregorianCalendar.from( zdt );

月份索引

该问题询问如何生成一个字符串,其中月份编号为1到12月的从零开始的索引0-11,以匹配GregorianCalendar在内部的工作方式。

坦率地说,回答这将是一种伤害。以零为基础的数字编号是疯狂疯狂的疯狂。这样做会导致混乱。在GregorianCalendar中这样做是一个非常糟糕的设计选择。它的使用应该被熄灭而不是提升。

关于java.time

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

现在位于Joda-Timemaintenance mode项目建议迁移到java.time。

要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310

从哪里获取java.time类?

ThreeTen-Extra项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如IntervalYearWeekYearQuartermore

答案 2 :(得分:1)

如果我理解正确的问题,我们会混合两件事

a)Calender / GregorianCalender中月份的内部表示以及实际的日历本身。

正确地说的内部表示代表0-11表示一年中的12个月,人类对此的解释是一年中的1-12个月。当您调用格式化操作时,您将获得日期显示在实际人类日历上的方式,即10月,10月中的日期。内部表示仍然是9.如果您问如何,可以使用API​​检查

gc.setTimeInMillis(dateTimeObj.getMillis());
System.out.println(gc.get(Calendar.MONTH));

这会打印数字9

如果您想要日期的内部表示,您也可以这样做。一个真正的hacky方式如下,虽然我不保证,但给你一个整体的想法。

LocalDate localDate = new LocalDate();
DateTime dateTimeObj = localDate.toDateTimeAtStartOfDay();
GregorianCalendar gc = new GregorianCalendar();
gc.setTimeInMillis(dateTimeObj.getMillis());
System.out.println(gc.get(Calendar.DAY_OF_MONTH) +"-"+ ("00"+ gc.get(Calendar.MONTH)).substring(1)  +"-"+gc.get(Calendar.YEAR));