Home > Enterprise >  Java Mail invite attachment issue with time zone
Java Mail invite attachment issue with time zone

Time:11-10

beginner here but Im using this example to send a java email invite. If you look at the last example in that link I have that working in my Spring CRUD app when a User creates a meeting an email gets sent with the meeting details and everything is good. The dateTime that is entered is correct in the database, however, the meeting invite is always 1 hour later than entered. I understand it has something to do with TimeZones but looking at the code I have no idea where to begin. So what do I have to change to set the daylight savings time for Berlin Germany?

Heres the code:

public class Index {

public static void main(String[] args) {

     try {
            final String username = "[email protected]";
            final String password = "xxxxx";
            
            String from = "[email protected]";
            String to = "[email protected]";
            String subject = "Meeting Subject";
            String startDate = "20201208"; // Date Formate: YYYYMMDD
            String endDate = "20201208"; // Date Formate: YYYYMMDD
            String startTime = "0400"; // Time Formate: HHMM
            String endTime = "0600"; // Time Formate: HHMM
            String emailBody = "Hi Team, This is meeting description. Thanks"; 
            
            Properties prop = new Properties();
            prop.put("mail.smtp.auth", "true");
            prop.put("mail.smtp.starttls.enable", "true");
            prop.put("mail.smtp.host", "smtp.gmail.com");
            prop.put("mail.smtp.port", "25");

            Session session = Session.getDefaultInstance(prop,  new javax.mail.Authenticator() {
                protected PasswordAuthentication getPasswordAuthentication() {
                    return new PasswordAuthentication(username, password);
                }
              });
            
            MimeMessage message = new MimeMessage(session);
            message.addHeaderLine("method=REQUEST");
            message.addHeaderLine("charset=UTF-8");
            message.addHeaderLine("component=VEVENT");

            message.setFrom(new InternetAddress(from, "New Outlook Event"));
            message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
            message.setSubject(subject);

            StringBuffer sb = new StringBuffer();

            StringBuffer buffer = sb.append("BEGIN:VCALENDAR\n"  
                    "PRODID:-//Microsoft Corporation//Outlook 9.0 MIMEDIR//EN\n"  
                    "VERSION:2.0\n"  
                    "METHOD:REQUEST\n"  
                    "BEGIN:VEVENT\n"  
                    "ATTENDEE;ROLE=REQ-PARTICIPANT;RSVP=TRUE:MAILTO:"  to  "\n"  
                    "DTSTART:"  startDate  "T"  startTime  "00Z\n"  
                    "DTEND:"  endDate  "T"  endTime  "00Z\n"  
                    "LOCATION:Conference room\n"  
                    "TRANSP:OPAQUE\n"  
                    "SEQUENCE:0\n"  
                    "UID:040000008200E00074C5B7101A82E00800000000002FF466CE3AC5010000000000000000100\n"  
                    " 000004377FE5C37984842BF9440448399EB02\n"  
                    "CATEGORIES:Meeting\n"  
                    "DESCRIPTION:"  emailBody  "\n\n"  
                    "SUMMARY:Test meeting request\n"  
                    "PRIORITY:5\n"  
                    "CLASS:PUBLIC\n"  
                    "BEGIN:VALARM\n"  
                    "TRIGGER:PT1440M\n"  
                    "ACTION:DISPLAY\n"  
                    "DESCRIPTION:Reminder\n"  
                    "END:VALARM\n"  
                    "END:VEVENT\n"  
                    "END:VCALENDAR");

            // Create the message part
            BodyPart messageBodyPart = new MimeBodyPart();

            // Fill the message
            messageBodyPart.setHeader("Content-Class", "urn:content-classes:calendarmessage");
            messageBodyPart.setHeader("Content-ID", "calendar_message");
            messageBodyPart.setDataHandler(new DataHandler(
                    new ByteArrayDataSource(buffer.toString(), "text/calendar")));// very important

            // Create a Multipart
            Multipart multipart = new MimeMultipart();

            // Add part one
            multipart.addBodyPart(messageBodyPart);

            // Put parts in message
            message.setContent(multipart);

            // send message
            Transport.send(message);
            
            System.out.println("Email sent!");
        } catch (MessagingException me) {
            me.printStackTrace();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
}
}

CodePudding user response:

The problem is that both DTSTART and DTEND are being pinned to UTC (as they end with the Z character).

Here's an excerpt from the original RFC:

  Example:  The following represents July 14, 1997, at 1:30 PM in New
  York City in each of the three time formats, using the "DTSTART"
  property.

   DTSTART:19970714T133000                   ; Local time
   DTSTART:19970714T173000Z                  ; UTC time
   DTSTART;TZID=America/New_York:19970714T133000
                                             ; Local time and time
                                             ; zone reference

Here is some Java code for both local and timezone supplied start dates:

final var start = ZonedDateTime.of(LocalDate.of(2020, Month.DECEMBER, 8), LocalTime.of(4, 0), ZoneId.of("Europe/Berlin"));
final var startDateString = DateTimeFormatter.ofPattern("yyyyMMdd'T'HHmmss").format(start);

// local date
System.out.println(String.format("DTSTART:%s%n", startDateString));

// timezone specified
System.out.println(String.format("DTSTART;TZID=%s:%s%n", start.getZone().getId(), startDateString));

DISCLAIMER: I've not tested the above, but it provides a starting point.

  • Related