Перетворити рядок в об’єкт календаря на Java


174

Я новачок у Java, зазвичай працюю з PHP.

Я намагаюся перетворити цей рядок:

Пн. 14 березня 16:02:37 GMT 2011

У об’єкт календаря, щоб я міг легко тягнути такий рік і місяць:

String yearAndMonth = cal.get(Calendar.YEAR)+cal.get(Calendar.MONTH);

Було б поганою ідеєю розібрати його вручну? Використовуєте метод підрядки?

Будь-яка порада допоможе подякувати!


Відповіді:


396
Calendar cal = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy", Locale.ENGLISH);
cal.setTime(sdf.parse("Mon Mar 14 16:02:37 GMT 2011"));// all done

Примітка: встановлюється Localeвідповідно до вашого оточення / вимог


Дивитися також


onlineconversion.com/unix_time.htm . Це онлайн-конвертер часових позначок. Значення, яке обчислюється кодом java, і це онлайн-перетворення отримує різницю. Чому ?? Ви можете пройти через це. Дякую :)
Sachin J

6
Зауважте, що це втрачає інформацію про часовий пояс. Об'єкт Calendar матиме системний TimeZone за замовчуванням, не розібраний.
Крістіан Врабі

Це вже не повинно бути головною / прийнятою відповіддю. Оскільки Java 8 вже працює понад 4 роки, відповідь слід оновити java.time. Цей Q / A з’являється досить помітним в Google.
Сколітус

18

тл; д-р

Сучасний підхід використовує класи java.time .

YearMonth.from(
    ZonedDateTime.parse( 
        "Mon Mar 14 16:02:37 GMT 2011" , 
        DateTimeFormatter.ofPattern( "E MMM d HH:mm:ss z uuuu" )
     )
).toString()

2011-03

Уникайте застарілих занять з датами

Сучасний спосіб - з класами java.time. Такі старі класи, як-от Calendar, виявились погано розробленими, заплутаними та клопітливими.

Визначте спеціальний формат, який відповідає вашому рядковому вводу.

String input = "Mon Mar 14 16:02:37 GMT 2011";
DateTimeFormatter f = DateTimeFormatter.ofPattern( "E MMM d HH:mm:ss z uuuu" );

Розбираємо як ZonedDateTime.

ZonedDateTime zdt = ZonedDateTime.parse( input , f );

Вас цікавлять рік та місяць. Класи java.time включають YearMonthклас для цієї мети.

YearMonth ym = YearMonth.from( zdt );

Ви можете допитати номери року та місяця за потреби.

int year = ym.getYear();
int month = ym.getMonthValue();

Але toStringметод генерує рядок у стандартному форматі ISO 8601 .

String output = ym.toString();

Зберіть це все разом.

String input = "Mon Mar 14 16:02:37 GMT 2011";
DateTimeFormatter f = DateTimeFormatter.ofPattern( "E MMM d HH:mm:ss z uuuu" );
ZonedDateTime zdt = ZonedDateTime.parse( input , f );
YearMonth ym = YearMonth.from( zdt );
int year = ym.getYear();
int month = ym.getMonthValue();

Скиньте до консолі.

System.out.println( "input: " + input );
System.out.println( "zdt: " + zdt );
System.out.println( "ym: " + ym );

вхід: пн. березня 14 16:02:37 GMT 2011

zdt: 2011-03-14T16: 02: 37Z [GMT]

ym: 2011-03

Живий код

Дивіться цей код, який працює в IdeOne.com .

Перетворення

Якщо у вас повинен бути Calendarоб'єкт, ви можете перетворити на GregorianCalendarнові методи, додані до старих класів.

GregorianCalendar gc = GregorianCalendar.from( zdt );

Про java.time

Java.time каркас вбудований в Java 8 і пізніших версій. Ці класи витісняти неприємні старі застарілі класи дати і часу , такі як java.util.Date, Calendar, і SimpleDateFormat.

Проект Joda-Time , який зараз знаходиться в режимі обслуговування , радить перейти на java.time.

Щоб дізнатися більше, дивіться навчальний посібник Oracle . І шукайте переповнення стека за багатьма прикладами та поясненнями. Специфікація - JSR 310 .

Де отримати класи java.time?

  • Java SE 8 та SE 9 та новіші версії
    • Вбудований.
    • Частина стандартного Java API з пакетною реалізацією.
    • Java 9 додає деякі незначні функції та виправлення.
  • Java SE 6 і SE 7
    • Значна частина функцій java.time повертається до Java 6 і 7 у ThreeTen-Backport .
  • Android

Проект ThreeTen-Extra розширює java.time додатковими класами. Цей проект є доказом можливих майбутніх доповнень до java.time. Ви можете знайти деякі корисні класи тут , такі як Interval, YearWeek, YearQuarter, і більш .


14

Ну, я думаю, було б поганою ідеєю копіювати код, який вже є у таких класах SimpleDateFormat.

З іншого боку, я особисто пропоную уникати Calendarі, Dateякщо можете, і використовувати натомість Joda Time , як набагато краще розроблений API дати та часу. Наприклад, ви повинні мати на увазі, що SimpleDateFormatце не є безпечним для потоків, тому вам потрібно або локальні потоки, синхронізація, або новий екземпляр кожного разу, коли ви його використовуєте. Пардери та формати Joda є безпечними для потоків.


Дякую за ваш внесок, я, безумовно, буду вивчати використання Joda в майбутньому, схоже, це може бути дуже корисно
Doug Molineux

@Jon Skeet Joda не десеріалізується в Android. Джода коштує мало, якщо вам не потрібно економити дати та час.
Френк Заппа

@FrankZappa: Я не погоджуюся з цим - ви можете робити всі розрахунки дати / часу в Joda Time, але потім конвертувати в інші типи (можливо, просто рядки для простоти) для цілей серіалізації.
Джон Скіт

Вибачте, довелося спростувати, відповідь занадто стара, застаріла, щоб відповісти вищого рейтингу. Сьогодні java.timeце шлях, Василь Бурк дав чудову відповідь.
Сколітус

2
@Scolytus: У верхній (і прийнятої) відповіді 332 голоси порівняно з 10 на цьому. Я думаю, що якщо ти обійдеш всереалізацію кожні 7 + -річної відповіді, яка має краще рішення зараз, у тебе не вистачить голосів ... (Я згоден, що відповідь Василя хороша, і я підтримав це.)
Джон Скіт

10

Не потрібно створювати новий календар, SimpleDateFormat вже використовує Календар під ним.

SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy", Locale.EN_US);
Date date = sdf.parse("Mon Mar 14 16:02:37 GMT 2011"));// all done
Calendar cal = sdf.getCalendar();

(Я поки не можу коментувати, тому я створив нову відповідь)


1
Ваше рішення виглядає елегантно, але має два недоліки: 1. JavaDoc не гарантує, що поведінка буде, як очікувалося. 2. Принаймні для Java 6 ви знайдете шлях у рядку 1353, де клонований об’єкт календаря. Тож тоді! Date.equals (cal.getTime ()).
niels

5

SimpleDateFormatчудово, просто зауважте, що HHвідрізняється від hhроботи з годинами. HHповернеться цілодобово, а годин - 12 годин.

Наприклад, наступне поверне час за 12 годин:

SimpleDateFormat sdf = new SimpleDateFormat("hh:mm aa");

Хоча це повернеться за 24 години:

SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");

4

Розбирайте час із часовим поясом, Zза шаблоном - для часового поясу

String aTime = "2017-10-25T11:39:00+09:00";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ", Locale.getDefault());
try {
    Calendar cal = Calendar.getInstance();
    cal.setTime(sdf.parse(aTime));
    Log.i(TAG, "time = " + cal.getTimeInMillis()); 
} catch (ParseException e) {
    e.printStackTrace();
}

Вихід: він поверне час UTC

1508899140000

введіть тут опис зображення

Якщо ми не встановимо часовий пояс у подібному шаблоні yyyy-MM-dd'T'HH:mm:ss. SimpleDateFormatвикористовуватиме часовий пояс, який встановленоSetting


3

Так, було б поганою практикою розібратися в цьому самостійно. Погляньте на SimpleDateFormat , він перетворить String в дату, і ви можете встановити Date в екземпляр календаря.


1

Простий метод:

public Calendar stringToCalendar(String date, String pattern) throws ParseException {
    String DEFAULT_LOCALE_NAME = "pt";
    String DEFAULT_COUNTRY = "BR";
    Locale DEFAULT_LOCALE = new Locale(DEFAULT_LOCALE_NAME, DEFAULT_COUNTRY);
    SimpleDateFormat format = new SimpleDateFormat(pattern, LocaleUtils.DEFAULT_LOCALE);
    Date d = format.parse(date);
    Calendar c = getCalendar();
    c.setTime(d);
    return c;
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.