122dd87d4de604631bc6dabd1186be58dbed71929Jan Berkelpackage com.xtremelabs.robolectric.shadows; 222dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel 322dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel 422dd87d4de604631bc6dabd1186be58dbed71929Jan Berkelimport android.text.format.Time; 522dd87d4de604631bc6dabd1186be58dbed71929Jan Berkelimport android.util.TimeFormatException; 622dd87d4de604631bc6dabd1186be58dbed71929Jan Berkelimport com.xtremelabs.robolectric.internal.Implementation; 722dd87d4de604631bc6dabd1186be58dbed71929Jan Berkelimport com.xtremelabs.robolectric.internal.Implements; 822dd87d4de604631bc6dabd1186be58dbed71929Jan Berkelimport com.xtremelabs.robolectric.internal.RealObject; 922dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel 1022dd87d4de604631bc6dabd1186be58dbed71929Jan Berkelimport java.lang.reflect.Constructor; 1122dd87d4de604631bc6dabd1186be58dbed71929Jan Berkelimport java.lang.reflect.InvocationTargetException; 1222dd87d4de604631bc6dabd1186be58dbed71929Jan Berkelimport java.text.ParseException; 1322dd87d4de604631bc6dabd1186be58dbed71929Jan Berkelimport java.text.SimpleDateFormat; 1422dd87d4de604631bc6dabd1186be58dbed71929Jan Berkelimport java.util.*; 1522dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel 1622dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel@Implements(Time.class) 1722dd87d4de604631bc6dabd1186be58dbed71929Jan Berkelpublic class ShadowTime { 1822dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel @RealObject 1922dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel private Time time; 2022dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel 214bbf62814947c2b192db055300561cdf5b3e7a3dJan Berkel private static final long SECOND_IN_MILLIS = 1000; 224bbf62814947c2b192db055300561cdf5b3e7a3dJan Berkel private static final long MINUTE_IN_MILLIS = SECOND_IN_MILLIS * 60; 234bbf62814947c2b192db055300561cdf5b3e7a3dJan Berkel private static final long HOUR_IN_MILLIS = MINUTE_IN_MILLIS * 60; 244bbf62814947c2b192db055300561cdf5b3e7a3dJan Berkel private static final long DAY_IN_MILLIS = HOUR_IN_MILLIS * 24; 254bbf62814947c2b192db055300561cdf5b3e7a3dJan Berkel 2622dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel public void __constructor__() { 2722dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel __constructor__(getCurrentTimezone()); 2822dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel } 2922dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel 3022dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel public void __constructor__(String timezone) { 3122dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel if (timezone == null) { 3222dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel throw new NullPointerException("timezone is null!"); 3322dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel } 3422dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel time.timezone = timezone; 3522dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel time.year = 1970; 3622dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel time.monthDay = 1; 3722dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel time.isDst = -1; 3822dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel } 3922dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel 4022dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel public void __constructor__(Time other) { 4122dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel set(other); 4222dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel } 4322dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel 4422dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel @Implementation 4522dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel public void set(Time other) { 4622dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel time.timezone = other.timezone; 4722dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel time.second = other.second; 4822dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel time.minute = other.minute; 4922dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel time.hour = other.hour; 5022dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel time.monthDay = other.monthDay; 5122dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel time.month = other.month; 5222dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel time.year = other.year; 5322dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel time.weekDay = other.weekDay; 5422dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel time.yearDay = other.yearDay; 5522dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel time.isDst = other.isDst; 5622dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel time.gmtoff = other.gmtoff; 5722dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel } 5822dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel 5922dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel @Implementation 6022dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel public void setToNow() { 6122dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel set(System.currentTimeMillis()); 6222dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel } 6322dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel 64f798c4cd7ba4400e26f7c8cc74ce7e8a86d0b053roflharrison 65f798c4cd7ba4400e26f7c8cc74ce7e8a86d0b053roflharrison @Implementation 66167730cf6c09cde1a3284c90cc27ab7f02cf9a55roflharrison public static boolean isEpoch(Time time) { 67167730cf6c09cde1a3284c90cc27ab7f02cf9a55roflharrison long millis = time.toMillis(true); 68167730cf6c09cde1a3284c90cc27ab7f02cf9a55roflharrison return getJulianDay(millis, 0) == Time.EPOCH_JULIAN_DAY; 69167730cf6c09cde1a3284c90cc27ab7f02cf9a55roflharrison } 70167730cf6c09cde1a3284c90cc27ab7f02cf9a55roflharrison 71f798c4cd7ba4400e26f7c8cc74ce7e8a86d0b053roflharrison 72167730cf6c09cde1a3284c90cc27ab7f02cf9a55roflharrison @Implementation 73167730cf6c09cde1a3284c90cc27ab7f02cf9a55roflharrison public static int getJulianDay(long millis, long gmtoff) { 74167730cf6c09cde1a3284c90cc27ab7f02cf9a55roflharrison long offsetMillis = gmtoff * 1000; 75f798c4cd7ba4400e26f7c8cc74ce7e8a86d0b053roflharrison long julianDay = (millis + offsetMillis) / DAY_IN_MILLIS; 76167730cf6c09cde1a3284c90cc27ab7f02cf9a55roflharrison return (int) julianDay + Time.EPOCH_JULIAN_DAY; 77167730cf6c09cde1a3284c90cc27ab7f02cf9a55roflharrison } 78f798c4cd7ba4400e26f7c8cc74ce7e8a86d0b053roflharrison 79f798c4cd7ba4400e26f7c8cc74ce7e8a86d0b053roflharrison @Implementation 80f798c4cd7ba4400e26f7c8cc74ce7e8a86d0b053roflharrison public long setJulianDay(int julianDay) { 81167730cf6c09cde1a3284c90cc27ab7f02cf9a55roflharrison // Don't bother with the GMT offset since we don't know the correct 82167730cf6c09cde1a3284c90cc27ab7f02cf9a55roflharrison // value for the given Julian day. Just get close and then adjust 83167730cf6c09cde1a3284c90cc27ab7f02cf9a55roflharrison // the day. 84f798c4cd7ba4400e26f7c8cc74ce7e8a86d0b053roflharrison //long millis = (julianDay - EPOCH_JULIAN_DAY) * DateUtils.DAY_IN_MILLIS; 85f798c4cd7ba4400e26f7c8cc74ce7e8a86d0b053roflharrison long millis = (julianDay - Time.EPOCH_JULIAN_DAY) * DAY_IN_MILLIS; 86167730cf6c09cde1a3284c90cc27ab7f02cf9a55roflharrison set(millis); 87167730cf6c09cde1a3284c90cc27ab7f02cf9a55roflharrison 88167730cf6c09cde1a3284c90cc27ab7f02cf9a55roflharrison // Figure out how close we are to the requested Julian day. 89167730cf6c09cde1a3284c90cc27ab7f02cf9a55roflharrison // We can't be off by more than a day. 90167730cf6c09cde1a3284c90cc27ab7f02cf9a55roflharrison int approximateDay = getJulianDay(millis, time.gmtoff); 91167730cf6c09cde1a3284c90cc27ab7f02cf9a55roflharrison int diff = julianDay - approximateDay; 92167730cf6c09cde1a3284c90cc27ab7f02cf9a55roflharrison time.monthDay += diff; 93167730cf6c09cde1a3284c90cc27ab7f02cf9a55roflharrison 94167730cf6c09cde1a3284c90cc27ab7f02cf9a55roflharrison // Set the time to 12am and re-normalize. 95167730cf6c09cde1a3284c90cc27ab7f02cf9a55roflharrison time.hour = 0; 96167730cf6c09cde1a3284c90cc27ab7f02cf9a55roflharrison time.minute = 0; 97167730cf6c09cde1a3284c90cc27ab7f02cf9a55roflharrison time.second = 0; 98167730cf6c09cde1a3284c90cc27ab7f02cf9a55roflharrison millis = time.normalize(true); 99167730cf6c09cde1a3284c90cc27ab7f02cf9a55roflharrison return millis; 100167730cf6c09cde1a3284c90cc27ab7f02cf9a55roflharrison } 101f798c4cd7ba4400e26f7c8cc74ce7e8a86d0b053roflharrison 10222dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel @Implementation 10322dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel public void set(long millis) { 10422dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel Calendar c = getCalendar(); 10522dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel c.setTimeInMillis(millis); 10622dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel set( 107f798c4cd7ba4400e26f7c8cc74ce7e8a86d0b053roflharrison c.get(Calendar.SECOND), 108f798c4cd7ba4400e26f7c8cc74ce7e8a86d0b053roflharrison c.get(Calendar.MINUTE), 109f798c4cd7ba4400e26f7c8cc74ce7e8a86d0b053roflharrison c.get(Calendar.HOUR_OF_DAY), 110f798c4cd7ba4400e26f7c8cc74ce7e8a86d0b053roflharrison c.get(Calendar.DAY_OF_MONTH), 111f798c4cd7ba4400e26f7c8cc74ce7e8a86d0b053roflharrison c.get(Calendar.MONTH), 112f798c4cd7ba4400e26f7c8cc74ce7e8a86d0b053roflharrison c.get(Calendar.YEAR) 11322dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel ); 11422dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel } 11522dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel 11622dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel @Implementation 11722dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel public long toMillis(boolean ignoreDst) { 11822dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel Calendar c = getCalendar(); 11922dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel return c.getTimeInMillis(); 12022dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel } 12122dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel 12222dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel @Implementation 12322dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel public void set(int second, int minute, int hour, int monthDay, int month, int year) { 12422dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel time.second = second; 12522dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel time.minute = minute; 12622dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel time.hour = hour; 12722dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel time.monthDay = monthDay; 12822dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel time.month = month; 12922dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel time.year = year; 13022dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel time.weekDay = 0; 13122dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel time.yearDay = 0; 13222dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel time.isDst = -1; 13322dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel time.gmtoff = 0; 13422dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel } 13522dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel 13622dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel @Implementation 13722dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel public void set(int monthDay, int month, int year) { 13822dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel set(0, 0, 0, monthDay, month, year); 13922dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel } 14022dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel 14122dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel @Implementation 14222dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel public void clear(String timezone) { 14322dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel if (timezone == null) { 14422dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel throw new NullPointerException("timezone is null!"); 14522dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel } 14622dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel time.timezone = timezone; 14722dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel time.allDay = false; 14822dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel time.second = 0; 14922dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel time.minute = 0; 15022dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel time.hour = 0; 15122dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel time.monthDay = 0; 15222dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel time.month = 0; 15322dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel time.year = 0; 15422dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel time.weekDay = 0; 15522dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel time.yearDay = 0; 15622dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel time.gmtoff = 0; 15722dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel time.isDst = -1; 15822dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel } 15922dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel 16022dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel @Implementation 16122dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel public static String getCurrentTimezone() { 16222dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel return TimeZone.getDefault().getID(); 16322dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel } 16422dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel 16522dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel @Implementation 16622dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel public static int compare(Time a, Time b) { 16722dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel long ams = a.toMillis(false); 16822dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel long bms = b.toMillis(false); 16922dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel if (ams == bms) { 17022dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel return 0; 17122dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel } else if (ams < bms) { 17222dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel return -1; 17322dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel } else { 17422dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel return 1; 17522dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel } 17622dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel } 17722dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel 17822dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel @Implementation 17922dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel public boolean before(Time other) { 18022dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel return Time.compare(time, other) < 0; 18122dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel } 18222dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel 18322dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel @Implementation 18422dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel public boolean after(Time other) { 18522dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel return Time.compare(time, other) > 0; 18622dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel } 18722dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel 18822dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel @Implementation 18922dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel public boolean parse(String timeString) { 19022dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel TimeZone tz; 19122dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel if (timeString.endsWith("Z")) { 19222dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel timeString = timeString.substring(0, timeString.length() - 1); 19322dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel tz = TimeZone.getTimeZone("UTC"); 19422dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel } else { 19522dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel tz = TimeZone.getTimeZone(time.timezone); 19622dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel } 197e3f746175b10f25da1be5d1bf60ee691f6f72955Jan Berkel SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd'T'HHmmss", Locale.ENGLISH); 198e3f746175b10f25da1be5d1bf60ee691f6f72955Jan Berkel SimpleDateFormat dfShort = new SimpleDateFormat("yyyyMMdd", Locale.ENGLISH); 19922dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel df.setTimeZone(tz); 20022dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel dfShort.setTimeZone(tz); 20122dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel time.timezone = tz.getID(); 20222dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel try { 20322dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel set(df.parse(timeString).getTime()); 20422dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel } catch (ParseException e) { 20522dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel try { 20622dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel set(dfShort.parse(timeString).getTime()); 20722dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel } catch (ParseException e2) { 20822dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel throwTimeFormatException(); 20922dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel } 21022dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel } 21122dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel return "UTC".equals(tz.getID()); 21222dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel } 21322dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel 21422dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel @Implementation 21522dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel public String format(String format) { 216e3f746175b10f25da1be5d1bf60ee691f6f72955Jan Berkel Strftime strftime = new Strftime(format, Locale.getDefault()); 217e3f746175b10f25da1be5d1bf60ee691f6f72955Jan Berkel strftime.setTimeZone(TimeZone.getTimeZone(time.timezone)); 218e3f746175b10f25da1be5d1bf60ee691f6f72955Jan Berkel return strftime.format(new Date(toMillis(false))); 21922dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel } 22022dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel 22122dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel @Implementation 22222dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel public String format2445() { 22322dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel return format("%Y%m%dT%H%M%S"); 22422dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel } 22522dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel 22622dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel @Implementation 22722dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel public String format3339(boolean allDay) { 22822dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel if (allDay) { 22922dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel return format("%Y-%m-%d"); 23022dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel } else if ("UTC".equals(time.timezone)) { 23122dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel return format("%Y-%m-%dT%H:%M:%S.000Z"); 23222dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel } else { 23322dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel String base = format("%Y-%m-%dT%H:%M:%S.000"); 23422dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel String sign = (time.gmtoff < 0) ? "-" : "+"; 235f798c4cd7ba4400e26f7c8cc74ce7e8a86d0b053roflharrison int offset = (int) Math.abs(time.gmtoff); 23622dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel int minutes = (offset % 3600) / 60; 23722dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel int hours = offset / 3600; 23822dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel return String.format("%s%s%02d:%02d", base, sign, hours, minutes); 23922dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel } 24022dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel } 24122dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel 24222dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel private void throwTimeFormatException() { 24322dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel try { 24422dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel Constructor<TimeFormatException> c = TimeFormatException.class.getDeclaredConstructor(); 24522dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel c.setAccessible(true); 24622dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel throw c.newInstance(); 24722dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel } catch (InvocationTargetException e) { 24822dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel throw new RuntimeException(e); 24922dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel } catch (InstantiationException e) { 25022dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel throw new RuntimeException(e); 25122dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel } catch (IllegalAccessException e) { 25222dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel throw new RuntimeException(e); 25322dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel } catch (NoSuchMethodException e) { 25422dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel throw new RuntimeException(e); 25522dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel } 25622dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel } 25722dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel 25822dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel private Calendar getCalendar() { 25922dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel Calendar c = Calendar.getInstance(TimeZone.getTimeZone(time.timezone)); 26022dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel c.set(time.year, time.month, time.monthDay, time.hour, time.minute, time.second); 26122dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel c.set(Calendar.MILLISECOND, 0); 26222dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel return c; 26322dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel } 26422dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel 26522dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel // taken from org.apache.catalina.util.Strftime.java 26622dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel // see http://javasourcecode.org/html/open-source/tomcat/tomcat-6.0.32/org/apache/catalina/util/Strftime.java.html 26722dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel /* 26822dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel * Licensed to the Apache Software Foundation (ASF) under one or more 26922dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel * contributor license agreements. See the NOTICE file distributed with 27022dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel * this work for additional information regarding copyright ownership. 27122dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel * The ASF licenses this file to You under the Apache License, Version 2.0 27222dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel * (the "License"); you may not use this file except in compliance with 27322dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel * the License. You may obtain a copy of the License at 27422dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel * 27522dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel * http://www.apache.org/licenses/LICENSE-2.0 27622dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel * 27722dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel * Unless required by applicable law or agreed to in writing, software 27822dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel * distributed under the License is distributed on an "AS IS" BASIS, 27922dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 28022dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel * See the License for the specific language governing permissions and 28122dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel * limitations under the License. 28222dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel */ 28322dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel public static class Strftime { 28422dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel protected static Properties translate; 28522dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel protected SimpleDateFormat simpleDateFormat; 28622dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel 28722dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel /** 28822dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel * Initialize our pattern translation 28922dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel */ 29022dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel static { 29122dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel translate = new Properties(); 29222dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel translate.put("a", "EEE"); 29322dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel translate.put("A", "EEEE"); 29422dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel translate.put("b", "MMM"); 29522dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel translate.put("B", "MMMM"); 29622dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel translate.put("c", "EEE MMM d HH:mm:ss yyyy"); 29722dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel 29822dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel //There's no way to specify the century in SimpleDateFormat. We don't want to hard-code 29922dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel //20 since this could be wrong for the pre-2000 files. 30022dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel //translate.put("C", "20"); 30122dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel translate.put("d", "dd"); 30222dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel translate.put("D", "MM/dd/yy"); 30322dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel translate.put("e", "dd"); //will show as '03' instead of ' 3' 30422dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel translate.put("F", "yyyy-MM-dd"); 30522dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel translate.put("g", "yy"); 30622dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel translate.put("G", "yyyy"); 30722dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel translate.put("H", "HH"); 30822dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel translate.put("h", "MMM"); 30922dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel translate.put("I", "hh"); 31022dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel translate.put("j", "DDD"); 31122dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel translate.put("k", "HH"); //will show as '07' instead of ' 7' 31222dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel translate.put("l", "hh"); //will show as '07' instead of ' 7' 31322dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel translate.put("m", "MM"); 31422dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel translate.put("M", "mm"); 31522dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel translate.put("n", "\n"); 31622dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel translate.put("p", "a"); 31722dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel translate.put("P", "a"); //will show as pm instead of PM 31822dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel translate.put("r", "hh:mm:ss a"); 31922dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel translate.put("R", "HH:mm"); 32022dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel //There's no way to specify this with SimpleDateFormat 32122dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel //translate.put("s","seconds since ecpoch"); 32222dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel translate.put("S", "ss"); 32322dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel translate.put("t", "\t"); 32422dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel translate.put("T", "HH:mm:ss"); 32522dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel //There's no way to specify this with SimpleDateFormat 32622dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel //translate.put("u","day of week ( 1-7 )"); 32722dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel 32822dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel //There's no way to specify this with SimpleDateFormat 32922dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel //translate.put("U","week in year with first sunday as first day..."); 33022dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel 33122dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel translate.put("V", "ww"); //I'm not sure this is always exactly the same 33222dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel 33322dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel //There's no way to specify this with SimpleDateFormat 33422dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel //translate.put("W","week in year with first monday as first day..."); 33522dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel 33622dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel //There's no way to specify this with SimpleDateFormat 33722dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel //translate.put("w","E"); 33822dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel translate.put("X", "HH:mm:ss"); 33922dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel translate.put("x", "MM/dd/yy"); 34022dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel translate.put("y", "yy"); 34122dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel translate.put("Y", "yyyy"); 34222dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel translate.put("Z", "z"); 34322dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel translate.put("z", "Z"); 34422dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel translate.put("%", "%"); 34522dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel } 34622dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel 34722dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel 34822dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel /** 34922dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel * Create an instance of this date formatting class 35022dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel * 35122dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel * @see #Strftime(String, Locale) 35222dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel */ 35322dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel public Strftime(String origFormat) { 35422dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel String convertedFormat = convertDateFormat(origFormat); 35522dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel simpleDateFormat = new SimpleDateFormat(convertedFormat); 35622dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel } 35722dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel 35822dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel /** 35922dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel * Create an instance of this date formatting class 36022dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel * 36122dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel * @param origFormat the strftime-style formatting string 36222dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel * @param locale the locale to use for locale-specific conversions 36322dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel */ 36422dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel public Strftime(String origFormat, Locale locale) { 36522dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel String convertedFormat = convertDateFormat(origFormat); 36622dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel simpleDateFormat = new SimpleDateFormat(convertedFormat, locale); 36722dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel } 36822dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel 36922dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel /** 37022dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel * Format the date according to the strftime-style string given in the constructor. 37122dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel * 37222dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel * @param date the date to format 37322dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel * @return the formatted date 37422dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel */ 37522dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel public String format(Date date) { 37622dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel return simpleDateFormat.format(date); 37722dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel } 37822dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel 37922dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel /** 38022dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel * Get the timezone used for formatting conversions 38122dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel * 38222dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel * @return the timezone 38322dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel */ 38422dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel public TimeZone getTimeZone() { 38522dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel return simpleDateFormat.getTimeZone(); 38622dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel } 38722dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel 38822dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel /** 38922dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel * Change the timezone used to format dates 39022dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel * 39122dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel * @see SimpleDateFormat#setTimeZone 39222dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel */ 39322dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel public void setTimeZone(TimeZone timeZone) { 39422dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel simpleDateFormat.setTimeZone(timeZone); 39522dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel } 39622dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel 39722dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel /** 39822dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel * Search the provided pattern and get the C standard 39922dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel * Date/Time formatting rules and convert them to the 40022dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel * Java equivalent. 40122dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel * 40222dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel * @param pattern The pattern to search 40322dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel * @return The modified pattern 40422dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel */ 40522dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel protected String convertDateFormat(String pattern) { 40622dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel boolean inside = false; 40722dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel boolean mark = false; 40822dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel boolean modifiedCommand = false; 40922dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel 41022dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel StringBuffer buf = new StringBuffer(); 41122dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel 41222dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel for (int i = 0; i < pattern.length(); i++) { 41322dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel char c = pattern.charAt(i); 41422dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel 41522dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel if (c == '%' && !mark) { 41622dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel mark = true; 41722dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel } else { 41822dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel if (mark) { 41922dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel if (modifiedCommand) { 42022dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel //don't do anything--we just wanted to skip a char 42122dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel modifiedCommand = false; 42222dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel mark = false; 42322dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel } else { 42422dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel inside = translateCommand(buf, pattern, i, inside); 42522dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel //It's a modifier code 42622dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel if (c == 'O' || c == 'E') { 42722dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel modifiedCommand = true; 42822dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel } else { 42922dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel mark = false; 43022dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel } 43122dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel } 43222dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel } else { 43322dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel if (!inside && c != ' ') { 43422dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel //We start a literal, which we need to quote 43522dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel buf.append("'"); 43622dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel inside = true; 43722dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel } 43822dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel 43922dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel buf.append(c); 44022dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel } 44122dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel } 44222dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel } 44322dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel 44422dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel if (buf.length() > 0) { 44522dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel char lastChar = buf.charAt(buf.length() - 1); 44622dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel 44722dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel if (lastChar != '\'' && inside) { 44822dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel buf.append('\''); 44922dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel } 45022dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel } 45122dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel return buf.toString(); 45222dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel } 45322dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel 45422dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel protected String quote(String str, boolean insideQuotes) { 45522dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel String retVal = str; 45622dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel if (!insideQuotes) { 45722dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel retVal = '\'' + retVal + '\''; 45822dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel } 45922dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel return retVal; 46022dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel } 46122dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel 46222dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel /** 46322dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel * Try to get the Java Date/Time formatting associated with 46422dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel * the C standard provided. 46522dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel * 46622dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel * @param buf The buffer 46722dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel * @param pattern The date/time pattern 46822dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel * @param index The char index 46922dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel * @param oldInside Flag value 47022dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel * @return True if new is inside buffer 47122dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel */ 47222dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel protected boolean translateCommand(StringBuffer buf, String pattern, int index, boolean oldInside) { 47322dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel char firstChar = pattern.charAt(index); 47422dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel boolean newInside = oldInside; 47522dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel 47622dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel //O and E are modifiers, they mean to present an alternative representation of the next char 47722dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel //we just handle the next char as if the O or E wasn't there 47822dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel if (firstChar == 'O' || firstChar == 'E') { 47922dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel if (index + 1 < pattern.length()) { 48022dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel newInside = translateCommand(buf, pattern, index + 1, oldInside); 48122dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel } else { 48222dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel buf.append(quote("%" + firstChar, oldInside)); 48322dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel } 48422dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel } else { 48522dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel String command = translate.getProperty(String.valueOf(firstChar)); 48622dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel 48722dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel //If we don't find a format, treat it as a literal--That's what apache does 48822dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel if (command == null) { 48922dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel buf.append(quote("%" + firstChar, oldInside)); 49022dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel } else { 49122dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel //If we were inside quotes, close the quotes 49222dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel if (oldInside) { 49322dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel buf.append('\''); 49422dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel } 49522dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel buf.append(command); 49622dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel newInside = false; 49722dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel } 49822dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel } 49922dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel return newInside; 50022dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel } 50122dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel } 50222dd87d4de604631bc6dabd1186be58dbed71929Jan Berkel} 503