Подтвердить что ты не робот

Joda проанализирует дату ISO8601 в часовом поясе GMT

У меня есть дата ISO 8601, скажем: 2012-01-19T19:00-05:00

Мой часовой пояс машины GMT+1

Я пытаюсь использовать joda для синтаксического анализа и преобразования его в соответствующую дату и время GMT:

DateTimeFormatter simpleDateISOFormat = DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mmZZ"); 
creationDate = simpleDateISOFormat.withZone(DateTimeZone.UTC)
                                  .parseDateTime(date + "T" + time)
                                  .toDate(); 

Теперь результат, который я ожидаю, Fri Jan 20 00:00:00 CET 2012

Вместо этого я получаю: Fri Jan 20 01:00:00 CET 2012

Я считаю, что это потому, что я вовремя GMT + 1.

Есть ли способ проанализировать фальсификацию даты в другом часовом поясе?

Изменить: В основном проблема заключается в том, что я вызываю метод toDate(). Метод преобразует DateTime в Date, как мне нужно, но я преобразовываю его в локальное время.

Кто-нибудь знает метод преобразования, который не налагает это ограничение?

4b9b3361

Ответ 1

Здесь работает тестовый файл groovy. Показывает, как могут отображаться часы в других часовых поясах.

import org.joda.time.*
import org.joda.time.format.*

@Grapes([
    @Grab(group='joda-time', module='joda-time', version='1.6.2')
])

class JodaTimeTest extends GroovyTestCase {

    void testTimeZone() {
        DateTimeFormatter parser    = ISODateTimeFormat.dateTimeParser()
        DateTimeFormatter formatter = ISODateTimeFormat.dateTimeNoMillis()

        DateTime dateTimeHere     = parser.parseDateTime("2012-01-19T19:00:00-05:00")

        DateTime dateTimeInLondon = dateTimeHere.withZone(DateTimeZone.forID("Europe/London"))
        DateTime dateTimeInParis  = dateTimeHere.withZone(DateTimeZone.forID("Europe/Paris"))

        assertEquals("2012-01-20T00:00:00Z", formatter.print(dateTimeHere))
        assertEquals("2012-01-20T00:00:00Z", formatter.print(dateTimeInLondon))
        assertEquals("2012-01-20T01:00:00+01:00", formatter.print(dateTimeInParis))
    }
}

Примечание:

  • Вам придется корректировать утверждения, потому что я располагаюсь в лондонском часовом поясе: -)
  • Метод "withZone" изменяет метаданные объекта DateTime, чтобы указать его часовой пояс. Все тот же момент времени, просто отображается с другим смещением.

Ответ 2

java.time

Команда Joda-Time сообщила нам перейти на java.time, встроенную в Java 8 и более поздние версии. Структура java.time определяется JSR 310. Большая часть функций java.time была возвращена обратно портирована на Java 6 и 7 и далее адаптирован для Android.

Offset

Классы java.time включают OffsetDateTime, чтобы представить момент на временной шкале с offset-from-UTC, но не полный часовой пояс.

В классах java.time по умолчанию используются стандартные форматы ISO 8601 при разборе или генерации строк. Поэтому нет необходимости определять шаблон форматирования.

String input = "2012-01-19T19:00-05:00";
OffsetDateTime odt = OffsetDateTime.parse( input );

Часовой пояс

A часовой пояс - это смещение плюс правила для обработки аномалий, таких как переход на летнее время (DST). A имя часового пояса использует формат continent/region. Вы можете назначить часовой пояс (ZoneId) на OffsetDateTime, чтобы получить ZonedDateTime.

ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = odt.atZoneSameInstant( zoneId );

Ответ 3

РЕДАКТИРОВАТЬ

fooobar.com/info/2129427/...

Это лучшее решение.


Для любых будущих читателей, если вы пытаетесь разобрать строку в формате yyyyMMddTHHmmssZ. Его проще разобрать с помощью следующего кода. Код находится в Котлине. Правило iCalendar recur - пример того, где может выглядеть этот формат.

// Reads from end to start to accommodate case where year has 4+ digits. 10100 for example.
fun iso8601GetPart(hashMap : HashMap,noOfCharsFromEnd : Int?) : String{
    var str = hashMap.get("DATE_TIME")
    var endIndex = str.length
    if(str.get(str.length-1)=='T' || str.get(str.length-1)=='Z'){
        endIndex--
    }
    if(noOfCharsFromEnd==null){
        return str
    }else{
        hashMap.put("DATE_TIME", str.substring(0, endIndex - noOfCharsFromEnd))
        return str.substring(endIndex-noOfCharsFromEnd,endIndex)
    }
}

fun foo(){

    var hashMap = HashMap<String,String>()
    hashMap.put("DATE_TIME",dateTimeString)

    var secOfMin = iso8601GetPart(hashMap,2).toInt()
    var minOfHour = iso8601GetPart(hashMap,2).toInt()
    var hourOfDay = iso8601GetPart(hashMap,2).toInt()
    var dayOfMonth = iso8601GetPart(hashMap,2).toInt()
    var monthOfYear = iso8601GetPart(hashMap,2).toInt()
    var years = iso8601GetPart(hashMap,null).toInt()
}