我想将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是我正在使用的版本。
答案 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)
java.util.GregorianCalendar.from(
java.time.LocalDate.parse( myJodaLocalDate.toString() )
.atStartOfDay( ZoneId.of( "America/Montreal" ) )
)
您正在混合两个截然不同的日期时间库:
旧的遗留日期时间类设计不当,令人困惑且麻烦;避免他们。被java.time类取代。
Joda-Time项目非常出色,为java.time提供了灵感。但现在该项目位于maintenance mode,团队建议迁移到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 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.Date
,.Calendar
和& java.text.SimpleDateFormat
现在位于Joda-Time的maintenance mode项目建议迁移到java.time。
要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310。
从哪里获取java.time类?
ThreeTen-Extra项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如Interval
,YearWeek
,YearQuarter
和more。
答案 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));