18

Итак, я пытаюсь сделать это (должно быть) простым упражнением, чтобы программа превратила строку даты в объект GregorianCalendar, отформатировала ее и снова вернула в качестве строки, когда это будет сделано ,Использование GregorianCalendar с SimpleDateFormat

Это последняя небольшая часть программы, которая извлекает патч из файла, разбивает его на отдельные записи, а затем разбивает записи на отдельные части данных и присваивает их объекту-человеку.

Я проверил код в нескольких местах, и код выполняет именно то, что он должен делать до тех пор, пока я не вызову функцию формата, которая вызывает исключение 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 = America/Vancouver, смещение = - 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 = ?, Д ST_OFFSET =?]

Значения year, month и day_of_month являются правильными, поскольку они являются номерами, которые я передал в его создание.

Мысли, предложения, я даже близко?

редактировать

оригинальных вопросы прояснились (спасибо assylias!), Но я до сих пор не могу печатать правильно, потому что эти две функции не связаны между собой и требование должны иметь значение даты 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; 
    } 

} 

последнее редактирование

Ok так что кажется, что я идиотка и не нужно, чтобы связать эти две функции DateUtil вместе, но и использовать их в тандеме , Сначала преобразуйте дату рождения в GregorianCalendar и сохраните его в объекте person.Затем в заявлении на печать просто скажите программе, чтобы форматировать эту дату, когда она печатается. Проблема решена. Все работает в соответствии со спецификациями сейчас, и я чувствую, что много глупостей, потому что в последний день или около того с классом DateUtil я рычал как рыба из воды, пытаясь заставить их работать одновременно.

Благодарим за помощь в получении правильной даты!

+0

FYI, чтобы форматировать код в StackOverflow, запустите строку с 4 (или более) пробелами. Используйте '>' только для кодов без кода. – assylias

+0

ah хорошо знать, thanks = P – RejectionHurts

ответ

44

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; 
+3

Возможно, вы также захотите * установить * календарь в 'SimpleDateFormat', чтобы он знал, что он использует это, а не другую систему календаря. –

+0

@JonSkeet Я отредактировал - спасибо. – assylias

+0

lol Я думал, что есть что-то на сегодняшний день, но я обманывал его некоторое время и не мог заставить его работать, поэтому я отказался от него = P Я отчитаюсь в нескольких – RejectionHurts

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; 
} 
+0

Требование о том, что должны быть эти 2 функции =/ничего не бывает просто lol – RejectionHurts

+1

Ну вы можете разделить это на 2 ** методы ** (не функции), если хотите :) – m0skit0

+0

линия о возвращаемом заявлении дает ошибку «не может конвертировать из void в GregorianCalendar» – RejectionHurts

2

SimpleDateFormat, как следует из названия, форматов Даты. Не календарь. Так что если вы хотите отформатировать GregorianCalendar с помощью SimpleDateFormat, вы должны преобразовать календарь на дату первого:

dateFormat.format(calendar.getTime()); 

И что вы видите печататься это ToString() представление календаря. Предполагаемое использование - отладка. Он не предназначен для отображения даты в графическом интерфейсе. Для этого используйте (Simple) DateFormat.

Наконец, чтобы преобразовать из строки в дату, вы также должны использовать (простой) DateFormat (его метод parse()), а не разделять строку так, как вы делаете. Это даст вам объект Date, и вы можете создать календарь из Даты, установив его (Calendar.getInstance()) и установив свое время (calendar.setTime()).

Мой совет: Googling - это не решение. Чтение API documentation - это то, что вам нужно сделать.

1
  1. Вы размещаете там двухзначный год. Первый век. И грегорианский календарь начался в 16 веке. Я думаю, вы должны добавить 2000 в год.

  2. Месяц в функции new GregorianCalendar (год, месяц, дни) основан на 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(Date date) 

и внести соответствующие изменения. fmt.format() с радостью возьмет объект Date.

  1. Всегда после возникновения неожиданного исключения, поймайте его самостоятельно, не позволяйте машине java делать это. Таким образом, вы поймете проблему.
+0

К сожалению, я не могу сделать последнее изменение, которое вы предложили, поскольку оно утверждает, что это функции, которые они могут использовать, не могут их изменить =/я исправил -1, полностью забыл, что год не проблема, кажется, и тело моей функции формата работает правильно, теперь, когда были реализованы изменения аллилия. = P я добавил оператор печати в функцию формата только для просмотра, и они распечатываются в соответствии с требованиями упражнения. плохо обновить приведенный выше код – RejectionHurts

+0

Год - проблема - в первом веке AC не было никакого gregorian календаря. Правильная функция проверяет вход для даты, после того, как был установлен первый график gregorian. – Gangnus

+0

Конечно, вы можете сделать перевод GregorianCalendar.getTime() внутри этой функции. Например, fmt.format (date.getTime()). Но также очень плохо назвать переменную GregorianCalendar переменной Date. Имена должны сидеть со своими типами. – Gangnus

1

Т.Л., д-р

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

Избегай унаследованное даты и время занятия

на вопрос и другие ответы уже устарело, используя проблемные старые классы даты и время, которые в настоящее время наследие, вытесняется java.time.

Использование java.time

Вы, кажется, иметь дело с даты только значения. Поэтому не используйте класс даты и времени. Вместо этого используйте LocalDate. Класс LocalDate представляет значение даты только без времени и без часового пояса.

Укажите Locale, чтобы определить (а) человеческий язык для перевода имени дня, названия месяца и т. Д. И (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.

вход: 23-Mar-2017

ld.toString(): 2017-03-23 ​​

выход: 23-Mar-2017


О java.time

Рамка 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. *.

Где получить классы 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
    • Более поздние версии Android реализаций пачке классов java.time.
    • Для более ранних Android, проект ThreeTenABP адаптирует ThreeTen-Backport (упомянутый выше). См. How to use ThreeTenABP….

ThreeTen-Extra Проект расширяет java.time с дополнительными классами. Этот проект является доказательством возможных будущих дополнений к java.time. Здесь вы можете найти полезные классы, такие как Interval, YearWeek, YearQuarter и more.

Смежные вопросы