简体   繁体   English

将日期转换为GregorianCalendar日期格式

[英]converting date to GregorianCalendar Date format

I want to convert the org.joda.time.LocalDate object to java.util.GregorianCalendar. 我想将org.joda.time.LocalDate对象转换为java.util.GregorianCalendar。 java.util.GregorianCalendar month displayed from index 0 to 11. So October is represented with digit 9 , November with digit 10....Whereas for LocalDate October is represented with digit 10, november with 11.... java.util.GregorianCalendar从索引0到11显示的月份。所以十月用数字9表示,十一月用数字10表示....而对于LocalDate十月则用数字10表示,十一月用11 ....

I am working on existing application where they have used GregorianCalendar. 我正在使用GregorianCalendar的现有应用程序。 Now I want to convert my LocalDate value which I had received through a method call into GregorianCalendar format so that month values are matched. 现在我想将我通过方法调用收到的LocalDate值转换为GregorianCalendar格式,以便匹配月份值。

I have already searched many blogs but could not convert the value. 我已经搜索了很多博客,但无法转换价值。 Below is the code I tried but still could not able to change the date format to GregorianCalendar format. 下面是我尝试过的代码,但仍然无法将日期格式更改为GregorianCalendar格式。

java code: 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();         
} }

Output: 输出:

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

Expected date value in the output: 13-9-2016 (As for GregorianCalendar October month is represent with digit 9). 输出中的预期日期值:13-9-2016(格里高利历年10月份用数字9表示)。

PS: java5 is the version I am using. PS:java5是我正在使用的版本。

I think you can't directly use SimpleDateFormat to format Gregorian date. 我想你不能直接使用SimpleDateFormat来格式化格里高利日期。 I have two suggestions work around: 我有两个建议可以解决:

1.If you don't care to reuse the calendar.getTime() you can roll (or add) the month by -1 before fmt.format: 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.Don't use SimpleDateFormat, calendar.get(Calendar.MONTH) will return 9 as your expect: 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;
}

tl;dr TL;博士

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

Details 细节

You are mixing two very different date-time libraries: 您正在混合两个非常不同的日期时间库:

  • Joda-Time 乔达时间
  • legacy date-time classes bundled with Java 与Java捆绑在一起的旧版日期时间类

The old legacy date-time classes are poorly-designed, confusing, and troublesome; 旧的遗留日期时间类设计不当,令人困惑,麻烦; avoid them. 避免他们。 Supplanted by the java.time classes. java.time补充

The Joda-Time project is excellent, and provided the inspiration for java.time. Joda-Time项目非常出色,为java.time提供了灵感。 But now the project is in maintenance mode , with the team advising migration to the java.time classes. 但现在项目处于维护模式 ,团队建议迁移到java.time类。

java.time java.time

Convert your org.joda.time.LocalDate to a java.time.LocalDate by going through a String. 通过遍历String将org.joda.time.LocalDate转换为java.time.LocalDate Both use standard ISO 8601 formats by default, so no need to specify a formatting pattern. 两者都默认使用标准的ISO 8601格式,因此无需指定格式化模式。

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

You apparently want a date-time value, so we need to add a time-of-day to your date-only LocalDate . 您显然需要一个日期时间值,因此我们需要在您的仅限日期的LocalDate添加一个时间。 Apparently you want to go with the first moment of the day. 显然你想要在一天中的第一时刻。 Do not assume this first moment is 00:00:00 as anomalies such as Daylight Saving Time (DST) may mean another time such as 01:00:00 . 不要假设第一时刻是00:00:00 ,因为夏令时(DST)等异常可能意味着另一个时间,例如01:00:00 Let java.time determine the moment. 让java.time确定当下。 You need to specify your desired/expected time zone to account for such anomalies and to adjust the wall-clock time . 您需要指定所需/预期的时区以解决此类异常并调整挂钟时间

The code in your Question ignores this crucial issue of time zone. 您的问题中的代码忽略了时区的这个关键问题。 If ignored, your JVM's current default time zone is implicitly applied. 如果忽略,则会隐式应用JVM的当前默认时区。 This default can change at any moment during runtime. 此默认值可运行时期间随时更改。 So better to be explicit. 所以要明确一点。

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

I strongly suggest you stick with the java.time classes. 我强烈建议你坚持使用java.time类。 But if you absolutely need the old legacy classes, such as for interfacing with old code not yet updated to java.time, then you may convert. 但是如果你绝对需要旧的遗留类,比如用于与尚未更新到java.time的旧代码接口,那么你可以转换。 Look to new methods added to the old classes. 查看添加到旧类的新方法。

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

Month indexing 月份索引

The Question asks for how to generate a String with the month number as an zero-based index 0-11 for January to December, to match how GregorianCalendar works internally. 该问题询问如何生成一个字符串,其中月份编号为1到12月的从零开始的索引0-11,以匹配GregorianCalendar在内部的工作方式。

Frankly, answering that would be a disservice. 坦率地说,回答这将是一种伤害。 Numbering months with a zero-based number is crazy nuts insane. 以零为基础的数字编号是疯狂疯狂的疯狂。 Doing so would cause no end of confusion. 这样做会导致混乱。 Doing so in GregorianCalendar was an extremely poor design choice to begin with. 在GregorianCalendar中这样做是一个非常糟糕的设计选择。 It's use should be extinguished rather than promoted. 它的使用应该被熄灭而不是提升。


About java.time 关于java.time

The java.time framework is built into Java 8 and later. java.time框架内置于Java 8及更高版本中。 These classes supplant the troublesome old legacy date-time classes such as java.util.Date , .Calendar , & java.text.SimpleDateFormat . 这些类取代了麻烦的旧遗留日期时间类,如java.util.Date.Calendarjava.text.SimpleDateFormat

The Joda-Time project, now in maintenance mode , advises migration to java.time. 现在处于维护模式Joda-Time项目建议迁移到java.time。

To learn more, see the Oracle Tutorial . 要了解更多信息,请参阅Oracle教程 And search Stack Overflow for many examples and explanations. 并搜索Stack Overflow以获取许多示例和解释。 Specification is JSR 310 . 规范是JSR 310

Where to obtain the java.time classes? 从哪里获取java.time类?

The ThreeTen-Extra project extends java.time with additional classes. ThreeTen-Extra项目使用其他类扩展了java.time。 This project is a proving ground for possible future additions to java.time. 该项目是未来可能添加到java.time的试验场。 You may find some useful classes here such as Interval , YearWeek , YearQuarter , and more . 您可以在这里找到一些有用的类,比如IntervalYearWeekYearQuarter ,和更多

If i understand the question right we are mixing 2 things 如果我理解正确的问题,我们会混合两件事

a) Internal representation of the months within Calender / GregorianCalender and the actual Calendar itself. a)Calender / GregorianCalender中月份的内部表示和实际的日历本身。

The internal representation as you rightly say is represented from 0-11 denoting 12 months of the year , the human interpretation of that is 1-12 months of the year. 你正确地说的内部表示代表0-11表示一年中的12个月,人类对此的解释是一年中的1-12个月。 When you call the format operation you get the way the date appears on a actual human calender which is October , month 10 of the year. 当您调用格式化操作时,您将获得日期显示在实际人类日历上的方式,即10月,10月中的日期。 The internal representation is still 9. If you ask how , you can check using the API 内部表示仍然是9.如果您问如何,您可以使用API​​进行检查

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

This prints the numeral 9 这打印数字9

If you want the internal representation of the date , you can do so too. 如果您想要日期的内部表示,您也可以这样做。 A really hacky way would be as follows although i do not vouch for it , but gives you an overall idea of things. 一个真正的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));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM