Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • Nov 06 14:48
    mangstadt closed #115
  • Nov 06 14:48
    mangstadt closed #117
  • Nov 06 14:47
    mangstadt closed #118
  • Oct 22 05:12
    M66B closed #121
  • Oct 22 05:12
    M66B commented #121
  • Oct 21 22:04
    mangstadt commented #121
  • Oct 19 12:50
    M66B opened #121
  • Sep 08 14:37
    mangstadt commented #120
  • Sep 06 09:02
    demanzano closed #120
  • Sep 06 09:02
    demanzano commented #120
  • Sep 06 06:39
    demanzano opened #120
  • Aug 05 12:56
    tarkal closed #119
  • Jul 26 13:38
    tarkal opened #119
  • Jul 07 14:21
    darku77 commented #118
  • Jun 30 00:49
    mangstadt commented #117
  • Jun 28 17:36
    tjmorgan0 commented #117
  • Jun 25 14:20
    mangstadt closed #116
  • Jun 25 14:20
    mangstadt commented #116
  • Jun 25 14:20

    mangstadt on master

    Update jackson dependency to la… (compare)

  • Jun 25 14:04
    mangstadt commented #118
Parth
@ParthPadg
FYI - my current workaround is that I created a wrapper Iterator that checks each Date returned, validating that it's before the DTEND specified.
Parth
@ParthPadg
Well, now I feel stupid. I realized that my recurrence rule didn't have an UNTIL specified - so of course the DateIterator will be infinite!
Sorry for the spam - thanks again for the awesome library! :D
(PS - can't wait until timezone info is included inside the ICalendar object! Maybe having a JodaTime plugin, which would allow you to make the DateStart/End objects contain a DateTime, which knows about timezones?)
Michael Angstadt
@mangstadt
@ParthPadg Thanks for the compliments! I'm glad you like biweekly. There's always the potential for migrating to Java 1.8 and using Java's updated date/time API as well.
Parth
@ParthPadg

@mangstadt RE migrating to Java 1.8, what would that mean for Android Lollipop/Marshmallow support? Currently, only Android N supports 1.8 syntax.

One more question - if I wanted to use Biweekly to parse solely an RRULE, do you have any suggestions in regards to using the RecurrenceRuleScribe?
I'm currently initializing the Scribe using whatever compiles, which looks something like this:

RecurrenceRuleScribe scribe = new RecurrenceRuleScribe();
ParseContext pc = new ParseContext();
pc.setVersion(ICalVersion.V2_0);
ICalParameters icp = new ICalParameters();
RecurrenceRule rrule = scribe.parseText("FREQ=WEEKLY;BYDAY=MO,WE,FR", null, icp, pc);

Is there a better way to be doing this?

Michael Angstadt
@mangstadt
@ParthPadg Hmm, good point about Android. It's not just the syntax but the API as well. Only Java 1.8 has the new date/time API.
@ParthPadg Yes, you are initializing the RecurrenceRuleScribe correctly.
Parth
@ParthPadg

@mangstadt hopefully the last question for you!

I'm using RecurrenceRule.getDateIterator(startDate, timezone), and it's exhibiting the very expected behavior of "remembering" the last Date that it spat out. However, if I want to repeatedly check from the "beginning" (like, if the user exits a screen and comes back, and I need to show the first date again, etc.), is there a way to "reset" the DateIterator? I've tried DateIterator.advanceTo(Date), but that ignores the input if input < current.
Am I stuck with just calling RecurrenceRule.getDateIterator(startDate, timezone) every time I need to reset?

Michael Angstadt
@mangstadt
@ParthPadg Yes, you'll just have to call getDateIterator() again. There's no way to "reset" the iterator.
Parth
@ParthPadg

@mangstadt I know I've been asking a lot of questions, and I apologize!

But I think I've found a small bug in the DateIterable created from DateIteratorFactory.createDateIterable(String, Date, TimeZone, boolean).
The bug is: if I create a DateIterable with a Date (e.g., July 17, 2016 @ 14:00) and timezone=PDT, the DateIterable doesn't entirely respect the timezone I input -- it spits out a Date with UTC time (e.g., July 19, 2016 @ 21:00). The workaround is to initialize the DateIterable with UTC time, but it isn't readily apparent that that's what a user should do.

I've written a small script that reproduces this issue (see below). I originally wrote it using org.joda.DateTime objects, but someone pointed out that I should use java.util.Date to reduce confounding variables. Let me know if I'm doing anything funky as a result - I don't use java.util.Date much.

I suspect that one of the issues is in DateIteratorFactory#dateToDateValue(Date, boolean), but it might be deeper in the iterator generator code. (I also realize that this is code ported from Google's RFC2445 lib, so feel free to tell me that this isn't your problem anymore :) )

Script that repros this issue:

TimeZone timezone_pdt = TimeZone.getTimeZone("America/Los_Angeles");
Date startDate = new Date(2016, 7, 17, 14, 0, 0);

DateIterable workaroundIterable = DateIteratorFactory.createDateIterable("RRULE:FREQ=WEEKLY;BYDAY=TU", startDate, DateTimeZone.UTC.toTimeZone(), true);
DateIterable PDTInitializedIterable = DateIteratorFactory.createDateIterable("RRULE:FREQ=WEEKLY;BYDAY=TU", startDate, timezone_pdt, true);

int count = 3;

SimpleDateFormat sdf_pdt = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz");
sdf_pdt.setTimeZone(timezone_pdt);

SimpleDateFormat sdf_default = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz");

for (DateIterator pdtIter = PDTInitializedIterable.iterator(), workaroundIter = workaroundIterable.iterator(); pdtIter.hasNext() && workaroundIter.hasNext();) {
    Date pdtNext = pdtIter.next();
    Date utcNext = workaroundIter.next();
    System.out.println("Next PDT-initialized-iterable time: \t" + sdf_pdt.format(pdtNext)); // should be "14:00:00 PDT", but is "...21:00:00 PDT"
    System.out.println("Next workaround-created time: \t\t" + sdf_default.format(utcNext));
    System.out.println();

    if (--count == 0)
        break;
}

Output:

Next PDT-initialized-iterable time:     Thu Aug 17 21:00:00 PDT
Next workaround-created time:         Thu Aug 17 14:00:00 PDT

Next PDT-initialized-iterable time:     Tue Aug 22 21:00:00 PDT
Next workaround-created time:         Tue Aug 22 14:00:00 PDT

Next PDT-initialized-iterable time:     Tue Aug 29 21:00:00 PDT
Next workaround-created time:         Tue Aug 29 14:00:00 PDT
Michael Angstadt
@mangstadt
@ParthPadg Thank you for the report. If I recall correctly, other people have noticed this issue as well. Fortunately, biweekly does not call this method.
Does this code work correctly for you?
TimeZone timezone_pdt = TimeZone.getTimeZone("America/Los_Angeles");
TimeZone.setDefault(timezone_pdt);

Calendar c = Calendar.getInstance();
c.clear();
c.set(Calendar.YEAR, 2016);
c.set(Calendar.MONTH, Calendar.AUGUST);
c.set(Calendar.DATE, 17);
c.set(Calendar.HOUR_OF_DAY, 14);
Date start = c.getTime();

Recurrence recur = new Recurrence.Builder(Frequency.WEEKLY).byDay(DayOfWeek.TUESDAY).build();
RecurrenceRule rrule = new RecurrenceRule(recur);

DateIterator it = rrule.getDateIterator(start, timezone_pdt);
int count = 3;
while (--count >= 0) {
    System.out.println(it.next());
}
Parth
@ParthPadg

@mangstadt I believe that does work -- I was using it previously.
The reason why I switched to DateIteratorFactory.getDateIterable() is because it returns a DateIterable, which allows me to create a new Iterator instance upon every call to iterator(). Especially when using enhanced for-each syntax, it's then easy to ensure that we don't cache/reuse an old instance of the DateIterator.

Of course, the other workaround it just to pass the createDateIterable() method a UTC timezone, which is easy enough to do.

Either way, figured I'd send the bug report your way. Thanks for finding another workaround! :)

Michael Angstadt
@mangstadt
@ParthPadg Thanks again for reporting this issue. This issue has been reported previously in mangstadt/biweekly#16. I created a mangstadt/biweekly#51 based on our conversation. Thanks again!
Parth
@ParthPadg
@mangstadt sorry, I was on vacation so I didn't respond sooner. Thanks for creating the issue and for creating such an awesome library! :)
Michael Angstadt
@mangstadt
Thank you, @ParthPadg!
Naftoli Gugenheim
@nafg
Hi, just used Biweekly to write an email attachment in an app, so thanks for the library
Naftoli Gugenheim
@nafg
I was wondering though, why the API is so full of indirection... e.g. DateStart wraps an ICalDate which both wraps and extends java.util.Date, similar for Priority
Michael Angstadt
@mangstadt
@nafg Well, DateStart is a property, so it has to contain not only a value, but also parameters. And the ICalDate object is needed because biweekly needs a way to tell if a Date has a time component or not.
Naftoli Gugenheim
@nafg
Why not just the latter? What do you mean by parameters?
Michael Angstadt
@mangstadt
@nafg For example: DTSTART;X-FOO=bar:20160811
Naftoli Gugenheim
@nafg
Ah, I guess "property" is an ical term
Ok thanks for the info
Michael Angstadt
@mangstadt
@nafg No problem. Feel free to post here if you have any other questions.
Simon Harrer
@simonharrer
Hi. I am creating an event with an alarm, but Outlook does not recognize the alarm. Is this a known issue?
Michael Angstadt
@mangstadt
@simonharrer Mmm not that I know of. What does your alarm look like?
Simon Harrer
@simonharrer
Duration duration = Duration.builder().prior(true).days(1).build();
Trigger trigger = new Trigger(duration, Related.START);
VAlarm alarm = VAlarm.display(trigger, "Text");
event.addAlarm(alarm);

generates

BEGIN:VALARM
ACTION:DISPLAY
TRIGGER;RELATED=START:-P1D
DESCRIPTION:Text
END:VALARM

which is not recognized by Outlook or Google Calendar.

Can this be related to the fact that the VEVENT is a full day event?
Michael Angstadt
@mangstadt
@simonharrer I don't see why an alarm wouldn't work for a full day event. Can you post the full iCal file?
Simon Harrer
@simonharrer
BEGIN:VCALENDAR
VERSION:2.0
PRODID:Abfuhrkalender Bamberg
NAME:Abfuhrkalender Bamberg 2016 für Bischberg (Landkreis Bamberg)
DESCRIPTION:Abfuhrkalender Bamberg 2016 für Bischberg (Landkreis Bamberg)
LAST-MODIFIED:20151101T230000Z
BEGIN:VTIMEZONE
TZID:Europe/Berlin
TZURL:http://tzurl.org/zoneinfo-outlook/Europe/Berlin
X-LIC-LOCATION:Europe/Berlin
BEGIN:DAYLIGHT
TZOFFSETFROM:+0100
TZOFFSETTO:+0200
TZNAME:CEST
DTSTART:19700329T020000
RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=3
END:DAYLIGHT
BEGIN:STANDARD
TZOFFSETFROM:+0200
TZOFFSETTO:+0100
TZNAME:CET
DTSTART:19701025T030000
RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
END:STANDARD
END:VTIMEZONE
BEGIN:VEVENT
UID:4c07611b-aa55-434e-bd22-06dbcbac2c86
DTSTAMP:20160925T094922Z
LAST-MODIFIED:20151101T230000Z
CREATED:20151101T230000Z
SUMMARY;LANGUAGE=de-de:BIO
LOCATION:Bischberg\, Landkreis Bamberg
DTSTART;VALUE=DATE:20160102
BEGIN:VALARM
ACTION:DISPLAY
TRIGGER;RELATED=START:-P1D
DESCRIPTION:Morgen wird der BIO abgeholt!
END:VALARM
END:VEVENT
END:VCALENDAR
Michael Angstadt
@mangstadt
@simonharrer Your iCal file looks good. I did a quick web search and found some people who reported that Google Calendar and Outlook will not import the alarms in iCal files. It's certainly possible that Google and Microsoft have disabled this for security reasons. http://stackoverflow.com/questions/7393774/ics-alarms-are-not-appearing-in-google-calendar-or-outlook
The iCal specification has a warning about how you should be careful about accepting alarms from untrusted sources: "Note: Implementations should carefully consider whether they accept alarm components from untrusted sources, e.g., when importing calendar objects from external sources. One reasonable policy is to always ignore alarm components that the calendar user has not set herself, or at least ask for confirmation in such a case."
Simon Harrer
@simonharrer
Thank you!
Dan Karp
@dankarp
When a VALARM has a TRIGGER that goes off at the start of the event, biweekly's VAlarm.getTrigger() returns null. This seems like a really bad idea.
e.g.
BEGIN:VALARM
ACTION:DISPLAY
DESCRIPTION:REMINDER
TRIGGER;RELATED=START:+PT00H00M00S
END:VALARM
Michael Angstadt
@mangstadt
Thanks @dankarp. This was happening because the period value begins with "+". biweekly was incorrectly treating this as an error. See: mangstadt/biweekly#58
amitvaswani
@amitvaswani
Hi, I am trying to create a rest api that will generate ics file, can anyone please show some pointers on how to achieve this using biweekly
Marco Rodriguez-Suarez
@marcoRS
Hey guys, I hope youre all well. I'm trying to figure out if theres a way to grab an RRule as a string. I've tried something simple as recurrence.toString() and recurrenceRule.toString() but that returns object info.
Marco Rodriguez-Suarez
@marcoRS
So a string of the form "FREQ=WEEKLY;INTERVAL=2"
Michael Angstadt
@mangstadt
Hi @marcoRS. I just added the solution to the FAQ page. May I ask: why do you need to do this? A few other people have asked about this as well.
Marco Rodriguez-Suarez
@marcoRS
The project I'm working on has a slightly different use case from the ical structure but we are using the RRules within our data structure. I need to be able to parse these to fill in a calendar and also to update.
Marco Rodriguez-Suarez
@marcoRS
Does anyone have proguard rules for BiWeekly? I'm getting a bit of proguard errors related to JCalDeserializer
Marco Rodriguez-Suarez
@marcoRS
@mangstadt Does BiWeekly have support for EXDATE when parsing an rrule string? I noticed Recurrence.Builder has a xrule method but when I add an EXDATE and I'm parsing the rule for relevant dates the EXDATE seems to be ignored.
Michael Angstadt
@mangstadt
@marcoRS EXDATE is a separate property. You cannot define exclusion dates within the RRULE property. You might want to check out the VEvent.getDateIterator() method. It combines all the RRULE and EXDATE properties to give you a single date iterator.
Nils Kilden-Pedersen
@nilskp
Hi. Quick question: Why should I use biweekly over ical4j? What was the motivation for creating biweekly? Presumably it solves some issue(s) with ical4j?
Michael Angstadt
@mangstadt
@nilskp I created biweekly because I didn't like the way the ical4j codebase was organized. It was also fairly easy for me to get the project started because I could base it on my ez-vcard project (the vCard and iCalendar file formats are very similar). One benefit to using biweekly over ical4j is that it is more memory efficient. From what I understand, ical4j cannot handle large iCalendar files very well because it has to read the entire file into memory before it can process it. Biweekly streams the data, which means it requires much less memory. Hope that answers your question!
Nils Kilden-Pedersen
@nilskp
@mangstadt thanks! :+1:
Michael Angstadt
@mangstadt
No problem!
Simon Harrer
@simonharrer
Hi. I was fighting with the reuccurrences. In my calendar, there are dates that occur every two weeks, but once and a while, one day is off that bi-weekly schedule. How can I still get the recurrence setting so that the user sees that they are related? I was wondering if I can use the RecurrenceId for that? But I have not found any examples or anything in the documentation. Any idea how I can proceed?
Michael Angstadt
@mangstadt
@simonharrer You should be able to add an EXDATE (exception date) property to the VEVENT component. This property specifies individual dates that are to be excluded from the recurrence rule.