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
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()
}
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.
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 );
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 );
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: