所以,我一直在绞尽脑汁地做这个(应该的)简单的练习,让程序将日期字符串变成GregorianCalendar
对象,格式化它,并在完成后再次将其作为字符串返回。
这是程序的最后一部分,它从文件中获取大量文本,将其分解为单独的记录,然后将记录分解为单独的数据片段并将它们分配给 person 对象。
我已经在多个地方检查了代码,代码完全按照它应该做的事情,直到我调用格式函数,它会抛出一个IllegalArgumentException
。GergorianCalendar
对象被分配了它应该被分配的值(尽管打印它又是一个完全不同的故事,如下所示......),但格式将不接受对象进行格式化。
不幸的是,讲师不太确定如何使用GregorianCalendar
和SimpleDateFormat
(但分配我们与他们一起工作),并说:"只是谷歌它......"我试过了,我发现什么也没帮助。
到目前为止,我的代码是:
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 中显示日期。为此,请使用 ( Simple
) DateFormat
。
最后,要从String
转换为Date
,您还应该使用(Simple
)DateFormat
(其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.Date
、Calendar
和SimpleDateFormat
。
Joda-Time 项目现在处于维护模式,建议迁移到 java.time 类。
要了解更多信息,请参阅 Oracle 教程。并搜索堆栈溢出以获取许多示例和解释。规范为 JSR 310。
使用符合 JDBC 4.2 或更高版本的 JDBC 驱动程序,您可以直接与数据库交换 java.time 对象。不需要字符串或java.sql.*类。
从哪里获得java.time类?
- Java SE
- 8、Java SE 9 及更高版本
- 内置。
- 具有捆绑实现的标准 Java API 的一部分。
- Java 9添加了一些小功能和修复。
Java SE - 6 和 Java SE 7
- 许多java.time功能在ThreeTen-Backport中向后移植到Java 6和7。
- 人造人
- java.time 类的 Android 捆绑包实现的更高版本。
- 对于早期的Android,ThreeTenABP项目适应了ThreeTen-Backport(如上所述)。请参阅如何使用ThreeTenABP...。
ThreeTen-Extra项目通过额外的类扩展了java.time。这个项目是未来可能添加到java.time的试验场。你可以在这里找到一些有用的类,如Interval
、YearWeek
、YearQuarter
等。
-
你把一个两位数的年份放在那里。第一世纪。公历始于 16 世纪。我认为你应该把2000年加到这一年。
-
函数中的月份
new GregorianCalendar(year, month, days)
从 0 开始。从那里的月份减去 1。 -
更改第二个函数的主体,如下所示:
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
对象。
- 总是在出现意外异常后,自己抓住它,不要让Java机器这样做。这样,您就会了解问题所在。