所以我一直在讨论这个(应该是)简单的练习,让程序将日期字符串转换为GregorianCalendar对象,格式化它,并在完成时将其作为字符串再次返回。
这是一个程序的最后一点,它从文件中获取文本,将其分解为单个记录,然后将记录分成单独的数据并将它们分配给一个人对象。
我已经在多个地方检查了代码,并且代码完全按照它应该执行的操作,直到我调用format函数,这会抛出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;
}
}
我得到的错误是:
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中[时间= ?, areFieldsSet =假,areAllFieldsSet =假,宽大=真,区= sun.util.calendar.ZoneInfo [ID = “美国/温哥华”,偏移= -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 =?]
年,月和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函数链接在一起,而是串联使用它们。首先,将birthdate转换为GregorianCalendar并将其存储在person对象中。然后在print语句中只需告诉程序在打印日期时格式化该日期。问题解决了。现在所有的工作都按照规格进行了,我觉得这很愚蠢,因为在最后一天左右,我在DateUtil课程中像鱼一样甩水,试图让它们同时工作。
感谢所有关于正确使用日期的帮助!
答案 0 :(得分:48)
SimpleDateFormat#format
方法将Date
作为参数。您可以通过调用Date
方法从Calendar
获得getTime
:
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;
答案 1 :(得分:4)
为什么会出现这种并发症?
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;
}
答案 2 :(得分:2)
SimpleDateFormat,如其名称所示,格式化日期。不是日历。因此,如果您想使用SimpleDateFormat格式化GregorianCalendar,您必须先将日历转换为日期:
dateFormat.format(calendar.getTime());
您看到的内容是日历的toString()表示。它的用途是调试。它不用于在GUI中显示日期。为此,使用(简单)DateFormat。
最后,要从String转换为Date,您还应该使用(Simple)DateFormat(它的parse()
方法),而不是像您一样拆分String。这将为您提供一个Date对象,您可以通过实例化Calendar.getInstance()
)并设置其时间(calendar.setTime()
)从日期创建日历。
我的建议是:谷歌搜索不是解决方案。阅读API documentation是您需要做的事情。
答案 3 :(得分:1)
你的年份是两位数。第一世纪。格里高利历从16世纪开始。我想,你应该在今年增加2000个。
新功能GregorianCalendar(年,月,日)中的月份为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(Date date)
并进行适当的更改。 fmt.format()
很乐意接受Date对象。
答案 4 :(得分:1)
LocalDate.parse(
"23-Mar-2017" ,
DateTimeFormatter.ofPattern( "dd-MMM-uuuu" , Locale.US )
)
问题和其他答案现在已经过时了,使用现在遗留下来的麻烦的旧日期时间类,取而代之的是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 )
请参阅此code run live at IdeOne.com。
输入:2017年3月23日
ld.toString():2017-03-23
输出:2017年3月23日
java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.Date
,Calendar
和& SimpleDateFormat
现在位于Joda-Time的maintenance mode项目建议迁移到java.time类。
要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310。
使用符合JDBC driver或更高版本的JDBC 4.2,您可以直接与数据库交换 java.time 对象。不需要字符串也不需要java.sql。* classes。
从哪里获取java.time类?
ThreeTen-Extra项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如Interval
,YearWeek
,YearQuarter
和more。