Преобразование метки времени из parse.com в Java
Я получаю метку времени создания объекта от parse.com как 2014-08-01T01:17:56.751Z. У меня есть класс, который преобразует его в относительное время.
public static String timeAgo(String time){
PrettyTime mPtime = new PrettyTime();
long timeAgo = timeStringtoMilis(time);
return mPtime.format( new Date( timeAgo ) );
}
public static long timeStringtoMilis(String time) {
long milis = 0;
try {
SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = sd.parse(time);
milis = date.getTime();
} catch (Exception e) {
e.printStackTrace();
}
return milis;
}
Проблема в том, что это неправильно разбирает дату. Прямо сейчас результат говорит 4 десятилетия назад, и это очень неправильно. Что я делаю не так?
2 ответа
Ваш текущий формат даты "yyyy-MM-dd HH:mm:ss"
не работает для данного примера 2014-08-01T01:17:56.751Z
, В формате отсутствуют символы T
а также Z
и миллисекунды. Измените это на:
new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
починить это.
Также проверьте примеры в JavaDoc SimpleDateFormat
потому что он также показывает правильный формат даты для вашего примера: http://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html.
Расширяя ответ @ Тома:
Эта проблема
При жестком кодировании "Z" вы предполагаете, что все даты были сохранены как UTC - что не обязательно должно иметь место.
Проблема в том, что SimpleDateFormat не распознает буквальное 'Z'
в качестве псевдонима для смещения UTC "-0000" (по какой-либо причине, поскольку он претендует на совместимость с ISO-8601).
Так что вы не можете сделать
new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
так как это неправильно предполагает, что все даты будут всегда записываться как в UTC, но вы не можете сделать
new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
либо, так как это не сможет проанализировать дату, когда встречается литерал "Z".
Решение 1. Используйте javax.xml.bind.DatatypeConverter
Этот преобразователь типов данных на самом деле соответствует стандарту ISO8601 и может быть использован так же просто, как
import javax.xml.bind.DatatypeConverter;
public Long isoToMillis(String dateString){
Calendar calendar = DatatypeConverter.parseDateTime(dateString);
return calendar.getTime().getTime();
}
Если вы все равно используете JAXB, это будет путь.
Решение 2. Используйте условные форматы
final static String ZULUFORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";
final static String OFFSETFORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSZ";
/* This is a utility method, so you want the calling method
* to be informed that something is wrong with the input format
*/
public static Long isoToMillis(String dateString) throws ParseException{
/* It is the default, so we should use it by default */
String formatString = ZULUFORMAT;
if(! dateString.endsWith("Z") ) {
formatString = OFFSETFORMAT;
}
SimpleDateFormat sd = new SimpleDateFormat(formatString);
return sd.parse(dateString).getTime();
}
Если вы еще не используете JAXB, вы можете поместить этот метод в служебный класс.