Joda разобрать дату ISO8601 в часовом поясе GMT - PullRequest
15 голосов
/ 31 января 2012

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

Часовой пояс моей машины GMT+1

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

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, как мне нужно, но я преобразую его по местному времени.

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

Ответы [ 3 ]

20 голосов
/ 04 февраля 2012

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

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 для указания его часового пояса. Все тот же момент времени, только с другим смещением.
0 голосов
/ 20 июня 2018

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

https://stackoverflow.com/a/23242779/812919

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


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

// 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()
}
0 голосов
/ 22 мая 2016

java.time

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

Смещение

Java.time-классы включают OffsetDateTime для представления момента на временной шкале с смещением от 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 );
...