Java SimpleDateFormat для часового пояса с разделителем двоеточий?
у меня есть дата в следующем формате: 2010-03-01T00:00:00-08:00
Я бросил следующие SimpleDateFormats на него, чтобы разобрать его:
private static final SimpleDateFormat[] FORMATS = {
new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"), //ISO8601 long RFC822 zone
new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssz"), //ISO8601 long long form zone
new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"), //ignore timezone
new SimpleDateFormat("yyyyMMddHHmmssZ"), //ISO8601 short
new SimpleDateFormat("yyyyMMddHHmm"),
new SimpleDateFormat("yyyyMMdd"), //birthdate from NIST IHE C32 sample
new SimpleDateFormat("yyyyMM"),
new SimpleDateFormat("yyyy") //just the year
};
у меня есть удобный метод, который использует такие форматы, как:
public static Date figureOutTheDamnDate(String wtf) {
if (wtf == null) {
return null;
}
Date retval = null;
for (SimpleDateFormat sdf : FORMATS) {
try {
sdf.setLenient(false)
retval = sdf.parse(wtf);
System.out.println("Date:" + wtf + " hit on pattern:" + sdf.toPattern());
break;
} catch (ParseException ex) {
retval = null;
continue;
}
}
return retval;
}
похоже, он попал в шаблон yyyyMMddHHmm но возвращает дату как Thu Dec 03 00:01:00 PST 2009.
каков правильный шаблон для разбора этой даты?
обновление: мне не нужен разбор часового пояса. Я не ожидаю, что время чувствительно проблемы с перемещением между зонами, но как я могу получить формат зоны "-08:00" для разбора????
единица тест:
@Test
public void test_date_parser() {
System.out.println("ntest_date_parser");
//month is zero based, are you effing kidding me
Calendar d = new GregorianCalendar(2000, 3, 6, 13, 00, 00);
assertEquals(d.getTime(), MyClass.figureOutTheDamnDate("200004061300"));
assertEquals(new GregorianCalendar(1950, 0, 1).getTime(), MyClass.figureOutTheDamnDate("1950"));
assertEquals(new GregorianCalendar(1997, 0, 1).getTime(), MyClass.figureOutTheDamnDate("199701"));
assertEquals(new GregorianCalendar(2010, 1, 25, 15, 19, 44).getTime(), MyClass.figureOutTheDamnDate("20100225151944-0800"));
//my machine happens to be in GMT-0800
assertEquals(new GregorianCalendar(2010, 1, 15, 13, 15, 00).getTime(),MyClass.figureOutTheDamnDate("2010-02-15T13:15:00-05:00"));
assertEquals(new GregorianCalendar(2010, 1, 15, 18, 15, 00).getTime(), MyClass.figureOutTheDamnDate("2010-02-15T18:15:00-05:00"));
assertEquals(new GregorianCalendar(2010, 2, 1).getTime(), MyClass.figureOutTheDamnDate("2010-03-01T00:00:00-08:00"));
assertEquals(new GregorianCalendar(2010, 2, 1, 17, 0, 0).getTime(), MyClass.figureOutTheDamnDate("2010-03-01T17:00:00-05:00"));
}
выход из тест-блок:
test_date_parser
Date:200004061300 hit on pattern:yyyyMMddHHmm
Date:1950 hit on pattern:yyyy
Date:199701 hit on pattern:yyyyMM
Date:20100225151944-0800 hit on pattern:yyyyMMddHHmmssZ
Date:2010-02-15T13:15:00-05:00 hit on pattern:yyyy-MM-dd'T'HH:mm:ss
Date:2010-02-15T18:15:00-05:00 hit on pattern:yyyy-MM-dd'T'HH:mm:ss
Date:2010-03-01T00:00:00-08:00 hit on pattern:yyyy-MM-dd'T'HH:mm:ss
Date:2010-03-01T17:00:00-05:00 hit on pattern:yyyy-MM-dd'T'HH:mm:ss
11 ответов:
JodaTime ' s
DateTimeFormatдля спасения:String dateString = "2010-03-01T00:00:00-08:00"; String pattern = "yyyy-MM-dd'T'HH:mm:ssZ"; DateTimeFormatter dtf = DateTimeFormat.forPattern(pattern); DateTime dateTime = dtf.parseDateTime(dateString); System.out.println(dateTime); // 2010-03-01T04:00:00.000-04:00(разница во времени и часовом поясе в
toString()это просто потому, что я на GMT-4 и не установил локаль явно)если вы хотите получить в итоге
java.util.Dateпросто использоватьDateTime#toDate():Date date = dateTime.toDate();ждать
JDK7 (JSR-310)JSR-310, реализация ссылки называется ThreeTen (надеюсь, это сделает его в Java 8), Если вы требуется лучший форматер в стандартном Java SE API. ТекущийSimpleDateFormatдействительно не ест двоеточие в обозначении часового пояса.обновление: согласно обновлению, вам, по-видимому, не нужен часовой пояс. Это должно работать с
SimpleDateFormat. Просто опустить его (Z) в шаблон.String dateString = "2010-03-01T00:00:00-08:00"; String pattern = "yyyy-MM-dd'T'HH:mm:ss"; SimpleDateFormat sdf = new SimpleDateFormat(pattern); Date date = sdf.parse(dateString); System.out.println(date); // Mon Mar 01 00:00:00 BOT 2010(что правильно в соответствии с моим часовым поясом)
Если вы использовали java 7, вы могли бы использовать следующий шаблон даты и времени. Похоже, что этот шаблон не поддерживается в более ранней версии java.
String dateTimeString = "2010-03-01T00:00:00-08:00"; DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX"); Date date = df.parse(dateTimeString);для получения дополнительной информации обратитесь к
SimpleDateFormatдокументация.
вот фрагмент, который я использовал - с plain
SimpleDateFormat. Надеюсь, что кто-то еще может извлечь из этого пользу:public static void main(String[] args) { SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ") { public StringBuffer format(Date date, StringBuffer toAppendTo, java.text.FieldPosition pos) { StringBuffer toFix = super.format(date, toAppendTo, pos); return toFix.insert(toFix.length()-2, ':'); }; }; // Usage: System.out.println(dateFormat.format(new Date())); }выход:
- Usual Output.........: 2013-06-14T10:54:07-0200 - This snippet's Output: 2013-06-14T10:54:07-02:00
попробуйте это, его работа для меня:
Date date = javax.xml.bind.DatatypeConverter.parseDateTime("2013-06-01T12:45:01+04:00").getTime();В Java 8:
OffsetDateTime dt = OffsetDateTime.parse("2010-03-01T00:00:00-08:00");
Если вы можете использовать JDK 1.7 или выше, попробуйте это:
public class DateUtil { private static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX"); public static String format(Date date) { return dateFormat.format(date); } public static Date parse(String dateString) throws AquariusException { try { return dateFormat.parse(dateString); } catch (ParseException e) { throw new AquariusException(e); } } }документ:https://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html который поддерживает новый формат часового пояса " XXX " (например, -3:00)
в то время как JDK 1.6 поддерживает только другие форматы для часового пояса, которые являются "z" (например, NZST), "zzzz" (например, стандартное время Новой Зеландии), "Z" (например, +1200) и т. д.
tl; dr
OffsetDateTime.parse( "2010-03-01T00:00:00-08:00" )подробности
The ответ от BalusC правильно, но теперь устарело по состоянию на Java 8.
java.время
The java.время framework является преемником как библиотеки Joda-Time, так и старых проблемных классов даты-времени в комплекте с самыми ранними версиями Java (java.утиль.Дата./Календарь и java.текст.SimpleDateFormat).
ISO 8601
входные данные строки происходит в соответствии с ISO 8601 стандартные.
java.классы времени используют форматы ISO 8601 по умолчанию при анализе / генерации текстовых представлений значений даты-времени. Поэтому нет необходимости определять шаблон форматирования.
OffsetDateTimeThe
OffsetDateTimeкласс представляет собой момент на временной линии, настроенный на какой-то конкретный смещение от UTC. В ваш вклад, смещение на 8 часов отстает от UTC, часто используется на большей части западного побережья Северной Америки.OffsetDateTime odt = OffsetDateTime.parse( "2010-03-01T00:00:00-08:00" );Вы, кажется, хотите только дату, в этом случае используйте
LocalDateкласса. Но имейте в виду, что вы отбрасываете данные, (а) время суток и (Б) часовой пояс. Действительно,дата не имеет смысла без контекста часового пояса. В любой данный момент дата меняется по всему миру. Например, сразу после полуночи в Париже все еще "вчера" в Монреале. Так что пока я предлагаю придерживаться значения даты и времени, вы можете легко конвертировать вLocalDateесли вы настаиваете.LocalDate localDate = odt.toLocalDate();Часовой Пояс
если вы знаете предполагаемый часовой пояс, примените его. Часовой пояс-это смещение плюс правила, используемые для обработки аномалий, таких как переход на летнее время (DST). Применение
ZoneIdполучает насZonedDateTime, теперь в режим обслуживания, советует миграция в java.время классы.чтобы узнать больше, смотрите Oracle Tutorial. Поиск переполнения стека для многих примеров и объяснений. Спецификация является JSR 310.
вы можете обменять java.время объекты непосредственно с вашей базой данных. Используйте - драйвера соответствуют JDBC 4.2 или позже. Нет необходимости в строках, нет необходимости в
java.sql.*классы.где получить java.время занятий?
- Java SE 8,Java SE 9,Java SE 10, и позже
- встроенный.
- часть стандартного Java API с комплектной реализацией.
- Java 9 добавляет некоторые незначительные функции и зафиксировать.
- Java SE 6 и Java SE 7
- большая часть java.функциональность time обратно портирована на Java 6 & 7 в ThreeTen-Backport.
- Android
- более поздние версии Android bundle реализации java.время классы.
- для более ранних Android ( ThreeTenABP проект приспосабливается ThreeTen-Backport (упоминалось выше). Смотрите как использовать ThreeTenABP....
The ThreeTen-Extra проект расширяет java.время с дополнительными занятиями. Этот проект является испытательным полигоном для возможных будущих дополнений к java.время. Вы можете найти некоторые полезные классы, такие как
Interval,YearWeek,YearQuarterи больше.
спасибо acdcjunior для вашего решения. Вот немного оптимизированная версия для форматирование и разбор:
public static final SimpleDateFormat XML_SDF = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ", Locale.FRANCE) { private static final long serialVersionUID = -8275126788734707527L; public StringBuffer format(Date date, StringBuffer toAppendTo, java.text.FieldPosition pos) { final StringBuffer buf = super.format(date, toAppendTo, pos); buf.insert(buf.length() - 2, ':'); return buf; }; public Date parse(String source) throws java.text.ParseException { final int split = source.length() - 2; return super.parse(source.substring(0, split - 1) + source.substring(split)); // replace ":" du TimeZone }; };
вы можете использовать X в Java 7.
https://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html
static final SimpleDateFormat DATE_TIME_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); static final SimpleDateFormat JSON_DATE_TIME_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX"); private String stringDate = "2016-12-01 22:05:30"; private String requiredDate = "2016-12-01T22:05:30+03:00"; @Test public void parseDateToBinBankFormat() throws ParseException { Date date = DATE_TIME_FORMAT.parse(stringDate); String jsonDate = JSON_DATE_TIME_FORMAT.format(date); System.out.println(jsonDate); Assert.assertEquals(jsonDate, requiredDate); }
попробовать
setLenient(false).добавление: похоже, вы распознаете различные форматированные
Dateстроки. Если вам нужно сделать запись, вы можете посмотреть на это пример что расширяетInputVerifier.
так как пример Apache FastDateFormat (нажмите для документации версий: 2.6и 3.5) отсутствует здесь, я добавляю один для тех, кто может понадобиться. Ключом здесь является шаблон
ZZ(2 капиталZs).import java.text.ParseException import java.util.Date; import org.apache.commons.lang3.time.FastDateFormat; public class DateFormatTest throws ParseException { public static void main(String[] args) { String stringDateFormat = "yyyy-MM-dd'T'HH:mm:ssZZ"; FastDateFormat fastDateFormat = FastDateFormat.getInstance(stringDateFormat); System.out.println("Date formatted into String:"); System.out.println(fastDateFormat.format(new Date())); String stringFormattedDate = "2016-11-22T14:30:14+05:30"; System.out.println("String parsed into Date:"); System.out.println(fastDateFormat.parse(stringFormattedDate)); } }вот вывод кода:
Date formatted into String: 2016-11-22T14:52:17+05:30 String parsed into Date: Tue Nov 22 14:30:14 IST 2016Примечание: приведенный выше код является lang3 Apache Commons. Класс
org.apache.commons.lang.time.FastDateFormatне поддерживает синтаксический анализ, и он поддерживает только форматирование. Например, вывод следующий код:import java.text.ParseException; import java.util.Date; import org.apache.commons.lang.time.FastDateFormat; public class DateFormatTest { public static void main(String[] args) throws ParseException { String stringDateFormat = "yyyy-MM-dd'T'HH:mm:ssZZ"; FastDateFormat fastDateFormat = FastDateFormat.getInstance(stringDateFormat); System.out.println("Date formatted into String:"); System.out.println(fastDateFormat.format(new Date())); String stringFormattedDate = "2016-11-22T14:30:14+05:30"; System.out.println("String parsed into Date:"); System.out.println(fastDateFormat.parseObject(stringFormattedDate)); } }будет такая:
Date formatted into String: 2016-11-22T14:55:56+05:30 String parsed into Date: Exception in thread "main" java.text.ParseException: Format.parseObject(String) failed at java.text.Format.parseObject(Format.java:228) at DateFormatTest.main(DateFormatTest.java:12)
если строка даты похожа на 2018-07-20T12: 18: 29.802 Z Используйте это
SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
Comments