-1

I have the following code that uses biweekly library in order to create an ical for an event in my Java application.

The ical is sent as expected with the email but it is always in GMT, I am currently trying to set it to be "America/New_York" as below but it is not working.

How can I do so?

    private String generateIcal(Appointment appointment) {
    
      ICalendar ical = new ICalendar();
      VEvent event = new VEvent();
    
      event.setDateStart(appointment.getEventStartDatetime()); //value of: 2021-01-07 01:01:00
      event.setDateEnd(appointment.getEventEndDatetime()); //value of: 2021-01-07 23:59:00
      event.setDescription(appointment.getDescription());
      event.setSummary(appointment.getTitle());
    
      ical.addEvent(event);

      String id = "America/New_York";
      TimeZone timezone = TimeZone.getTimeZone(id);

      return Biweekly.write(ical).tz(timezone, false).go();

 }

ics file contents:

BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Michael Angstadt//biweekly 0.6.5//EN
BEGIN:VTIMEZONE
TZID:America/New_York
LAST-MODIFIED:20201011T015911Z
TZURL:http://tzurl.org/zoneinfo/America/New_York
X-LIC-LOCATION:America/New_York
X-PROLEPTIC-TZNAME:LMT
BEGIN:STANDARD
TZNAME:EST
TZOFFSETFROM:-0456
TZOFFSETTO:-0500
DTSTART:18831118T120358
END:STANDARD
BEGIN:STANDARD
TZNAME:EST
TZOFFSETFROM:-0400
TZOFFSETTO:-0500
DTSTART:19181027T020000
RRULE:FREQ=YEARLY;UNTIL=19201031T060000Z;BYDAY=-1SU;BYMONTH=10
END:STANDARD
BEGIN:STANDARD
TZNAME:EST
TZOFFSETFROM:-0400
TZOFFSETTO:-0500
DTSTART:19210925T020000
RRULE:FREQ=YEARLY;UNTIL=19410928T060000Z;BYDAY=-1SU;BYMONTH=9
END:STANDARD
BEGIN:STANDARD
TZNAME:EST
TZOFFSETFROM:-0400
TZOFFSETTO:-0500
DTSTART:19450930T020000
END:STANDARD
BEGIN:STANDARD
TZNAME:EST
TZOFFSETFROM:-0400
TZOFFSETTO:-0500
DTSTART:19460929T020000
RRULE:FREQ=YEARLY;UNTIL=19540926T060000Z;BYDAY=-1SU;BYMONTH=9
END:STANDARD
BEGIN:STANDARD
TZNAME:EST
TZOFFSETFROM:-0400
TZOFFSETTO:-0500
DTSTART:19551030T020000
RRULE:FREQ=YEARLY;UNTIL=20061029T060000Z;BYDAY=-1SU;BYMONTH=10
END:STANDARD
BEGIN:STANDARD
TZNAME:EST
TZOFFSETFROM:-0400
TZOFFSETTO:-0500
DTSTART:20071104T020000
RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=11
END:STANDARD
BEGIN:DAYLIGHT
TZNAME:EDT
TZOFFSETFROM:-0500
TZOFFSETTO:-0400
DTSTART:19180331T020000
RRULE:FREQ=YEARLY;UNTIL=19200328T070000Z;BYDAY=-1SU;BYMONTH=3
END:DAYLIGHT
BEGIN:DAYLIGHT
TZNAME:EDT
TZOFFSETFROM:-0500
TZOFFSETTO:-0400
DTSTART:19210424T020000
RRULE:FREQ=YEARLY;UNTIL=19410427T070000Z;BYDAY=-1SU;BYMONTH=4
END:DAYLIGHT
BEGIN:DAYLIGHT
TZNAME:EWT
TZOFFSETFROM:-0500
TZOFFSETTO:-0400
DTSTART:19420209T020000
END:DAYLIGHT
BEGIN:DAYLIGHT
TZNAME:EPT
TZOFFSETFROM:-0400
TZOFFSETTO:-0400
DTSTART:19450814T190000
END:DAYLIGHT
BEGIN:DAYLIGHT
TZNAME:EDT
TZOFFSETFROM:-0500
TZOFFSETTO:-0400
DTSTART:19460428T020000
RRULE:FREQ=YEARLY;UNTIL=19730429T070000Z;BYDAY=-1SU;BYMONTH=4
END:DAYLIGHT
BEGIN:DAYLIGHT
TZNAME:EDT
TZOFFSETFROM:-0500
TZOFFSETTO:-0400
DTSTART:19740106T020000
RDATE:19750223T020000
END:DAYLIGHT
BEGIN:DAYLIGHT
TZNAME:EDT
TZOFFSETFROM:-0500
TZOFFSETTO:-0400
DTSTART:19760425T020000
RRULE:FREQ=YEARLY;UNTIL=19860427T070000Z;BYDAY=-1SU;BYMONTH=4
END:DAYLIGHT
BEGIN:DAYLIGHT
TZNAME:EDT
TZOFFSETFROM:-0500
TZOFFSETTO:-0400
DTSTART:19870405T020000
RRULE:FREQ=YEARLY;UNTIL=20060402T070000Z;BYDAY=1SU;BYMONTH=4
END:DAYLIGHT
BEGIN:DAYLIGHT
TZNAME:EDT
TZOFFSETFROM:-0500
TZOFFSETTO:-0400
DTSTART:20070311T020000
RRULE:FREQ=YEARLY;BYDAY=2SU;BYMONTH=3
END:DAYLIGHT
END:VTIMEZONE
BEGIN:VEVENT
UID:c59d5d8b-884a-4467-a80b-6eed29e8c94f
DTSTAMP:20210106T092518Z
DTSTART;TZID=America/New_York:20210106T200100
DTEND;TZID=America/New_York:20210107T185900
DESCRIPTION: test event
SUMMARY: test Summary
END:VEVENT
END:VCALENDAR

Gmail Invite:

Note that the below is showing the invite as 1.01am in my local time (GMT) but it should actually be showing 1.01am + 5 hours as GMT is 5 hours ahead of New York timezone.

enter image description here

java12399900
  • 1,485
  • 7
  • 26
  • 56
  • "DTSTART;TZID=America/New_York:20210106T200100" - that's 8:01pm New York time, which is 1:01am GMT, exactly as I'd expect it to be. It sounds like you *expected* it to be 1:01am in New York time, but that's not what your ICS file shows. We don't know what `appointment.getEventStartDatetime()` is, which doesn't help. – Jon Skeet Jan 06 '21 at 18:54
  • Yeah I am expecting that the ICal will show 1.01am in New York time. I have now updated my code to show what the values of the start and end time are, I am just confused why the start time is showing as my 1.01 my local time (GMT) rather than New York time. thanks – java12399900 Jan 06 '21 at 19:00
  • What is the *type* of `appointment.getEventStartDatetime()`? (I don't know the iCalendar library well.) Likewise what are the types involved in `Biweekly.write(ical).tz(timezone, false)`? – Jon Skeet Jan 06 '21 at 19:16
  • It would be nice to have a [mcve] for this - a simple console app that doesn't require any user input, but outputs the iCal entry (on the console). That would make it easier to reproduce the problem. It does look like the gmail invite is behaving correctly given the iCal entry. – Jon Skeet Jan 06 '21 at 19:21
  • getEventStartDateTime returns a standard Java Date, Biweekly.write(ical) returns a ChainingTextWriter which then calls the .tz() method. This can se seen here: http://mangstadt.github.io/biweekly/javadocs/0.6.1/index.html?biweekly/io/chain/ChainingTextWriter.html – java12399900 Jan 06 '21 at 19:22
  • I am not understanding how gmail is behaving correctly? As the I set the ical to have a start time of 1.01 in New York time...but it shows in gmail as 1.01am in GMT? – java12399900 Jan 06 '21 at 19:25
  • "getEventStartDateTime returns a standard Java Date" - okay, that's a big problem to start with, given that `java.util.Date` represents an *instant in time*. No time zone, no notion of "this is a local time". So I'd be interested in what "value of: 2021-01-07 01:01:00" really means here. (Of course, it would be best if you could avoid `java.util.Date` entirely, but I understand that's unlikely to be feasible.) – Jon Skeet Jan 06 '21 at 19:41
  • "As the I set the ical to have a start time of 1.01 in New York time" - you didn't. Look at the ICS file. It specifically says it's 8:01pm in New York time. So your ICS file doesn't say what you want it to say - I'd suggest working out what the ICS file *should* say, and focus on that, taking gmail out of the equation. – Jon Skeet Jan 06 '21 at 19:43
  • Sorry I think I am not explaining very well. I expect that my ical invite /ICS file should show 1.01 start time in New York time and 6.01am in GMT (i.e. 5 hours ahead). I also believe that getEventStartDateTime is supposed to represent GMT. – java12399900 Jan 06 '21 at 20:02
  • "I also believe that getEventStartDateTime is supposed to represent GMT" - if it's returning a `java.util.Date`, it represents an instant in time, not in any time zone. But yes, if you want your event to represent 1:01am in New York, the ICS file should show that - which is why I said that gmail is doing the right thing (given the data), and it's the ICS file that's wrong. – Jon Skeet Jan 06 '21 at 21:41
  • OK thanks, what I am not understanding is how the ical is being generated with a time of 8.01pm New York time whenever I have set the start time to be 1.01am in New York time. – java12399900 Jan 07 '21 at 10:23
  • Well that's the question, really - and that's where a [mcve] would help so that we can know exactly what's going on. We still don't know what you mean by "value of: 2021-01-07 01:01:00", or what instant in time the `java.util.Date` you're using represents. – Jon Skeet Jan 07 '21 at 11:56
  • the instant in time the date I am using is 2021-01-07 01:01:00 in the New York time zone. – java12399900 Jan 07 '21 at 12:41
  • That's certainly what you *intend* to set, but I see nothing that gives me confidence of that. There's no concrete evidence for it. If you log `appointment.getEventStartDatetime().getTime()` what does that show? – Jon Skeet Jan 07 '21 at 12:48
  • it gives 2021-01-07 01:01:00 – java12399900 Jan 07 '21 at 12:59
  • Not if it's a java.util.Date it won't. `Date.getTime()` returns a `long`. Again, please just provide us with a [mcve]. At this point I've asked for that (and other simple information) that I'm just giving up. Good luck. – Jon Skeet Jan 07 '21 at 14:23

2 Answers2

1

You can use the tz method in the chaining API to set a default output timezone for all your properties.

ICalendar ical = ...
String id = "America/New_York";
TimeZone timezone = TimeZone.getTimeZone(id);
Biweekly.write(ical).tz(timezone, false).go(System.out);
Michael
  • 34,873
  • 17
  • 75
  • 109
  • I have tried this but I am getting the same issue with timezone always coming as GMT? I have updated my code above – java12399900 Jan 06 '21 at 09:24
  • I have also added the ics file contents, note that I am using google chrome for this. – java12399900 Jan 06 '21 at 09:31
  • @java12399900 I don't see what the issue is? The output you included in your edited answer looks correct to me. The DTSTART and DTEND properties are assigned to the Americal/New_York timezone definition. – Michael Jan 06 '21 at 14:18
  • I noticed that also, but I have now added a screenshot of the event invite that comes to Gmail, notice that it is in GMT? Appreciate the help on this as I know you are the Library creator :) – java12399900 Jan 06 '21 at 17:11
  • Please see my reply also to Jon Skeets comment, it will explain further what I mean. – java12399900 Jan 06 '21 at 19:05
  • Can I just check, when I do event.setDateStart() - does biweekly assume that this is a GMT time? – java12399900 Jan 06 '21 at 20:12
  • @java12399900 It all depends upon how you are creating the "java.util.Date" object that you are passing into the setDateStart() method. Internally, the Java's Date object represents its value in UTC time. When you call Date.toString() (i.e. when you pass the Date object to System.out.println), what Java does in the background is convert that internal UTC timestamp to your local timezone. Biweekly does something similar. It creates the DTSTART property value based on the timezone you pass to biweekly. Does that make sense? – Michael Jan 07 '21 at 00:13
  • ok so it will set the time in my case to be 8.01pm in NYC time? – java12399900 Jan 07 '21 at 10:05
  • Ok, so in my case then how can I make biweekly create the ical with a start time of 1.01am in New York time rather than 8.01pm? – java12399900 Jan 07 '21 at 10:21
  • This is pretty basic Java programming we're talking about here :-P Here is your answer for you: LocalDateTime t = LocalDateTime.of(2021, 1, 7, 1, 0, 0); ZonedDateTime z = t.atZone(ZoneId.of("America/New_York")); Date d = Date.from(z.toInstant()); – Michael Jan 07 '21 at 14:09
0

The invite is set to :

DTSTART;TZID=America/New_York:20210106T200100
DTEND;TZID=America/New_York:20210107T185900

This states that the event runs from 8:01pm in New York. The time zone you've set up for America/New_York has an offset of -500 so what this is saying is this time of 20210107T185900 is offset by -500 (5 hours behind UTC).

You're then opening the invite in your Gmail calendar which is converting it to the GMT time zone automatically (based on your local computers date time settings). which is why it's showing as 1:01am (GMT).

Dizzy
  • 448
  • 5
  • 15