Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/371.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 将日期转换为GregoriaCalendar日期格式_Java_Gregorian Calendar_Localdate - Fatal编程技术网

Java 将日期转换为GregoriaCalendar日期格式

Java 将日期转换为GregoriaCalendar日期格式,java,gregorian-calendar,localdate,Java,Gregorian Calendar,Localdate,我想将org.joda.time.LocalDate对象转换为java.util.Gregorianalendar。java.util.GregorianCalendar月从索引0显示到11。因此,10月用数字9表示,11月用数字10表示……而对于LocalDate,10月用数字10表示,11月用数字11表示 我正在处理他们使用GregorianCalendar的现有应用程序。现在,我想将通过方法调用收到的LocalDate值转换为GregoriaCalendar格式,以便匹配月份值 我已经搜索

我想将org.joda.time.LocalDate对象转换为java.util.Gregorianalendar。java.util.GregorianCalendar月从索引0显示到11。因此,10月用数字9表示,11月用数字10表示……而对于LocalDate,10月用数字10表示,11月用数字11表示

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

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

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
输出中的预期日期值: 2016年9月13日(对于GregoriaCalendar,10月份用数字9表示)


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

我认为您不能直接使用SimpleDataFormat来格式化公历日期。 我有两个建议:

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.不要使用SimpleDataFormat,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;
}
tl;博士 细节 您混合了两个非常不同的日期时间库:

  • 与Java捆绑的遗留日期时间类
旧的遗留日期时间类设计得很差,令人困惑,而且很麻烦;避开它们。被班级取代了

Joda Time项目非常优秀,为java.Time提供了灵感。但是现在项目已经开始,团队建议迁移到java.time类

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

java.time.LocalDate ld = java.time.LocalDate.parse( myJodaLocalDate.toString() );
显然,您需要一个日期时间值,因此我们只需在日期中添加一个时间
LocalDate
。显然,你想从一天的第一刻开始。不要假设第一个时刻是
00:00:00
,因为夏令时(DST)等异常可能意味着另一个时间,如
01:00:00
。让java.time来决定时刻。您需要指定所需/预期时区,以解释此类异常情况并调整时间

你问题中的代码忽略了时区这一关键问题。如果忽略,将隐式应用JVM的当前默认时区。此默认值可以在运行时的任何时刻更改。所以最好是直截了当

ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ld.atStartOfDay( z );
我强烈建议您坚持使用java.time类。但是,如果您绝对需要旧的遗留类,例如用于与尚未更新为java.time的旧代码接口,那么您可以转换。查看添加到旧类的新方法

GregorianCalendar gc = java.util.GregorianCalendar.from( zdt );
月份索引 问题是如何生成一个月号为0-11的字符串作为1月到12月的零基索引,以匹配GregoriaCalendar的内部工作方式

坦率地说,回答这个问题是一种伤害。以零为基数来计算月份是疯狂的。这样做会造成无尽的混乱。在Gregorianalendar这样做一开始是一个非常糟糕的设计选择。它的使用应该停止而不是推广


关于java.time 该框架内置于Java8及更高版本中。这些类取代了麻烦的旧日期时间类,例如,&

该项目现已启动,建议迁移到java.time

要了解更多信息,请参阅。并搜索堆栈溢出以获得许多示例和解释。规格是

从哪里获得java.time类

  • 后来
    • 内置的
    • 标准JavaAPI的一部分,带有捆绑实现
    • Java9添加了一些次要功能和修复
    • 大部分java.time功能都在中向后移植到Java6和Java7
    • 该项目专门针对Android采用了Three Ten Backport(如上所述)

该项目使用其他类扩展了java.time。这个项目是java.time将来可能添加的一个试验场。您可能会在这里找到一些有用的类,例如、、和。

如果我正确理解这个问题,我们将混合两种东西

a) 日历/公历内月份的内部表示和实际日历本身

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

gc.setTimeInMillis(dateTimeObj.getMillis());
System.out.println(gc.get(Calendar.MONTH));
这将打印数字
9

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

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