将 GregorianCalendar 与 SimpleDateFormat 结合使用



所以,我一直在绞尽脑汁地做这个(应该的)简单的练习,让程序将日期字符串变成GregorianCalendar对象,格式化它,并在完成后再次将其作为字符串返回。

这是程序的最后一部分,它从文件中获取大量文本,将其分解为单独的记录,然后将记录分解为单独的数据片段并将它们分配给 person 对象。

我已经在多个地方检查了代码,代码完全按照它应该做的事情,直到我调用格式函数,它会抛出一个IllegalArgumentExceptionGergorianCalendar对象被分配了它应该被分配的值(尽管打印它又是一个完全不同的故事,如下所示......),但格式将不接受对象进行格式化。

不幸的是,讲师不太确定如何使用GregorianCalendarSimpleDateFormat(但分配我们与他们一起工作),并说:"只是谷歌它......"我试过了,我发现什么也没帮助。

到目前为止,我的代码是:

public class DateUtil {
    public static GregorianCalendar convertFromDMY(String dd_mm_yy) throws ParseException{
        // this actually works, got rid of the original code idea
        String[] splitDate = dd_mm_yy.split("-");
        int days = Integer.parseInt(splitDate[0]);
        int month = Integer.parseInt(splitDate[1]);
        int year = Integer.parseInt(splitDate[2]);
        // Dates are going in right, checked in print statement,
        // but the object is not getting formatted…
        GregorianCalendar dateConverted = new GregorianCalendar(year, month, days);
        format(dateConverted);
        return dateConverted;
    }
    public static String format(GregorianCalendar date){
        SimpleDateFormat fmt = new SimpleDateFormat("dd-MMM-yyyy");
        String dateFormatted = fmt.format(date);
        return dateFormatted;
    }
}

我得到的错误是:

线程"main"中的异常 java.lang.IllegalArgumentException: 无法格式化给定的对象>作为日期    at java.text.DateFormat.format(DateFormat.java:281)    at java.text.Format.format(Format.java:140)    在实验室2。DateUtil.format(DateUtil.java:26)    在实验室2。DateUtil.convertFromDMY(DateUtil.java:19)    在实验室2。实验室2.创建学生(实验室2.java:75)    在实验室2。Lab2.main(Lab2.java:34)

还有一件事,我什至使用GregorianCalendar对吗?当我打印出该对象的值时(应该得到一个日期,对吧?我明白这个:

java.util.GregorianCalendar[time=?,areFieldsSet=false,areAllFieldsSet=false,lenient=true,zone=sun.util.calendar.ZoneInfo[id="America/Vancouver",offset=-28800000,dstSavings =3600000,useDaylight=true,

transitions=189,lastRule=java.util.SimpleTimeZone[id=America/Vancouver,offset=-28800000,dstSavings = 3600000,useDaylight=true,startYear=0,startMode=3,startMonth=2,startDay=8,startDayOfWeek=1,startTime=7200000,startTimeMode=0,endMode=3,endMonth=10,endDay=1,endDayOfWeek=1,endTime=7200000,endTimeMode=0]],firstDayOfWeek=1,最小天数InFirstWeek=1,ERA=?,YEAR=1985,MONTH=4,WEEK_OF_YEAR

=?,WEEK_OF_MONTH=?,DAY_OF_MONTH=22,DAY_OF_YEAR=?,DAY_OF_WEEK=?,DAY_OF_WEEK_IN_MONTH=?,AM_PM=0,HOUR=0,HOUR_OF_DAY=0,MINUTE=0,秒=0,毫秒=?,ZONE_OFFSET=?,DST_OFFSET=?]

年、月和day_of_month值都是正确的,因为它们是我在创建它时传递的数字。

想法,建议,我什至接近吗?

编辑

原始问题已清除(谢谢 assylias!),但我仍然无法正确打印,因为这两个函数没有链接,并且要求是从 person 对象打印出GregorianCalendar日期值(因为出生日期是一个GregorianCalendar)。

更新的代码:

public class DateUtil {
    static SimpleDateFormat fmt = new SimpleDateFormat("dd-MMM-yyyy");
    public static GregorianCalendar convertFromDMY(String dd_mm_yy) throws ParseException{
        // this actually works, got rid of the original code idea
        String[] splitDate = dd_mm_yy.split("-");
        int days = Integer.parseInt(splitDate[0]);
        int month = (Integer.parseInt(splitDate[1]) - 1);
        int year = Integer.parseInt(splitDate[2]);
        // dates go in properly
        GregorianCalendar dateConverted = new GregorianCalendar(year, month, days);
        String finalDate = format(dateConverted);
        return ;
    }
    public static String format(GregorianCalendar date) throws ParseException{
       fmt.setCalendar(date);
        String dateFormatted = fmt.format(date.getTime());
        System.out.println(dateFormatted);
        return dateFormatted;
    }
}

上次编辑

好吧,看来我是个白痴,不需要将两个DateUtil函数链接在一起,而是同时使用它们。首先,将出生日期转换为GregorianCalendar并将其存储在 person 对象中。然后,在 print 语句中,只需告诉程序在打印时设置该日期的格式即可。问题解决了。现在一切都按照规范工作,我觉得自己更愚蠢了,因为我在DateUtil班的最后一天左右像鱼一样离开了水,试图让他们同时工作。

感谢您对正确约会的帮助!

SimpleDateFormat.format()方法将Date作为参数。您可以通过调用Calendar getTime()方法从Date获取

public static String format(GregorianCalendar calendar) {
    SimpleDateFormat fmt = new SimpleDateFormat("dd-MMM-yyyy");
    fmt.setCalendar(calendar);
    String dateFormatted = fmt.format(calendar.getTime());
    return dateFormatted;
}

另请注意,月份从 0 开始,因此您可能意味着:

int month = Integer.parseInt(splitDate[1]) - 1;

为什么会出现这样的并发症?

public static GregorianCalendar convertFromDMY(String dd_mm_yy) throws ParseException 
{
    SimpleDateFormat fmt = new SimpleDateFormat("dd-MMM-yyyy");
    Date date = fmt.parse(dd_mm_yy);
    GregorianCalendar cal = GregorianCalendar.getInstance();
    cal.setTime(date);
    return cal;
}

SimpleDateFormat ,顾名思义,格式Date s。不是Calendar.因此,如果要使用 SimpleDateFormat 格式化GregorianCalendar ,必须先将Calendar转换为Date

dateFormat.format(calendar.getTime());

你看到打印的是日历的toString()表示形式。它的预期用途是调试。它不用于在 GUI 中显示日期。为此,请使用 ( SimpleDateFormat

最后,要从String转换为Date,您还应该使用(SimpleDateFormat(其parse()方法),而不是像现在这样拆分String。这将为您提供一个Date对象,您可以通过实例化(Calendar.getInstance())并设置其时间(calendar.setTime())从Date创建Calendar

我的建议是:谷歌搜索不是这里的解决方案。阅读 API 文档是您需要做的。

tl;dr

LocalDate.parse(
    "23-Mar-2017" ,
    DateTimeFormatter.ofPattern( "dd-MMM-uuuu" , Locale.US ) 
)

避免使用传统的日期时间课程

问题和其他答案现在已经过时了,使用麻烦的旧日期时间类,这些类现在是遗留的,被java.time类所取代。

使用 java.time

您似乎正在处理仅日期的值。因此,请勿使用日期时间类。而是使用 LocalDate .LocalDate 类表示没有时间且没有时区的仅日期值。

指定一个Locale来确定 (a) 用于翻译日期名称、月份名称等的人类语言,以及 (b) 决定缩写、大写、标点符号、分隔符等问题的文化规范。

解析字符串。

String input = "23-Mar-2017" ;
DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd-MMM-uuuu" , Locale.US ) ;
LocalDate ld = LocalDate.parse( input , f );

生成一个字符串。

String output = ld.format( f );

如果为您提供的是年、月和月几的数字而不是文本,请使用 LocalDate.of

LocalDate ld = LocalDate.of( 2017 , 3 , 23 );  // ( year , month 1-12 , day-of-month )

查看此代码在 IdeOne.com 实时运行。

输入:2017 年 3 月 23 日

ld.toString(): 2017-03-23

输出:2017 年 3 月 23 日


关于 java.time

java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧传统日期时间类,如java.util.DateCalendarSimpleDateFormat

Joda-Time 项目现在处于维护模式,建议迁移到 java.time 类。

要了解更多信息,请参阅 Oracle 教程。并搜索堆栈溢出以获取许多示例和解释。规范为 JSR 310。

使用符合 JDBC 4.2 或更高版本的 JDBC 驱动程序,您可以直接与数据库交换 java.time 对象。不需要字符串或java.sql.*类。

从哪里获得java.time类?

    Java SE
  • 8Java SE 9 及更高版本
    • 内置。
    • 具有捆绑实现的标准 Java API 的一部分。
    • Java 9添加了一些小功能和修复。
  • Java SE
  • 6Java SE 7
    • 许多java.time功能在ThreeTen-Backport中向后移植到Java 6和7。
  • 人造人
    • java.time 类的 Android 捆绑包实现的更高版本。
    • 对于早期的Android,ThreeTenABP项目适应了ThreeTen-Backport(如上所述)。请参阅如何使用ThreeTenABP...

ThreeTen-Extra项目通过额外的类扩展了java.time。这个项目是未来可能添加到java.time的试验场。你可以在这里找到一些有用的类,如IntervalYearWeekYearQuarter等。

  1. 你把一个两位数的年份放在那里。第一世纪。公历始于 16 世纪。我认为你应该把2000年加到这一年。

  2. 函数中的月份new GregorianCalendar(year, month, days)从 0 开始。从那里的月份减去 1。

  3. 更改第二个函数的主体,如下所示:

        String dateFormatted = null;
        SimpleDateFormat fmt = new SimpleDateFormat("dd-MMM-yyyy");
        try {
            dateFormatted = fmt.format(date);
        }
        catch ( IllegalArgumentException e){
            System.out.println(e.getMessage());
        }
        return dateFormatted;
    

调试后,您会发现简单的GregorianCalendar不能是fmt.format();的参数。

真的,没有人需要GregorianCalendar作为输出,即使你被告知返回"一个字符串"。

将格式函数的标头更改为

public static String format(final Date date) 

并进行适当的更改。 fmt.format()会很乐意接受Date对象。

  1. 总是在出现意外异常后,自己抓住它,不要让Java机器这样做。这样,您就会了解问题所在。

相关内容

  • 没有找到相关文章

最新更新