mirror of
https://codeberg.org/Mercury-IM/Smack
synced 2024-11-27 00:32:07 +01:00
SMACK-407 Time zones now parse correctly.
git-svn-id: http://svn.igniterealtime.org/svn/repos/smack/trunk@13442 b35dd754-fafc-0310-a699-88a17e54d16e
This commit is contained in:
parent
04cea9e28c
commit
e0e92eca76
3 changed files with 120 additions and 15 deletions
|
@ -10,12 +10,12 @@ import java.text.SimpleDateFormat;
|
||||||
public enum DateFormatType
|
public enum DateFormatType
|
||||||
{
|
{
|
||||||
XEP_0082_DATE_PROFILE("yyyy-MM-dd"),
|
XEP_0082_DATE_PROFILE("yyyy-MM-dd"),
|
||||||
XEP_0082_DATETIME_PROFILE("yyyy-MM-dd'T'HH:mm:ss'Z'"),
|
XEP_0082_DATETIME_PROFILE("yyyy-MM-dd'T'HH:mm:ssZ"),
|
||||||
XEP_0082_DATETIME_MILLIS_PROFILE("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"),
|
XEP_0082_DATETIME_MILLIS_PROFILE("yyyy-MM-dd'T'HH:mm:ss.SSSZ"),
|
||||||
XEP_0082_TIME_PROFILE("hh:mm:ss"),
|
XEP_0082_TIME_PROFILE("hh:mm:ss"),
|
||||||
XEP_0082_TIME_ZONE_PROFILE("hh:mm:ss'Z'"),
|
XEP_0082_TIME_ZONE_PROFILE("hh:mm:ssZ"),
|
||||||
XEP_0082_TIME_MILLIS_PROFILE("hh:mm:ss.SSS"),
|
XEP_0082_TIME_MILLIS_PROFILE("hh:mm:ss.SSS"),
|
||||||
XEP_0082_TIME_MILLIS_ZONE_PROFILE("hh:mm:ss.SSS'Z'"),
|
XEP_0082_TIME_MILLIS_ZONE_PROFILE("hh:mm:ss.SSSZ"),
|
||||||
XEP_0091_DATETIME("yyyyMMdd'T'HH:mm:ss");
|
XEP_0091_DATETIME("yyyyMMdd'T'HH:mm:ss");
|
||||||
|
|
||||||
private String formatString;
|
private String formatString;
|
||||||
|
|
|
@ -71,7 +71,7 @@ public class StringUtils {
|
||||||
|
|
||||||
private static final DateFormat dateTimeFormatter = DateFormatType.XEP_0082_DATETIME_MILLIS_PROFILE.createFormatter();
|
private static final DateFormat dateTimeFormatter = DateFormatType.XEP_0082_DATETIME_MILLIS_PROFILE.createFormatter();
|
||||||
private static final Pattern dateTimePattern = Pattern.compile("^\\d+(-\\d+){2}+T(\\d+:){2}\\d+.\\d+(Z|([+-](\\d+:\\d+)))?$");
|
private static final Pattern dateTimePattern = Pattern.compile("^\\d+(-\\d+){2}+T(\\d+:){2}\\d+.\\d+(Z|([+-](\\d+:\\d+)))?$");
|
||||||
private static final DateFormat dateTimeNoMillisFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
|
private static final DateFormat dateTimeNoMillisFormatter = DateFormatType.XEP_0082_DATETIME_PROFILE.createFormatter();
|
||||||
private static final Pattern dateTimeNoMillisPattern = Pattern.compile("^\\d+(-\\d+){2}+T(\\d+:){2}\\d+(Z|([+-](\\d+:\\d+)))?$");
|
private static final Pattern dateTimeNoMillisPattern = Pattern.compile("^\\d+(-\\d+){2}+T(\\d+:){2}\\d+(Z|([+-](\\d+:\\d+)))?$");
|
||||||
|
|
||||||
private static final DateFormat xep0091Formatter = new SimpleDateFormat("yyyyMMdd'T'HH:mm:ss");
|
private static final DateFormat xep0091Formatter = new SimpleDateFormat("yyyyMMdd'T'HH:mm:ss");
|
||||||
|
@ -101,11 +101,11 @@ public class StringUtils {
|
||||||
xep0091Date7Digit2MonthFormatter.setLenient(false);
|
xep0091Date7Digit2MonthFormatter.setLenient(false);
|
||||||
|
|
||||||
couplings.add(new PatternCouplings(datePattern, dateFormatter));
|
couplings.add(new PatternCouplings(datePattern, dateFormatter));
|
||||||
couplings.add(new PatternCouplings(dateTimePattern, dateTimeFormatter));
|
couplings.add(new PatternCouplings(dateTimePattern, dateTimeFormatter, true));
|
||||||
couplings.add(new PatternCouplings(dateTimeNoMillisPattern, dateTimeNoMillisFormatter));
|
couplings.add(new PatternCouplings(dateTimeNoMillisPattern, dateTimeNoMillisFormatter, true));
|
||||||
couplings.add(new PatternCouplings(timePattern, timeFormatter));
|
couplings.add(new PatternCouplings(timePattern, timeFormatter, true));
|
||||||
couplings.add(new PatternCouplings(timeNoZonePattern, timeNoZoneFormatter));
|
couplings.add(new PatternCouplings(timeNoZonePattern, timeNoZoneFormatter));
|
||||||
couplings.add(new PatternCouplings(timeNoMillisPattern, timeNoMillisFormatter));
|
couplings.add(new PatternCouplings(timeNoMillisPattern, timeNoMillisFormatter, true));
|
||||||
couplings.add(new PatternCouplings(timeNoMillisNoZonePattern, timeNoMillisNoZoneFormatter));
|
couplings.add(new PatternCouplings(timeNoMillisNoZonePattern, timeNoMillisNoZoneFormatter));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -165,6 +165,10 @@ public class StringUtils {
|
||||||
|
|
||||||
if (matcher.matches())
|
if (matcher.matches())
|
||||||
{
|
{
|
||||||
|
if (coupling.needToConvertTimeZone) {
|
||||||
|
dateString = coupling.convertTime(dateString);
|
||||||
|
}
|
||||||
|
|
||||||
synchronized (coupling.formatter) {
|
synchronized (coupling.formatter) {
|
||||||
return coupling.formatter.parse(dateString);
|
return coupling.formatter.parse(dateString);
|
||||||
}
|
}
|
||||||
|
@ -752,11 +756,31 @@ public class StringUtils {
|
||||||
private static class PatternCouplings {
|
private static class PatternCouplings {
|
||||||
Pattern pattern;
|
Pattern pattern;
|
||||||
DateFormat formatter;
|
DateFormat formatter;
|
||||||
|
boolean needToConvertTimeZone = false;
|
||||||
|
|
||||||
public PatternCouplings(Pattern datePattern, DateFormat dateFormat) {
|
public PatternCouplings(Pattern datePattern, DateFormat dateFormat) {
|
||||||
pattern = datePattern;
|
pattern = datePattern;
|
||||||
formatter = dateFormat;
|
formatter = dateFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public PatternCouplings(Pattern datePattern, DateFormat dateFormat, boolean shouldConvertToRFC822) {
|
||||||
|
pattern = datePattern;
|
||||||
|
formatter = dateFormat;
|
||||||
|
needToConvertTimeZone = shouldConvertToRFC822;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String convertTime(String dateString) {
|
||||||
|
if (dateString.charAt(dateString.length() - 1) == 'Z') {
|
||||||
|
return dateString.replace("Z", "+0000");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// If the time zone wasn't specified with 'Z', then it's in
|
||||||
|
// ISO8601 format (i.e. '(+|-)HH:mm')
|
||||||
|
// RFC822 needs a similar format just without the colon (i.e.
|
||||||
|
// '(+|-)HHmm)'), so remove it
|
||||||
|
return dateString.replaceAll("([\\+\\-]\\d\\d):(\\d\\d)","$1$2");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -253,7 +253,7 @@ public class StringUtilsTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void parseXep0082DateProfile() throws Exception
|
public void parseXep0082Date() throws Exception
|
||||||
{
|
{
|
||||||
Date date = StringUtils.parseDate("1971-07-21");
|
Date date = StringUtils.parseDate("1971-07-21");
|
||||||
Calendar cal = Calendar.getInstance();
|
Calendar cal = Calendar.getInstance();
|
||||||
|
@ -265,7 +265,7 @@ public class StringUtilsTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void parseXep0082TimeProfile() throws Exception
|
public void parseXep0082Time() throws Exception
|
||||||
{
|
{
|
||||||
Date date = StringUtils.parseDate("02:56:15");
|
Date date = StringUtils.parseDate("02:56:15");
|
||||||
Calendar cal = Calendar.getInstance();
|
Calendar cal = Calendar.getInstance();
|
||||||
|
@ -277,7 +277,31 @@ public class StringUtilsTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void parseXep0082TimeWithMillisProfile() throws Exception
|
public void parseXep0082TimeUTC() throws Exception
|
||||||
|
{
|
||||||
|
Date date = StringUtils.parseDate("02:56:15Z");
|
||||||
|
Calendar cal = Calendar.getInstance();
|
||||||
|
cal.setTime(date);
|
||||||
|
cal.setTimeZone(TimeZone.getTimeZone("GMT"));
|
||||||
|
assertEquals(2, cal.get(Calendar.HOUR_OF_DAY));
|
||||||
|
assertEquals(56, cal.get(Calendar.MINUTE));
|
||||||
|
assertEquals(15, cal.get(Calendar.SECOND));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void parseXep0082TimeWithZone() throws Exception
|
||||||
|
{
|
||||||
|
Date date = StringUtils.parseDate("04:40:15+02:30");
|
||||||
|
Calendar cal = Calendar.getInstance();
|
||||||
|
cal.setTime(date);
|
||||||
|
cal.setTimeZone(TimeZone.getTimeZone("GMT"));
|
||||||
|
assertEquals(2, cal.get(Calendar.HOUR_OF_DAY));
|
||||||
|
assertEquals(10, cal.get(Calendar.MINUTE));
|
||||||
|
assertEquals(15, cal.get(Calendar.SECOND));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void parseXep0082TimeWithMillis() throws Exception
|
||||||
{
|
{
|
||||||
Date date = StringUtils.parseDate("02:56:15.123");
|
Date date = StringUtils.parseDate("02:56:15.123");
|
||||||
Calendar cal = Calendar.getInstance();
|
Calendar cal = Calendar.getInstance();
|
||||||
|
@ -290,7 +314,33 @@ public class StringUtilsTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void parseXep0082DateTimeProfile() throws Exception
|
public void parseXep0082TimeWithMillisUTC() throws Exception
|
||||||
|
{
|
||||||
|
Date date = StringUtils.parseDate("02:56:15.123Z");
|
||||||
|
Calendar cal = Calendar.getInstance();
|
||||||
|
cal.setTime(date);
|
||||||
|
cal.setTimeZone(TimeZone.getTimeZone("GMT"));
|
||||||
|
assertEquals(2, cal.get(Calendar.HOUR_OF_DAY));
|
||||||
|
assertEquals(56, cal.get(Calendar.MINUTE));
|
||||||
|
assertEquals(15, cal.get(Calendar.SECOND));
|
||||||
|
assertEquals(123, cal.get(Calendar.MILLISECOND));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void parseXep0082TimeWithMillisZone() throws Exception
|
||||||
|
{
|
||||||
|
Date date = StringUtils.parseDate("02:56:15.123+01:00");
|
||||||
|
Calendar cal = Calendar.getInstance();
|
||||||
|
cal.setTime(date);
|
||||||
|
cal.setTimeZone(TimeZone.getTimeZone("GMT"));
|
||||||
|
assertEquals(1, cal.get(Calendar.HOUR_OF_DAY));
|
||||||
|
assertEquals(56, cal.get(Calendar.MINUTE));
|
||||||
|
assertEquals(15, cal.get(Calendar.SECOND));
|
||||||
|
assertEquals(123, cal.get(Calendar.MILLISECOND));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void parseXep0082DateTimeUTC() throws Exception
|
||||||
{
|
{
|
||||||
Date date = StringUtils.parseDate("1971-07-21T02:56:15Z");
|
Date date = StringUtils.parseDate("1971-07-21T02:56:15Z");
|
||||||
Calendar cal = Calendar.getInstance();
|
Calendar cal = Calendar.getInstance();
|
||||||
|
@ -305,7 +355,22 @@ public class StringUtilsTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void parseXep0082DateTimeProfileWithMillis() throws Exception
|
public void parseXep0082DateTimeZone() throws Exception
|
||||||
|
{
|
||||||
|
Date date = StringUtils.parseDate("1971-07-21T02:56:15-01:00");
|
||||||
|
Calendar cal = Calendar.getInstance();
|
||||||
|
cal.setTime(date);
|
||||||
|
cal.setTimeZone(TimeZone.getTimeZone("GMT"));
|
||||||
|
assertEquals(1971, cal.get(Calendar.YEAR));
|
||||||
|
assertEquals(6, cal.get(Calendar.MONTH));
|
||||||
|
assertEquals(21, cal.get(Calendar.DAY_OF_MONTH));
|
||||||
|
assertEquals(3, cal.get(Calendar.HOUR_OF_DAY));
|
||||||
|
assertEquals(56, cal.get(Calendar.MINUTE));
|
||||||
|
assertEquals(15, cal.get(Calendar.SECOND));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void parseXep0082DateTimeWithMillisUTC() throws Exception
|
||||||
{
|
{
|
||||||
Date date = StringUtils.parseDate("1971-07-21T02:56:15.123Z");
|
Date date = StringUtils.parseDate("1971-07-21T02:56:15.123Z");
|
||||||
Calendar cal = Calendar.getInstance();
|
Calendar cal = Calendar.getInstance();
|
||||||
|
@ -320,6 +385,22 @@ public class StringUtilsTest {
|
||||||
assertEquals(123, cal.get(Calendar.MILLISECOND));
|
assertEquals(123, cal.get(Calendar.MILLISECOND));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void parseXep0082DateTimeWithMillisZone() throws Exception
|
||||||
|
{
|
||||||
|
Date date = StringUtils.parseDate("1971-07-21T02:56:15.123-01:00");
|
||||||
|
Calendar cal = Calendar.getInstance();
|
||||||
|
cal.setTime(date);
|
||||||
|
cal.setTimeZone(TimeZone.getTimeZone("GMT"));
|
||||||
|
assertEquals(1971, cal.get(Calendar.YEAR));
|
||||||
|
assertEquals(6, cal.get(Calendar.MONTH));
|
||||||
|
assertEquals(21, cal.get(Calendar.DAY_OF_MONTH));
|
||||||
|
assertEquals(3, cal.get(Calendar.HOUR_OF_DAY));
|
||||||
|
assertEquals(56, cal.get(Calendar.MINUTE));
|
||||||
|
assertEquals(15, cal.get(Calendar.SECOND));
|
||||||
|
assertEquals(123, cal.get(Calendar.MILLISECOND));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void parseXep0091() throws Exception
|
public void parseXep0091() throws Exception
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue