因此,我一直在思考这个(应该是)简单的练习,让程序将日期字符串转换为GregorianCalendar对象,格式化它,并在完成时将其作为字符串再次返回 .
这是一个程序的最后一点,它从文件中获取文本,将其分解为单个记录,然后将记录分成单独的数据并将它们分配给一个人对象 .
我已经在多个地方检查了代码,代码完全按照它应该执行的操作,直到我调用格式函数,这会抛出IllegalArgumentException . GergorianCalendar对象被赋予它应该被分配的值(虽然打印它是另一个故事,如下所示......),但格式不接受格式化的对象 .
不幸的是,导师不太确定如何使用GregorianCalendar和SimpleDateFormat(但指派我们使用它们)并且说“Just Google it”......我试过,我发现没有任何帮助 .
我到目前为止的代码是:
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;
}
}
我得到的错误是:
Exception in thread "main" java.lang.IllegalArgumentException: Cannot format given Object >as a Date
at java.text.DateFormat.format(DateFormat.java:281)
at java.text.Format.format(Format.java:140)
at lab2.DateUtil.format(DateUtil.java:26)
at lab2.DateUtil.convertFromDMY(DateUtil.java:19)
at lab2.Lab2.createStudent(Lab2.java:75)
at lab2.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 =真,过渡= 189,lastRule = java.util.SimpleTimeZone中[ID =美国/温哥华,偏移= -28800000,dstSavings = 3600000,useDaylight =真,startYear = 0,STARTMODE = 3,startMonth = 2,朝九特派= 8 ,startDayOfWeek = 1,开始时间= 7200000,startTimeMode = 0,endMode = 3,endMonth = 10,endday指定= 1,一个endDayOfWeek = 1,结束时间= 7200000,endTimeMode = 0]],Firstdayofweek可= 1,minimalDaysInFirstWeek = 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,SECOND = 0,微差= ?, ZONE_OFFSET = ?, DST_OFFSET =?]
year,month和day_of_month值都是正确的,因为它们是我传递给它的数字 .
思考,建议,我甚至关闭?
edit
原始问题得到澄清(谢谢assylias!)但我仍然无法正确打印,因为这两个函数没有链接,并且要求是从person对象打印出GregorianCalendar日期值(因为birthdate是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;
}
}
last edit
好吧,好像我是个白痴,并且不需要将两个DateUtil函数链接在一起,但是串联使用它们 . 首先,将birthdate转换为GregorianCalendar并将其存储在person对象中 . 然后在print语句中只需告诉程序在打印日期时格式化该日期 . 问题解决了 . 现在所有的工作都按照规格进行,我感觉很愚蠢,因为我在最后一天左右用水甩掉了鱼,用DateUtil类,试图让它们同时工作 .
感谢所有关于正确使用日期的帮助!
5 回答
SimpleDateFormat#format
方法将Date
作为参数 . 您可以通过调用getTime
方法从Calendar
获取Date
:另请注意,月份从0开始,因此您可能意味着:
为什么会出现这样
正如其名称所示,SimpleDateFormat格式化日期 . 不是日历 . 因此,如果要使用SimpleDateFormat格式化GregorianCalendar,则必须先将日历转换为日期:
而你看到的是日历的toString()表示 . 它的用途是调试 . 它不是用于在GUI中显示日期 . 为此,使用(简单)DateFormat .
最后,要从String转换为Date,您还应该使用(Simple)DateFormat(它的
parse()
方法),而不是像您一样拆分String . 这将为您提供Date对象,您可以通过实例化(Calendar.getInstance()
)并设置其时间(calendar.setTime()
)从日期创建日历 .我的建议是:谷歌搜索不是这里的解决方案 . 阅读API documentation是你需要做的 .
你的年份是两位数 . 第一世纪 . 格里高利历始于16世纪 . 我想,你应该在今年增加2000 .
函数new GregorianCalendar中的月份(年,月,日)是从0开始的 . 从那里的月份减去1 .
更改第二个函数的主体,以便:
调试后你会发现简单的GregorianCalendar不能是fmt.format()的参数;
真的,没有人需要GregorianCalendar作为输出,即使你被告知返回“一个字符串” .
将格式化函数的 Headers 更改为
并做出适当的改变 .
fmt.format()
将很乐意接受Date对象 .tl;博士
避免遗留日期时间类
问题和其他答案现在已经过时,使用了现在遗留下来的麻烦的旧日期时间类,取而代之的是java.time类 .
使用java.time
您似乎正在处理仅限日期的值 . 所以不要使用日期时间类 . 而是使用
LocalDate
. LocalDate类表示没有时间且没有时区的仅日期值 .指定Locale以确定(a)用于翻译日期名称,月份名称等的人类语言,以及(b)决定缩写,大小写,标点符号,分隔符等问题的文化规范 .
解析一个字符串 .
生成一个字符串 .
如果您为年,月和日提供了数字而不是文本,请使用
LocalDate.of
.见code run live at IdeOne.com .
关于java.time
java.time框架内置于Java 8及更高版本中 . 这些类取代了麻烦的旧legacy日期时间类,例如java.util.Date,Calendar和SimpleDateFormat .
现在位于maintenance mode的Joda-Time项目建议迁移到java.time类 .
要了解更多信息,请参阅Oracle Tutorial . 并搜索Stack Overflow以获取许多示例和解释 . 规格是JSR 310 .
使用与JDBC 4.2或更高版本兼容的JDBC driver,您可以直接与数据库交换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 .
Android
更新版本的Android捆绑java.time类的实现 .
对于早期的Android,ThreeTenABP项目适应ThreeTen-Backport(如上所述) . 见How to use ThreeTenABP… .
ThreeTen-Extra项目使用其他类扩展java.time . 该项目是未来可能添加到java.time的试验场 . 您可以在这里找到一些有用的类,例如Interval,YearWeek,YearQuarter和more .