EWSoftware / PDI

A Personal Data Interchange (PDI) library that implements the vCard (RFC 2426), vCalendar, and iCalendar (RFC 2445) specifications including recurrence pattern generation
Microsoft Public License
64 stars 26 forks source link

How to handle correct timezone settings? #13

Closed nhaberl closed 4 years ago

nhaberl commented 4 years ago

Hi,

I'm really struggling ... could you plaese help to get the following code running. I have some infos about classes from previous years ... HOW can I set the right timezone ? All dates are in Vienna timezone (with daylight simmertime in case), which is the local datetime.

            var c = classService.GetClassById(id);
            VCalendar cal = new VCalendar();
            VTimeZone tz = new VTimeZone();

            VEvent e = new VEvent();
            e.StartDateTime.TimeZoneDateTime = c.Start;
            e.StartDateTime.TimeZoneId = TimeZoneInfo.Local.Id;

            e.EndDateTime.TimeZoneDateTime = c.End;
            e.EndDateTime.TimeZoneId = TimeZoneInfo.Local.Id;
            e.Location.Value = c.LocationText;
            e.Summary.Value = "{0}".Fmt(c.Type);
            cal.Events.Add(e);

Some clients like Outlook work but some push the date back to UTC when editing ... So the overall goal would be to write 1 event to a overall valid ical file which is opened everywhere.

I have seen the Timezone section in the sample files but do not know how to add these!

Maybe you could also add this to the docs because I think this is one of the main purposes when using your library.

Anyway, awesome library! (too awesome for me at the moment :))

EWSoftware commented 4 years ago

The iCalendar format is well defined and won't change from client to client. If it works in Outlook but doesn't work in a different client, then the other client is handling the file differently or perhaps ignoring parts it doesn't support. If it imports correctly with the time zone but converts it to UTC and strips the time zone out when saved, more likely than not, the client application doesn't support time zones on the events when it exports them. If you have the option, try creating an event within the client application with time zone info and export it from the client application to an iCalendar file to see how it writes the event out. That should give you some idea of what its expecting when it imports one and if it keeps the time zone info when it writes it back out.

If you want to add the time zone information to the saved calendar, you'll need to load the available time zone settings into the calendar's static TimeZones property which is a collection of VTimeZone objects. Its properties correspond to the properties you see in the iCalendar files such as the time zone ID and observance rules. If any items in the calendar define a time zone, the related time zone information will be automatically written out to the saved calendar file.

The TimeZoneRegInfo class may be of help there as it shows how to build a full set of time zone info from the registry and load it into the TimeZones property. It's used in the VTimeZoneTest form in the PDIWinFormsTest demo application and is also used in the Calendar Browser demo application.

nhaberl commented 4 years ago

Thanks, so as I understand...it's a must to set the timezone collection in calendar class first and add all timezones which occur in the events.

Afzer that I can use Timezones in the event ?

So how can determine the right timezone string to set ? With respect to daylight saving time.

Do I have to set the offset value to the event start and enddate or is that calculated from timezone info in the event?

I am sorry but its really difficult to understand.

EWSoftware commented 4 years ago

If you use the TimeZoneRegInfo class as noted above, it will load the settings for all known time zones so you don't need to know specifically what may be in the events. If you set a time zone ID on an event property and that ID is present in the time zone collection, the time zone info will be written out automatically when the calendar is saved.

If you set the date/times on the event using their TimeZoneDateTime property as you are in your example above, it assumes they are in the time zone currently assigned to the object. You shouldn't need to set any other offsets. Note that if you use the date/time properties UtcDateTime or DateTimeValue it will convert the value you assign from UTC or local time based on the current time zone defined on the property. If using those two properties, it's important to set the time zone ID first. TimeZoneDateTime doesn't do any conversion as it assumes the value is in the currently defined time zone.

nhaberl commented 4 years ago

Thank you so much, but on Linux I cannot use the timezone class. Is there a way to add timezones in another way ?

Can I build these in .net natively? Or where do I get all these at runtime or is there any source to look for the exact string and settings ?

Sorry for those maybe stupid questions

Have a great day

EWSoftware commented 4 years ago

You can build them yourself. You can see how in the noted class. They only difference would be that you'd have to load them from a different data source rather than the registry such as the IANA time zone database.

A simpler approach would be to run the PDIWinFormsTest on a Windows PC, open the time zone demo form and use the Save option to save all the time zone info to a calendar file. You can then load that when your application starts up and that info will get loaded into the calendar's time zone collection so it functions the same way.

Whichever way you handle it, you'd need to keep the data source files used up to date as the time zone info changed over time.

nhaberl commented 4 years ago

Thank you so much, got it working. This link describes it pretty well.

And for the Timezone info ... as we are in .NET anyway maybe TimezonInfo would be better fit, which works also on .NET Standard