use of net.fortuna.ical4j.model.property.TzOffsetTo in project zm-mailbox by Zimbra.
the class ZoneInfo2iCalendar method toStandardComp.
private static Standard toStandardComp(Time gmtOffset, String tznameFormat) {
PropertyList props = new PropertyList();
if (tznameFormat != null && tznameFormat.length() > 0 && !tznameFormat.contains("%")) {
props.add(new TzName(iCalEscape(tznameFormat)));
}
props.add(getMsOutlookStyleDtstart());
String offset = getUtcOffset(gmtOffset);
UtcOffset utcOffset = new UtcOffset(offset);
props.add(new TzOffsetTo(utcOffset));
props.add(new TzOffsetFrom(utcOffset));
return new Standard(props);
}
use of net.fortuna.ical4j.model.property.TzOffsetTo in project zm-mailbox by Zimbra.
the class ZoneInfo2iCalendar method toVTimeZoneComp.
/**
* @param referenceDate
* @param zline1 ZoneLine for 1st rule applicable after referenceDate
* @param zline2 ZoneLine for 2nd rule applicable after referenceDate
* @param obs1 Observances corresponding to zline1
* @param vtzProps Properties to associate with the VTIMEZONE component
* @param inDaylightTime true if referenceDate falls within daylight time by the rules in zline1
* @return best timezone or null if unable to determine one.
*/
private static VTimeZone toVTimeZoneComp(Calendar referenceDate, ZoneLine zline1, ZoneLine zline2, Observances obs1, PropertyList vtzProps, boolean inDaylightTime) {
int hintYear = referenceDate.get(Calendar.YEAR);
Observance obs4zl2;
Time daylightOffset;
Time standardOffset = zline2.getGmtOff();
String tznameFormat = zline2.getAbbrevFormat();
if (zline2.hasRule()) {
RuleInfo rl2 = getRuleInfo(hintYear, zline2);
daylightOffset = (null == rl2.daylight) ? standardOffset : addTimes(standardOffset, rl2.daylight.getSave());
if (inDaylightTime) {
obs4zl2 = toObservanceComp(hintYear, rl2.standard, true, /* isStandard */
standardOffset, daylightOffset, tznameFormat);
return toVTimeZoneComp(hintYear, new Observances(obs4zl2, obs1.daylight), vtzProps);
} else {
if (null == rl2.daylight) {
return null;
}
obs4zl2 = toObservanceComp(hintYear, rl2.daylight, false, /* isStandard */
standardOffset, daylightOffset, tznameFormat);
return toVTimeZoneComp(hintYear, new Observances(obs1.std, obs4zl2), vtzProps);
}
} else if (zline2.hasSave()) {
List<String> tokens = Lists.newArrayList();
Until prevRuleEnd = zline1.getUntil();
if (zline2.hasUntil()) {
Until currRuleEnd = zline2.getUntil();
if (null == currRuleEnd) {
// Don't think this can happen
return null;
}
String fromYear;
if (prevRuleEnd != null) {
fromYear = String.format("%d", prevRuleEnd.getYear());
} else {
fromYear = String.format("%d", hintYear);
}
String toYear = String.format("%d", currRuleEnd.getYear());
// NAME
tokens.add(getObservanceName(tznameFormat, null));
// FROM
tokens.add(fromYear);
// TO
tokens.add(toYear);
// TYPE
tokens.add("-");
// IN
tokens.add(ZoneInfoParser.Month.toString(currRuleEnd.getMonth()));
// ON
tokens.add(String.format("%s", currRuleEnd.getDay().toString()));
// AT
tokens.add(String.format("%s", currRuleEnd.getTime().toString()));
// SAVE
tokens.add(zline2.getSave().toString());
// LETTER/S
tokens.add("-");
RuleLine newRule = pseudoZoneLineTokensToRuleLine(tokens, zline2);
if (null == newRule) {
return null;
}
daylightOffset = addTimes(standardOffset, zline2.getSave());
obs4zl2 = toObservanceComp(hintYear, newRule, inDaylightTime, /* need the opposite */
standardOffset, daylightOffset, tznameFormat);
if (inDaylightTime) {
return toVTimeZoneComp(hintYear, new Observances(obs4zl2, obs1.daylight), vtzProps);
} else {
return toVTimeZoneComp(hintYear, new Observances(obs1.std, obs4zl2), vtzProps);
}
} else {
if (!inDaylightTime) {
// Only reason for having a save but no until is if changing to standard time only?
return null;
}
if (prevRuleEnd == null) {
return null;
}
String fromYear = String.format("%d", prevRuleEnd.getYear());
String toYear = "max";
// NAME
tokens.add(getObservanceName(tznameFormat, null));
// FROM
tokens.add(fromYear);
// TO
tokens.add(toYear);
// TYPE
tokens.add("-");
// IN
tokens.add(ZoneInfoParser.Month.toString(prevRuleEnd.getMonth()));
// ON
tokens.add(String.format("%s", prevRuleEnd.getDay().toString()));
// AT
tokens.add(String.format("%s", prevRuleEnd.getTime().toString()));
// SAVE
tokens.add(zline2.getSave().toString());
// LETTER/S
tokens.add("-");
RuleLine newRule = pseudoZoneLineTokensToRuleLine(tokens, zline2);
if (null == newRule) {
return null;
}
daylightOffset = standardOffset;
/* random value - fix later */
;
obs4zl2 = toObservanceComp(hintYear, newRule, true, standardOffset, daylightOffset, tznameFormat);
TzOffsetFrom stdOffsetFrom = (TzOffsetFrom) obs4zl2.getProperties().getProperty(Property.TZOFFSETFROM);
TzOffsetTo stdOffsetTo = (TzOffsetTo) obs4zl2.getProperties().getProperty(Property.TZOFFSETTO);
TzOffsetTo dlOffsetTo = (TzOffsetTo) obs1.daylight.getProperties().getProperty(Property.TZOFFSETTO);
if (stdOffsetTo.equals(dlOffsetTo)) {
// New standard time is same as current daylight time - just use observance.
obs4zl2 = toStandardComp(zline2.getGmtOff(), tznameFormat);
return toVTimeZoneComp(hintYear, new Observances(obs4zl2, null), vtzProps);
}
// Make sure that the zones are consistent with each other
stdOffsetFrom.setOffset(dlOffsetTo.getOffset());
TzOffsetFrom dlOffsetFrom = (TzOffsetFrom) obs1.daylight.getProperties().getProperty(Property.TZOFFSETFROM);
dlOffsetFrom.setOffset(stdOffsetTo.getOffset());
return toVTimeZoneComp(hintYear, new Observances(obs4zl2, obs1.daylight), vtzProps);
}
}
return null;
}
use of net.fortuna.ical4j.model.property.TzOffsetTo in project zm-mailbox by Zimbra.
the class TimeZoneDefinition method getTimeZone.
/**
*
* @return the appropriate iCal4j TimeZone for this TimeZoneDefinition
*/
public TimeZone getTimeZone() {
if (theZone != null) {
return theZone;
}
if (effectiveRule == null) {
theZone = new TimeZone(0, TimeZones.UTC_ID);
return theZone;
}
if (!effectiveRule.hasDaylightSaving()) {
theZone = new TimeZone(effectiveRule.getStandardUtcOffsetMillis(), getTimezoneName());
return theZone;
}
UtcOffset stdOffset = effectiveRule.getStandardUtcOffset();
UtcOffset dlOffset = effectiveRule.getDaylightUtcOffset();
PropertyList vtzProps = new PropertyList();
TzId myTzid = new TzId(getTimezoneName());
vtzProps.add(myTzid);
VTimeZone vtz = new VTimeZone(vtzProps);
Standard stdComp = new Standard();
stdComp.getProperties().add(effectiveRule.getStandardDtStart());
stdComp.getProperties().add(effectiveRule.icalStandardRRule());
TzOffsetFrom offsetFrom = new TzOffsetFrom(dlOffset);
TzOffsetTo offsetTo = new TzOffsetTo(stdOffset);
stdComp.getProperties().add(offsetFrom);
stdComp.getProperties().add(offsetTo);
Daylight dayComp = new Daylight();
dayComp.getProperties().add(effectiveRule.getDaylightDtStart());
dayComp.getProperties().add(effectiveRule.icalDaylightRRule());
offsetFrom = new TzOffsetFrom(stdOffset);
offsetTo = new TzOffsetTo(dlOffset);
dayComp.getProperties().add(offsetFrom);
dayComp.getProperties().add(offsetTo);
vtz.getObservances().add(stdComp);
vtz.getObservances().add(dayComp);
try {
vtz.validate(true);
theZone = new TimeZone(vtz);
} catch (ValidationException e) {
if (sLog.isDebugEnabled()) {
sLog.debug("Problem with property %s - will default to UTC" + this.mpi.toString(), e);
}
theZone = new TimeZone(0, TimeZones.UTC_ID);
}
theZone = new TimeZone(vtz);
return theZone;
}
use of net.fortuna.ical4j.model.property.TzOffsetTo in project zm-mailbox by Zimbra.
the class ZoneInfo2iCalendar method toVTimeZoneComp.
/**
* @param zoneLines - Only the zoneLines related to a time zone that might be relevant from the reference date.
*/
private static VTimeZone toVTimeZoneComp(Calendar referenceDate, List<ZoneLine> zoneLines, LastModified lastModified, Set<String> tzAliases, boolean isPrimary, Integer matchScore) {
int hintYear = referenceDate.get(Calendar.YEAR);
ZoneLine zline1 = zoneLines.get(0);
PropertyList vtzProps = toVTimeZonePropertyList(zline1, lastModified, tzAliases, isPrimary, matchScore);
if (zoneLines.size() == 1) {
return toVTimeZoneComp(hintYear, toObservances(hintYear, zline1), vtzProps);
}
boolean suppressWarning = false;
// Rare to get here - generally happens for some new timezone changes in the near future.
ZoneLine zline2 = zoneLines.get(1);
Observances obs1 = toObservances(hintYear, zline1);
if (zline1.hasRule()) {
if ((null != obs1.std) && (null != obs1.daylight)) {
VTimeZone vtz = null;
vtz = toVTimeZoneComp(referenceDate, zline1, zline2, obs1, vtzProps, obs1.inDaylightTimeOnDate(referenceDate));
if (vtz != null) {
return vtz;
}
}
} else {
SimpleDateFormat format1 = new SimpleDateFormat("yyyy-MM-dd");
String fmtRefDate = format1.format(referenceDate.getTime());
if ((null != obs1.std) && (null == obs1.daylight)) {
// At reference date, only using STANDARD time
Observances obs2 = toObservances(hintYear, zline2);
if ((null != obs2.std) && (null != obs2.daylight)) {
if (obs2.inDaylightTimeOnDate(referenceDate)) {
System.err.println(String.format("1st zoneLine '%s' for '%s' only has STANDARD time.", zline1.toString(), zline1.getName()));
System.err.println(String.format("Reference date %s would be in DAYLIGHT time by rules of 2nd zoneLine '%s'", fmtRefDate, zline2.toString()));
System.err.println("Therefore, Ignoring 2nd zoneLine.");
suppressWarning = true;
} else {
TzOffsetTo oldOffsetTo = (TzOffsetTo) obs1.std.getProperties().getProperty(Property.TZOFFSETTO);
TzOffsetTo newOffsetTo = (TzOffsetTo) obs2.std.getProperties().getProperty(Property.TZOFFSETTO);
if (oldOffsetTo.equals(newOffsetTo)) {
// Standard time same by current rules and new rules - can ignore 1st zoneLine going forward
return toVTimeZoneComp(hintYear, toObservances(hintYear, zline2), vtzProps);
}
System.err.println(String.format("1st zoneLine '%s' for '%s' only has STANDARD time.", zline1.toString(), zline1.getName()));
System.err.println(String.format("Reference date %s would also be in STANDARD time by rules of 2nd zoneLine '%s'", fmtRefDate, zline2.toString()));
System.err.println(String.format("BUT OLD STANDARD has TZOFFSETTO=%s which differs from new TZOFFSETTO=%s.", oldOffsetTo.toString(), newOffsetTo.toString()));
System.err.println("Therefore, Ignoring 2nd zoneLine.");
suppressWarning = true;
}
}
}
}
if (!suppressWarning) {
System.err.println(String.format("More than 1 zoneLine for zone '%s' but unknown scenario. Using only zoneLine:\n %s", zline1.getName(), zline1.toString()));
}
return toVTimeZoneComp(hintYear, toObservances(hintYear, zline1), vtzProps);
}
use of net.fortuna.ical4j.model.property.TzOffsetTo in project zm-mailbox by Zimbra.
the class ZoneInfo2iCalendar method toObservanceComp.
private static Observance toObservanceComp(int hintYear, RuleLine rline, boolean isStandard, Time standardOffset, Time daylightOffset, String tznameFormat) {
PropertyList props = new PropertyList();
String tzname = getObservanceName(tznameFormat, rline);
if (tzname != null) {
props.add(new TzName(tzname));
}
Time at = rline.getAt();
Time onset;
switch(at.getType()) {
case STANDARD_TIME:
if (isStandard) {
// We're moving from daylight time to standard time. In iCalendar we want hh:mm:ss in
// wall clock in the pre-transition time, so it's daylight time.
// daylight = utc + daylight offset = (standard - standard offset) + daylight offset
onset = addTimes(subtractTimes(at, standardOffset), daylightOffset);
} else {
// We're moving from standard time to daylight time. In iCalendar we want hh:mm:ss in
// wall clock in the pre-transition time, so it's standard time. at is already in
// standard time.
onset = at;
}
break;
case UTC_TIME:
if (isStandard) {
// We're moving from daylight time to standard time. In iCalendar we want hh:mm:ss in
// wall clock in the pre-transition time, so it's daylight time.
// daylight = utc + daylightOffset.
onset = addTimes(at, daylightOffset);
} else {
// We're moving from standard time to daylight time. In iCalendar we want hh:mm:ss in
// wall clock in the pre-transition time, so it's standard time.
// standard = utc + standard offset.
onset = addTimes(at, standardOffset);
}
break;
default:
// WALL_TIME
// at is already in the iCalendar style.
onset = at;
break;
}
int hh = onset.getHour();
int mm = onset.getMinute();
int ss = onset.getSecond();
if (hh >= 24) {
// Hour should be between 0 and 23, but sometimes we can get 24:00:00 from the zoneinfo source.
// Since hour part in iCalendar only allows 0-23, let's approximate any time with hour >= 24 to
// 23:59:59.
hh = 23;
mm = 59;
ss = 59;
}
// YYYYMMDD fixed to 16010101 (MS Outlook style)
props.add(getDtStart(String.format("16010101T%02d%02d%02d", hh, mm, ss)));
Time toOffset, fromOffset;
if (isStandard) {
toOffset = standardOffset;
fromOffset = daylightOffset;
} else {
toOffset = daylightOffset;
fromOffset = standardOffset;
}
props.add(new TzOffsetTo(new UtcOffset(getUtcOffset(toOffset))));
props.add(new TzOffsetFrom(new UtcOffset(getUtcOffset(fromOffset))));
int month = rline.getIn();
StringBuilder rruleVal = new StringBuilder();
rruleVal.append("FREQ=YEARLY;WKST=MO;INTERVAL=1;BYMONTH=").append(month).append(";");
rruleVal.append(dayToICalRRulePart(hintYear, month, rline.getOn()));
try {
RRule rrule = new RRule(new ParameterList(), rruleVal.toString());
props.add(rrule);
} catch (ParseException e) {
}
if (isStandard) {
return new Standard(props);
} else {
return new Daylight(props);
}
}
Aggregations