I will make one assumption, you meant "...in Eastern Time every week for the entire year". When you say EST, you are specifically referring to Eastern Standard Time. When DST is applicable, it is known as Eastern Daylight Time (EDT).
Also, abbreviations are not a good way to identify time zones. How I would I know you meant EST in the United States (UTC-5) and not EST in Australia (UTC+10)? Abbreviations are ambiguous. You can see a fairly comprehensive list here.
The first thing to do is to decide how you want to identify the user's time zone. There are two databases in common use:
The Microsoft Time Zone Database
PROs
- Built in to Windows operating system.
- Updates deployed automatically through Windows Update.
- Easy to consume from Win32 or .Net Framework.
CONs
- Maintained by Microsoft instead of a standards body or community.
- Zones tend to be very broad instead of refined.
- Not good with historical time zone changes.
- Interoperability with non-Microsoft servers can be painful.
- Updated less frequently.
The IANA/Olson Time Zone Database
PROs
- Widely implemented on Linux, Mac, Java, PHP, and many other platforms.
- Libraries are available for JavaScript and for Windows/.Net.
- Refined, distinct time zones named from an exemplar city.
- Contains historical data for time zone changes.
- Referenced in many RFCs and other standards.
- Community maintained, recently backed by IANA.
- Frequent updates, several times a year.
CONs
- Not usually maintained automatically, although some implementations may do so.
- There are so many zones, it can be difficult to present a simple drop-down list to your users. Map-based timezone pickers, such as this one, are needed for a good user experience.
Now that you have identified which time zone your user is in - let's get to the heart of your original question. How should you deal with a recurring event that is at the same local time without regard to DST changes?
You actually have two different concerns, persistence and execution.
For persistence (and transport, display, etc.) you need to store a combined local time and time zone. For example, 8:00 PM in the America/New_York
IANA zone. If possible in your framework, store this time without a date component. Don't convert it to UTC or try to adjust it for DST. You are simply capturing the users intent in the way they have expressed it to you.
For execution, you need to fire your recurring job at a specific scheduled time. The server your job is running on might be in a different time zone entirely. What you need is a series of UTC DateTime values, so you can set a task scheduler to fire at specific moments in instantaneous time. You might also use a local-time-plus-utc-offset for this, such as a DateTimeOffset
in .Net. That would have the advantage of seeing 8:00PM on every value, even if the offset was switching between -4 and -5. See DateTime vs DateTimeOffset.
To align these two concepts, you need some code that will evaluate the local time and compute the execution timestamp. You could just set up the next scheduled job as each job runs, or you could do this periodically and project event times for some future X number of events. That's up to you. If you need to put future event dates on a calendar - then you certainly need the latter approach.