Joda parse ISO8601 date in GMT timezone

折月煮酒 提交于 2019-12-12 08:19:36

问题


I have a ISO 8601 date, lets say: 2012-01-19T19:00-05:00

My machine timezone is GMT+1

I'm trying to use joda to parse this and convert it to the respective GMT date and time:

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

Now the result that I'm expecting is Fri Jan 20 00:00:00 CET 2012

Instead I'm getting: Fri Jan 20 01:00:00 CET 2012

I believe this is because I'm in timezone GMT + 1.

Is there a way to parse the date faking to be in a different time zone?

Edit: Basically the problem is when I call the toDate() method. The method converts the DateTime into a Date as I need to do but I transforms it in local time.

Do someone know a conversion method which doesn't impose this limitation?


回答1:


Here's a working groovy testcase. Shows how times in other timezones can be displayed.

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))
    }
}

Note:

  • You'll have to adjust the assertions, because I'm located in the London timezone :-)
  • The "withZone" method changes the DateTime object's metadata to indicate it's timezone. Still the same point in time, just displayed with a different offset.



回答2:


java.time

The Joda-Time team has told us to migrate to the java.time framework built into Java 8 and later. The java.time framework is defined by JSR 310. Much of the java.time functionality has been back-ported to Java 6 & 7 and further adapted for Android.

Offset

The java.time classes include OffsetDateTime to represent a moment on the timeline with an offset-from-UTC but not a full time zone.

The java.time classes use the standard ISO 8601 formats by default when parsing or generating strings. So no need to define a formatting pattern.

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

Time Zone

A time zone is an offset plus rules for handling anomalies such as Daylight Saving Time (DST). A proper time zone name uses a continent/region format. You can assign a time zone (ZoneId) to an OffsetDateTime to get a ZonedDateTime.

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



回答3:


EDIT

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

Is a better solution.


For any future readers, if you are trying to parse a string in the format yyyyMMddTHHmmssZ. Its easier to parse it with the following code. Code is in Kotlin. The iCalendar recur rule is an example of where this format might appear.

// 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()
}


来源:https://stackoverflow.com/questions/9077226/joda-parse-iso8601-date-in-gmt-timezone

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!