[英]Joda parse ISO8601 date in GMT timezone
我有一个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
,但我在本地时间转换它。
有人知道一种不会施加此限制的转换方法吗?
这是一个工作的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))
}
}
注意:
Joda-Time团队告诉我们要迁移到Java 8及更高版本中内置的java.time框架。 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 );
时区是偏移加上用于处理诸如夏令时(DST)之类的异常的规则。 正确的时区名称使用continent/region
格式。 您可以将时区( ZoneId
)分配给OffsetDateTime
以获取ZonedDateTime
。
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = odt.atZoneSameInstant( zoneId );
编辑
https://stackoverflow.com/a/23242779/812919
是更好的解决方案。
对于任何未来的读者,如果您尝试以yyyyMMddTHHmmssZ
格式解析字符串。 使用以下代码更容易解析它。 代码在Kotlin。 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()
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.