Использование GregorianCalendar с SimpleDateFormat
Итак, я ломал голову над этим (должно быть) простым упражнением, чтобы заставить программу превратить строку даты в объект GregorianCalendar
, отформатировать и вернуть ее снова в виде строки, когда это будет сделано.
Это последняя небольшая часть программы, которая берет фрагмент текста из файла, разбивает его на отдельные записи, затем разбивает записи на отдельные фрагменты данных и назначает их объекту person.
Я проверил код в нескольких местах, и код делает именно то, что должен был делать до тех пор, пока я не вызову функцию форматирования, которая вызывает IllegalArgumentException
. GergorianCalendar
назначают значения, которые он должен назначить (хотя печать это, опять же, совсем другая история, как показано ниже...), но формат не будет принимать объект для форматирования.
К сожалению, инструктор не был слишком уверен в том, как использовать GregorianCalendar
и SimpleDateFormat
(но нам поручили работать с ними), и сказал: "Просто Google это…" Я пытался, и ничего, что я нашел, не помогло.
Код, который у меня пока есть:
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, = startDay 8, startDayOfWeek = 1, начальный промежуток = 7200000, startTimeMode = 0, endMode = 3, endMonth = 10, endDay = 1, endDayOfWeek = 1, EndTime = 7200000, endTimeMode = 0]], firstDayOfWeek = 1, minimalDaysInFirstWeek = 1, ЭРА =?, ГОД = 1985, МЕСЯЦ = 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, ЧАС = 0, HOUR_OF_DAY = 0, МИНУТНЫЙ = 0, ВТОРОЙ = 0, миллисекунду =?, ZONE_OFFSET =?, DST_OFFSET =?]
Значения year, month и day_of_month являются правильными, поскольку они являются числами, которые я передал при его создании.
Мысли, предложения, я даже близко?
редактировать
Исходные проблемы устранены (спасибо, ассилиас!), Но я все еще не могу печатать должным образом, потому что две функции не связаны, и необходимо, чтобы значение даты GregorianCalendar
распечатано из объекта person (поскольку дата рождения - это 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. Затем в заявлении на печать просто скажите программе отформатировать эту дату в том виде, в котором она печатается. Проблема была решена. Теперь все работает в соответствии со спецификациями, и я чувствую себя намного глупее, потому что в последний день или около того с классом DateUtil
я бился, как рыба, из воды, пытаясь заставить их работать одновременно.
Спасибо всем за помощь в получении даты, чтобы войти правильно!
Ответы
Ответ 1
Метод 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;
Ответ 2
Почему такие осложнения?
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;
}
Ответ 3
SimpleDateFormat
, как указывает его имя, форматирует Date
s. Не Calendar
. Итак, если вы хотите отформатировать GregorianCalendar
с использованием SimpleDateFormat
, вы должны сначала преобразовать Calendar
в Date
:
dateFormat.format(calendar.getTime());
И то, что вы видите напечатанным, является представлением календаря toString()
. Предполагаемое использование - отладка. Он не предназначен для отображения даты в графическом интерфейсе. Для этого используйте (Simple
) DateFormat
.
Наконец, чтобы преобразовать String
в Date
, вы должны также использовать (Simple
) DateFormat
(его метод parse()
), а не разбивать String
как вы это делаете. Это даст вам объект Date
, и вы можете создать Calendar
из Date
, создав его экземпляр (Calendar.getInstance()
) и установив его время (calendar.setTime()
).
Мой совет: поиск в Google не является решением проблемы. Чтение документации по API - это то, что вам нужно сделать.
Ответ 4
-
Вы помещаете туда двухзначный год. Первый век И григорианский календарь начался в 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 делать это. Таким образом, вы поймете проблему.
Ответ 5
ТЛ; др
LocalDate.parse(
"23-Mar-2017" ,
DateTimeFormatter.ofPattern( "dd-MMM-uuuu" , Locale.US )
)
Избегайте устаревших классов времени
Вопрос и другие ответы теперь устарели, используя неприятные старые классы времени, которые теперь являются устаревшими, вытесняются классами java.time.
Использование java.time
Кажется, вы имеете дело только с датами. Поэтому не используйте класс даты и времени. Вместо этого используйте LocalDate
. Класс LocalDate
представляет значение даты только без времени и без часового пояса.
Укажите Locale
чтобы определить (а) человеческий язык для перевода имени дня, названия месяца и т.д. И (б) культурных норм, определяющих вопросы сокращения, капитализации, пунктуации, разделителей и т.д.
Разбор строки.
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.
вход: 23-Мар-2017
ld.toString(): 2017-03-23
выпуск: 23-Мар-2017
О java.time
Рамка java.time встроена в Java 8 и более поздние версии. Эти классы вытесняют неприятные старые устаревшие классы времени, такие как java.util.Date
, Calendar
и SimpleDateFormat
.
Проект Joda-Time, теперь в режиме обслуживания, советует перейти на классы java.time.
Чтобы узнать больше, ознакомьтесь с учебным пособием Oracle. И поиск Qaru для многих примеров и объяснений. Спецификация - JSR 310.
Используя JDBC-драйвер, совместимый с JDBC 4.2 или более поздней версией, вы можете обменивать объекты java.time непосредственно с вашей базой данных. Нет необходимости в строках или классах java.sql. *.
Где можно получить классы java.time?
- Java SE 8, Java SE 9 и более поздние версии
- Встроенный.
- Часть стандартного Java API с интегрированной реализацией.
- Java 9 добавляет некоторые незначительные функции и исправления.
- Java SE 6 и Java SE 7
- Большая часть функциональных возможностей java.time включена обратно в Java 6 и 7 в ThreeTen-Backport.
- Android
Проект ThreeTen-Extra расширяет java.time с дополнительными классами. Этот проект является доказательством возможных будущих дополнений к java.time. Здесь вы можете найти полезные классы, такие как Interval
, YearWeek
, YearQuarter
и другие.