Преобразование строки в дату с часовым поясом - PullRequest
15 голосов
/ 17 ноября 2010

У меня есть строка в шаблоне гггг-мм-дд чч: мм а, и я могу получить объект часового пояса отдельно, в котором приведенная выше строка представляет дату.

Я хочу преобразовать это вниже формат.гггг-мм-дд чч: мм: сс z

как я могу это сделать?

Ответы [ 5 ]

21 голосов
/ 17 ноября 2010

Вы можете использовать SimpleDateFormat с yyyy-MM-dd HH:mm:ss и явно установить TimeZone :

public static Date getSomeDate(final String str, final TimeZone tz)
    throws ParseException {
  final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm a");
  sdf.setTimeZone(tz);
  return sdf.parse(str);
}

/**
 * @param args
 * @throws IOException
 * @throws InterruptedException
 * @throws ParseException
 */
public static void main(final String[] args) throws ParseException {
  final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z");
  System.out.println(sdf.format(getSomeDate(
      "2010-11-17 01:12 pm", TimeZone.getTimeZone("Europe/Berlin"))));
  System.out.println(sdf.format(getSomeDate(
      "2010-11-17 01:12 pm", TimeZone.getTimeZone("America/Chicago"))));
}

Распечатывается:

2010-11-17 13:12:00 + 0100

2010-11-17 20:12:00 + 0100

Обновление 2010-12-01: Если вы хотите явно распечатать специальный TimeZone, установите его в SimpleDateFormat:

sdf.setTimeZone(TimeZone .getTimeZone("IST")); 
System.out.println(sdf.format(getSomeDate(
    "2010-11-17 01:12 pm", TimeZone.getTimeZone("IST"))));

Какие отпечатки 2010-11-17 13:12:00 +0530

9 голосов
/ 23 января 2017

ТЛ; др

LocalDateTime.parse(                        // Parse string as value without time zone and without offset-from-UTC.
    "2017-01-23 12:34 PM" , 
    DateTimeFormatter.ofPattern( "uuuu-MM-dd hh:mm a" )
)                                           // Returns a `LocalDateTime` object.
.atZone( ZoneId.of( "America/Montreal" ) )  // Assign time zone, to determine a moment. Returns a `ZonedDateTime` object.
.toInstant()                                // Adjusts from zone to UTC.
.toString()                                 // Generate string: 2017-01-23T17:34:00Z
.replace( "T" , " " )                       // Substitute SPACE for 'T' in middle.
.replace( "Z" , " Z" )                      // Insert SPACE before 'Z'.

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

В других ответах используются старые классы даты и времени (Date, Calendar и т. Д.), Которые теперь унаследованы и заменены классами java.time.

LocalDateTime

У меня есть строка в шаблоне гггг-мм-дд чч: мм а

В такой входной строке отсутствует указание смещения от UTC или часового пояса. Таким образом, мы разбираем как LocalDateTime.

Определите шаблон форматирования, соответствующий вашему вводу с DateTimeFormatter объектом.

String input = "2017-01-23 12:34 PM" ;
DateTimeFormatter f = DateTimeFormatter.ofPattern( "uuuu-MM-dd hh:mm a" );
LocalDateTime ldt = LocalDateTime.parse( input , f );

ldt.toString (): 2017-01-23T12: 34

Обратите внимание, что LocalDateTime - это , а не конкретный момент, только смутное представление о диапазоне возможных моментов. Например, через несколько минут после полуночи в Париже Франция все еще «вчера» в Монреале, Канада. Поэтому без контекста часового пояса, такого как Europe/Paris или America/Montreal, просто говорить «через несколько минут после полуночи» не имеет смысла.

ZoneId

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

Часовой пояс представлен классом ZoneId.

Укажите собственное имя часового пояса в формате continent/region, например America/Montreal, Africa/Casablanca или Pacific/Auckland. Никогда не используйте 3-4-буквенное сокращение, например EST или IST, поскольку они не истинных часовых поясов, не стандартизированы и даже не уникальны (!).

ZoneId z = ZoneId.of( "America/Montreal" );

ZonedDateTime

Примените ZoneId, чтобы получить ZonedDateTime, который действительно является точкой на временной шкале, конкретным моментом в истории.

ZonedDateTime zdt = ldt.atZone( z );

zdt.toString (): 2017-01-23T12: 34-05: 00 [Америка / Монреаль]

Instant

Я хочу преобразовать это в приведенный ниже формат. гггг-мм-дд чч: мм: сс z

Во-первых, знайте, что буквенный символ Z является сокращением от Zulu и означает UTC . Другими словами, смещение от UTC нулевых часов, +00:00.

Класс Instant представляет момент на временной шкале в UTC с разрешением наносекунд (до девяти (9) цифр десятичного знака доля).

Вы можете извлечь Instant объект из ZonedDateTime.

Instant instant = zdt.toInstant();  // Extracting the same moment but in UTC.

Для генерации строки в стандартном формате ISO 8601 , например 2017-01-22T18:21:13.354Z, позвоните toString. Стандартный формат не имеет пробелов, использует T для отделения даты год-месяц от часа-минуты-секунды и добавляет Z канонически для смещения нуля.

String output = instant.toString();

instant.toString (): 2017-01-23T17: 34: 00Z

Я настоятельно рекомендую использовать стандартные форматы, когда это возможно. Если вы настаиваете на использовании пробелов в указанном вами желаемом формате, либо определите свой собственный шаблон форматирования в объекте DateTimeFormatter или просто выполните строковую манипуляцию с выводом Instant::toString .

String output = instant.toString()
                       .replace( "T" , " " )  // Substitute SPACE for T.
                       .replace( "Z" , " Z" ); // Insert SPACE before Z.

вывод: 2017-01-23 17:34:00 Z

Попробуйте этот код в прямом эфире на IdeOne.com .


О java.time

Фреймворк java.time встроен в Java 8 и более поздние версии. Эти классы заменяют проблемные старые устаревшие классы даты и времени, такие как java.util.Date, Calendar, & SimpleDateFormat.

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

Чтобы узнать больше, см. Oracle Tutorial . И поиск переполнения стека для многих примеров и объяснений. Спецификация 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 и more .

5 голосов
/ 17 ноября 2010

Использовать SimpleDateFormat

String string1 = "2009-10-10 12:12:12 ";
SimpleDateFormat sdf =  new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z")
sdf.setTimeZone(tz);
Date date = sdf.parse(string1);
0 голосов
/ 22 января 2017

Несомненно, формат, который обычно используется, будет иметь форму 2014-10-05T15:23:01Z (TZ)

Для этого нужно использовать этот код

SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
String dateInString = "2014-10-05T15:23:01Z";

 try {

     Date date = formatter.parse(dateInString.replaceAll("Z$", "+0000"));
     System.out.println(date);

 } catch (ParseException e) {
     e.printStackTrace();
 }

Выходной сигнал будет Sun Oct 05 20:53:01 IST 2014

Тем не менее, я не уверен, почему мы должны были заменить все "Z", если вы не добавляете replaceall, все программы завершатся ошибкой.

0 голосов
/ 17 ноября 2010

Создайте новый экземпляр SimpleDateFormat , используя ваш шаблон даты.После этого вы можете вызвать его метод синтаксического анализа для преобразования строк даты в объект java.util.Date .

...