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
Dan Karp
@dankarp
No problem!
Michael Angstadt
@mangstadt
@dankarp See: mangstadt/biweekly#46
Dan Karp
@dankarp
Thanks!
Dan Karp
@dankarp
I have an old iCalendar REPLY that throws an NPE when parsed.
BEGIN:VCALENDAR
METHOD:REPLY
BEGIN:VEVENT
DTSTAMP:20050317T164626Z
DTSTART:20050318T170000Z
UID:040000008200E00074C5B7101A82E00800000000A0DD17CECD2AC501000000000000000010000000DA4A35FDD8F70E4686F330A21558AF27
ATTENDEE;PARTSTAT=ACCEPTED;CN="Roland Schtroumpf":MAILTO:schtroumpf@example.com
LOCATION:866-555-3378, conf ID = 650-555-0500, passcode = 255455
DTEND:20050318T180000Z
END:VEVENT
END:VCALENDAR
It's malformed (missing a VERSION), but that shouldn't lead to an NPE.
Michael Angstadt
@mangstadt
@dankarp Thanks for the report. See my response in mangstadt/biweekly#48.
Parth
@ParthPadg
Hi @mangstadt - I've started integrating Biweekly into an Android app that I'm working on, and I've gotta say, it's a great library! Thanks so much for making an easy-to-use API!
I have one question though: it looks like the DateIterators that I can generate never actually terminate - even though I have a DTEND section under VEVENT, I still get iterator dates past the year 12,135!
I've tried both(?) ways of generating the DateIterator - either event.getRecurrenceRule().getDateIterator(event.getDateStart(), tzinfo) or event.getDateIterator(event.getDateStart(), tzinfo)
do you have any suggestions, or is there anything obvious that I'm missing?
(I can send over my sample ICal event that I'm using to test out my code, as well as my test code, if you'd like)
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"