Given any two or more timezones, I would like to convert the local time in any timezone to any other such that the time representation accurately represents any local alterations (DST, etc) that each timezone has in effect.
Specifically, if some of the timezones I provide happen to deal with DST considerations, I need to detect and catch this such that the appropriate recalculations will automatically be made - for example, that the output for those timezones is automatically adjusted forward or backward by one hour.
I want to do all of this from the shell, if possible, preferably using portable techniques; I was considering handing off the heavy lifting to date, but I'm not sure how to have it perform relative timezone-accurate calculation, especially in a way that's crossplatform to at least Linux and BSD.
Convert to UTC first and then convert to the target time zone (using CET as an example)
TZ=CET date --date=#$(TZ=UTC date +%s)
DST will be taken automatically.
Related
I need to use time zone strings like this:
CET-1CEST,M3.5.0,M10.5.0/3
CET-1CEST-2,M3.5.0/02:00:00,M10.5.0/03:00:00
But the go time pkg is using the IANA Time Zone database e.g.: Europe/Paris
Is there perhaps a way to use or convert the strings?
I want to add/subtract time differences of various zones.
You'll need to build (or find) a map of 3-letter time zones to IANA time zone that covers the time zones you'll be seeing.
The reason being that 3-letter time zones like CET are not guaranteed to be unique (and are, in fact, not unique).
For instance, CET covers multiple TZDB time zones. They are all UTC+0100, but vary in
whether or not they observer Daylight Savings/Summer Time, and
The dates of the switch from standard time to daylight savings/summer time and vice-versa.
And PST covers "Pacfic Standard Time" (UTC-0800/UTC-0700), covering the west coast of the USA, but it also covers Asia/Manila (UTC+0800/UTC+0800).
There are lots more anomalies like that: the world is a big place, with lots of different governments and cultures.
Also, history matters: the geographic boundaries of time zones have changed over the years, as have the rules surrounding daylight savings times. So to get an accurate notion of a local time measurement relative to UTC, in addition to the local time measurement itself, you need to know not only where the measurement was taken, but when it was taken.
[and it gets worse if you have to consider the shift from the Julian to the Gregorian calendar: that took centuries to complete. Russia, for instance, didn't switch to the Gregorian calendar until after the Bolshevik Revolution at the end of the 1st world war.
Quite some time ago I used to work on the specific project using Spring on the backend. The system supposed to work across multiple timezones. Therefore it was decided to use integer values (Long) to store and transfer dates between backend and the web app. As I remember the main reason was to simplify and minimize work with timezones since the timestamp will always represent exact time and we always able to retrieve Date from it without worrying of incorrect timezone (the user's browser will apply proper timezone).
At that time I was little occupied with architecture, as I was only a junior. But since then I have not seen any application of this practice, and I can not find anything on the Internet.
I know there are some cases when we do not need to rely on time zones, for example when I travel to different country I don't want my alarm clock to be changed according to the new timezone. But I still want my reminder to notify me when I need to make an important call at the right time.
I believe the second case is much more common in the software.
Therefore I wanted to know is there any real benefit of using numeric timestamps?
I see at least two potential benefits:
Less hassle with the timezones (especially for the less experienced devs who can be confused at times working with dates)
Less data is transferred through the REST (?)
Downsides:
We have to extract Date value every time to process or display it (this can be automated using most of the frontend frameworks)
Database values and server debugging is not that self-evident
Underneath the scenes of DATE types in databases and higher-level languages, there is always some version of a relative date offset and resolution. In example:
DOS used 1 January 1980 with 10ms,
COBOL assumed 1 January 1601 with 1s resolution
UNIX and its ilk just happened to chose 1 Jan 1970 Midnight GMT.
Benefits of using a numeric and not interpreted numeric in your data storage is arguably (but subjective) easier date arithmetic. For TZ-heavy stuff like airline scheduling/logistics relying on the numeric (vs date type) as the numeric native allows one to keep consistency without date type function conversions despite TZs as well as politically-arbitrary DST adjustments. Because, the Uniform Time Act is the furthest thing from being uniform.
I would say that this really depends on the designated use of that value. It would probably make more sense to expose the timestamp value if you expect a technical usage, and ISO 8601 if you expect any other usage. For majority of usages they would probably be synonymous (watch out for leap seconds). They both refer to a fixed point in time.
Exposing the dates as ISO 8601 strings is definitely easier for debugging and for human eyes. You know straight away, which point in time it is.
UNIX timestamps historically also had a flaw of being restricted to the size of integer values. In 64 bit architecture this is usually no longer an issue, but for backwards compatibility strings would be a better option.
I would definitely not recommend to expose the dates through an API in the local time zones. Such values are usually ambiguous and unreliable. They are good for humans, but not good for anything else. Consider daylight saving time for example. Some periods in time exist twice, and some hours do not exist at all.
Oftentimes, to know what happens when in your code you need high precision time to profile your app or for other reasons. Apparently, now() does not provide this feature, but is there another reasonably simple way to get 'now' to millisecond precision?
From the docs:
help?> time
time()
Get the system time in seconds since the epoch, with fairly high (typically, microsecond) resolution.
So you can get the current DateTime using that.
But if you just want relative time, for e.g. profiling, you could use tic() and toq(), or time_ns() for really high accuracy, or just time.
This is not a post about technology per se, rather a post about the appropriate algorithm. I want my users to be able to schedule an event on my application to occur at a specific time (which they will see displayed in their time zone on my site) every week.
Say a user in New York schedules the event to occur at 8pm EST. I would like the event to occur for this user at 8pm EST every week for the entire year, regardless of daylight savings time.
Currently I'm storing the time value in UTC in my database, but UTC does not change based on the time of year. It seems that some timezones do have a concept of daylight savings and some dont, which means that if I were to do any timezone translation processing on the fly (either before any queries that lookup the date in order to schedule the event, or to display the scheduled time on the site) I would have to see if the user's timezone supports daylight savings and if the target timestamp falls within a daylight savings period.
How do people typically solve this type of problem? In other words, how should I store a logical time in my database, display it properly, use it for scheduling a task properly regardless of daylight savings time, for all user timezones, in the simplest way possible?
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.
Perhaps you can use any of the publicly available time zone APIs. Eg. https://developers.google.com/maps/documentation/timezone/ .
I would convert into UTC as soon as possible and out of UTC as late as possible, because when countries switch out of DST at the end of the summer they put the clocks back, and there are two hours in the day with the same time - so DST times cannot uniquely describe all times.
I'm working on an application that uses a lot of dates, but that doesn't rely on times at all. I'd like to store them internally as NSDates so that I can use NSDatePicker controls, built-in date functions, etc.
However, I keep tripping over the fact that NSDates insist on storing a time as well as a date. Many of the date initialization functions append either the current time or an arbitrary time. I've written my code to wipe out the times on all dates by setting the time components to 0 - but even so, time zone issues screw up some of the comparisons (e.g., comparing the current date to a specific date produces the wrong answer if the current date in the local time zone is different than the date in GMT).
Surely there's a better way to tackle this problem...?
The answer, as Thilo mentioned, was to set a fixed time zone.
Note that that wasn't quite enough. Initially, I chose GMT, and just fixed the time at 00:00:00. As it happens, that's kind of a stupid move, because any actual adjustment of the time can cause problems. Like, say... loading that value into a DatePicker control, and then using the application around 1am in a time zone west of GMT. Whoops.
To work around most of those problems, I instead chose GMT and set the time at a fixed 12:00:00. That should keep dates concurrent for eleven time zones east or west of GMT.