Перетворити рядок в об’єкт календаря на 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.