I have some old data from oracle and the time is in milliseconds generated from Java.
I use this conversion:
to_date('19700101000000','YYYYMMDDHH24MISS')+ column/86400
And it always have a 5 hour shift to the actual time (which I cannot figure out why), so I just directly subtract 5/24 from the date above.
But it does not comes with day time conversion so in winter it is correct but for summer time it is 1 hour shift. How can I solve this?
Also if any one can point why there is a 5 hour shift will be much appreciated!
The 5 hour shift is probably caused by the difference between your local time (Central Time Zone, based on your user name ) and UTC time. Actually the shift should be 6 hours (CST is UTC - 6), so you've probably got it backwards; your summer time is probably closer to correct, and your winter time is still off by an hour.
Related
How should an RFC 5545 duration of less than 24 hours act when it crosses a Daylight Saving Time (DST) transition?
For example, assume DST ends at 2:00AM on a particular day, and assume that an event starts at the second 1:10AM on that day. (The first 1:10AM is one real-world hour earlier in Daylight Time, the second 1:10AM is in Standard Time).
If that event has a -PT15M (15 mins before) duration reminder, then how many real-world minutes before the start of the event should that reminder pop up? Should it pop up 15 real-world minutes earlier at the first 1:55AM (in Daylight Time)? Or should it pop up 75 real-world minutes earlier at 12:55AM Daylight Time?
The spec seems to imply the latter behavior, but that behavior seems counter-intuitive to me. If I want a reminder 15 minutes beforehand, I really mean "15 minutes". However it is intuitive for longer reminders, e.g. -P1D should be 25 hours before the start of that event so that you get the reminder at the same local time on the previous day.
Anyway, how do most calendar apps deal with this unintuitive behavior? Do they ignore the spec and always treat reminders <24 hours as exact without adjusting for DST? Or am I understanding the spec incorrectly and it's the -P1D case that will be unintuitive with the one-day reminder showing up at a different local time as the event start time?
Obviously this is somewhat of a corner case because few meetings start in the middle of the night. But there are cases where this could happen, e.g. late-night social events. And if I promise to meet you at the bar in 2 hours, I probably don't mean 1 hours or 3 hours on some nights!
Here's what the RFC 5545 spec says:
In the case of discontinuities in the time scale, such as the change from standard time to daylight time and back, the computation of the exact duration requires the subtraction or addition of the change of duration of the discontinuity.
To clarify further, according to https://standards.calconnect.org/csd/cc-51003.pdf, RFC 5545 has a concept of nominal durations (in local clock time) and exact durations (a real-world stopwatch that ignores DST). The language above is about how a nominal persisted duration should be converted to an exact duration.
This question isn't specific to a particular calendar implementation, but I'm tagging Google Calendar and Outlook here because developers using those APIs probably have the most context about these issues.
Consolidation of answers and comments above and direct answers to questions posed:
First part:
"How should an RFC 5545 duration of less than 24 hours act when it
crosses a Daylight Saving Time (DST) transition?"
Answer:
Since the duration is less than 24 hours, the exact number of hours, minutes, or seconds should be used for the duration (realtime). There is no confliction or ambiguity with durations < 24 hours.
Second part:
"If that event has a -PT15M (15 mins before) duration reminder, then
how many real-world minutes before the start of the event should that
reminder pop up? Should it pop up 15 real-world minutes earlier at the
first 1:55AM (in Daylight Time)? Or should it pop up 75 real-world
minutes earlier at 12:55AM Daylight Time?"
Answer:
15 real world minutes. The specs clearly say that anything less than one day is exact time. Any confusion or ambiguity around a daylight saving cutoff where a time is 'repeated' is avoided by adhering to the standard for referring a repeated clocktime during daylight savings. IE:
IE the first instance of a time such as 1.10am is the one that is assumed to be intended when one sees 1.10am for a timezone.
If one wants to refer to the second instance of 1.10 am one must use another timezone (eg UTC) to clearly identify the actual moment in time.
Third Part:
"how do most calendar apps deal with this unintuitive behavior? Do
they ignore the spec and always treat reminders <24 hours as exact
without adjusting for DST? Or am I understanding the spec incorrectly
and it's the -P1D case that will be unintuitive with the one-day
reminder showing up at a different local time as the event start
time?"
Answer:
They don't ignore the spec. The specification deals with this as one would intuitively expect. A reminder of < 24 hours (PT24H) is exact. No need to adjust for DST.
Similarly a reminder of 24 hours (PT24H) before should occur exactly 24 hours before.
In the case of a one day (P1D) reminder, a 1 day reminder should occur at the same time the previous day be this 23,24,or 25 hours before. This is as one would intuitively expect. The actual number of hours will of course vary depending on the day's place in the calendar.
P1D is not the same as PT24H, as P1D will depend on the dates place in the calendar, whether DST changeover is happening that day, whereas PT24H is exact.
References:
Daylight saving time and time zone best practices
https://www.rfc-editor.org/rfc/rfc5545#section-3.3.5 see DATETIME
https://icalendar.org/iCalendar-RFC-5545/3-3-6-duration.html
https://icalendar.org/iCalendar-RFC-5545/3-8-2-5-duration.html
The challenge here is to avoid ambiguity, not just with duration, but also with the event time. See the first point in the summary of answers here Daylight saving time and time zone best practices
To avoid ambiguities and to accurately refer to the 'second' 1.10am one should use UTC timezone for those second instances.
Note: In the DATETIME part of the spec, under Form #3, https://www.rfc-editor.org/rfc/rfc5545#section-3.3.5 it clearly states that a local time with timezone always refers to the first instance.
Page 45 of the above doc says for recurrences it is always interpreted as above (first instance):
If the computed local start time of a recurrence instance does not
exist, or occurs more than once, for the specified time zone, the
time of the recurrence instance is interpreted in the same manner
as an explicit DATE-TIME value describing that date and time, as
specified in Section 3.3.5.
I take this to mean that the only way to refer to the second 1.10 am of your example would be using UTC time! (or another timezone not affected by that daylight saving change).
The summary of answers in the stack overflow link above does note that in some cases, one may need to store both local & UTC. I suggest this may be exactly such a situation, where during the repeated cutover hour, the only truly accurate representation of times in that repeated daylight saving hour (the second hour), is the UTC time.
Example:
Repeat every 2nd week on Mondays every year between January 15th and May 10th.
I don't think so. This is the closest you can get IMO:
DTSTART;VALUE=DATE:20160115
RRULE:FREQ=YEARLY;BYWEEKNO=3,5,7,9,11,13,15,17,19;BYDAY=MO
Unfortunately, this will expand January 13th or 14th in certain years, which also means that all other instances in that year will be off by one week (see the first 100 instances). I think there are a few dates for which this would be correct though (because certain days in the year are always in the same calendar week).
The only way to do that is, if start and end date of the range match the start and end of a month.
I.e., in order to expand an event to every 2nd Monday between January 1st and May 31st each year you could do this:
DTSTART;VALUE=DATE:20160101
RRULE:FREQ=YEARLY;BYMONTH=1,2,3,4,5;BYDAY=MO;BYSETPOS=1,3,5,7,9,11,13,15,17,19,21,23,25,27
Here are the first 100 instances of that rule. Though some RRULE implementations might not support this properly.
I'm trying to calculate the day of week from a seconds since epoch timestamp. From time.h I can use gmtime(), but this increases the program with 1.3kB, probably because gmtime() also calculates the date.
So, I'm wondering what would be wrong about using something like:
(timestamp / (24*3600)) % 7
The only thing I could think of is leap seconds, such that something like 00:00:02 could be classified as the wrong day.
edit
This is for embedded programming, 1.3kB is a substantial part of the 64kB program/firmware. Furthermore, I'm not expecting to do anything with timezones or dates after this.
what would be wrong about using something like: (?)
(timestamp / (24*3600)) % 7
Not much wrong with the above except you have not specified the day of the week the epoch began (e.g. Thursday) nor the day of the week the week begins on (e.g. Monday). See 8601 for a deeper discusison on the first day of the week. Also watch out for computations like 24*3600 that with 16-bit int/unsigned lead to troubles.
Example: Let us say the epoch began on day-of-the-week number 3 (Monday:0. Thursday:3). This takes care of 2 issues at once: day of the week of the epoch and the first day of the week as only the positive difference needs to be coded.
#define EPOCH_DOW 3
#define SECS_PER_DAY 86400
dow = ((timestamp / SECS_PER_DAY) + EPOCH_DOW) % 7;
If timestamp is a signed type, append the following to insure a result in the [0...6] range.
dow = (dow + 7) % 7;
// or
if (dow < 0) dow += 7;
I doubt leap seconds are used in your application. If they are, the task is far more complicated as code then needs to deal with not only with a more complex calculation, but how to receive updates of the next scheduled leap-seconds - they occur irregularly.
You're off by 4, since January 1, 1970 was a Thursday, and you may compute an incorrect result for dates before the epoch depending on the behavior of % on negative operands. (The simplest fix is to check whether the result is negative, and if so add 7.) But other than this, your algorithm is correct; it's the same as used by glibc internal function __offtime, which gmtime ultimately ends up calling. (You can't call it yourself, as it's an internal implementation detail).
There's no need to worry about leap seconds; Unix time ignores them.
I would recommend encapsulating the code in a (possibly inline) function, with the gmtime implementation as a comment of #if 0 block, so that you can easily switch to it if you start needing to compute months/years as well.
SQLServer datetime format is stored as 8 bytes where the first four bytes are number of days since Jan 1, 1900 and the other four bytes are number of ticks since midnight. And the tick is 1/300 of the second.
I'm wondering why is that? Where is that 1/300 came from? There must be some historic reason for that.
Yes, there is a historical reason: UNIX !
For details, read this excelent article by Joe Celko.
Here is the detail you're looking for:
Temporal data in T-SQL
used to be a prisoner of UNIX system clock ticks and could only go
to three decimal seconds with rounding errors. The new ANSI/ISO data
types can go to seven decimal seconds, have a true DATE and TIME data
types. Since they are new, most programmers are not using them yet.
The function mktime takes a struct tm as argument. One of the members of struct tm is tm_isdst. You can set this to 1 for wintertime, 0 for summertime, or -1 if you don't know.
However, if during winter, you try to convert 2009-09-01 00:00, mktime fails to see that although it is currently winter, the date you are converting is summertime. So the result is one hour off. For me (GMT+1) it's 2009-08-31 22:00, while it should be 23:00.
Is there a way to determine if a particular date is in the summer or wintertime period? Is it possible to convert a summer date to utc in the winter?
(I hit upon this problem trying to answer this question)
This is one of the (many) deficiencies in the time handling interfaces in Standard C. See also the Olson time zone database. There isn't an easy way to find when a time zone switches between winter and summer (daylight saving and standard) time, for example. Anything in the future is, of course, a prediction — the rule sets change often (the current release is 2017a).
Is there as far as you know, a UNIX specific solution?
I took a look at the code in tzcode2017a.tar.gz, and the mktime() there behaves as you want if you set the tm_isdst to -1 (unknown). So, if you use that (public domain) code, you would be OK - probably. Quoting from 'localtime(3)' as distributed with the Olson code:
Mktime converts the broken‐down time, expressed as local time, in the structure pointed to by tm into a calendar time value with the same encoding as that of the values returned by the time function. The original values of the tm_wday and tm_yday components of the structure are ignored, and the original values of the other components are not restricted to their normal ranges. (A positive or zero value for tm_isdst causes mktime to presume initially that summer time (for example, Daylight Saving Time in the U.S.A.) respectively, is or is not in effect for the specified time. A negative value for tm_isdst causes the mktime function to attempt to divine whether summer time is in effect for the specified time; in this case it does not use a consistent rule and may give a different answer when later presented with the same argument.)
I believe that the last caveat about a 'consistent rule' means that if the specification of the time zone changes (for example, as when the USA changed from 1st week in April to 2nd week in March for the change to Daylight Saving Time) mean that if you determined some time before the rule changed and after the rule changed, the same input data would give different outputs.
(Note there are useful HTML files in ftp://ftp.iana.org/tz/ directory, such as ftp://ftp.iana.org/tz/tz-link.html.)