Unknown timestamp reference date - windows

I'm currently dealing with a system which uses an unknown timestamp mechanism.
The system is running on a Windows machine, so my first thought was that it uses some kind of Windows epoch for its timestamps, but it appears it does not.
My goal is to convert these timestamps to Unix timestamps.
A few examples:
The following timestamp: 2111441659 converts to: 2013-10-01 11:59
2111441998 to 2013-10-01 17:14
2111443876 to 2013-10-02 14:36
2111444089 to 2013-10-02 17:57
(All dates are GMT+2)
I've tried to calculate the reference date using the data above, but somehow I get a different result with every single timestamp.
Could anybody shed some light on this rather odd problem?
Thanks in advance!

To me the number seems to small to be milliseconds. My first guess was then seconds but looking at the speed this number varies with i think minutes is a better guess. Doing some math on it 2111441659/60/24/365 = 4017.20254756 which suggests the epoch might be sometime in the year -2000?
Here is a list of common epochs in computing but the year -2000 is not really there :) How are you obtaining this timestamp?
P.S. are you sure the year is set to 2013 on this machine and not to 4013? :) This would then fit with the .NET epoch of January 1, Year 1

In order to distinguish your timestamp from Unix timestamp, let's call yours The Counter.
So we have four counter values with their corresponding DateTime value. The first thing to do is calculate the counter's unit correspondence to a real time unit, let's say a second.
In order to do that, we need (1) the difference d between two counter values and (2) the difference s between their corresponding DateTimes, in seconds.
Considering the first two values we have d1=2111441998-2111441659=339. The difference between 2013-10-01 11:59 and 2013-10-01 17:14 (in seconds) is s1=18900. Consequently, the counter's unit corresponds to u1=s1/d1=55.7522123894 seconds.
But if we do the same with pairs #2 and #3, we will find that u2=40.9584664536 seconds.
Similarily, pairs #3 and #4 give us u3=56.6197183114 seconds.
My conclusion therefore, is that there's no alignment between the counter values and the corresponding DateTimes provided. That's the reason why you get a different result with each sample.

Finally, after many hours of comparing the timestamps with the datetimes, trying to discover the logic between them, I've found the answer by reverse engineering the software which generates the timestamps.
It turns out that the integer timestamps are actually bitwise representations* of the datetimes.
In pseudocode:
year = TimeStamp >> 20;
month = (TimeStamp >> 16) & 15;
day = (TimeStamp >> 11) & 31;
hour = (TimeStamp >> 6) & 31;
minute = TimeStamp & 63;
*I'm not sure if this is the correct term for it, if not, please correct me.

Related

Summing times in Google sheets

I have a sheet where I record my working hours (this is more for me to remind me to stop working than anything else). For every day, I have three possible shifts - early, normal & late, and I have a formula which will sum up any times put into these columns and give me the daily total hours.
To summarise the duration of time spent working in a day, I use the following formula: =(C41-B41)+(E41-D41)+12+(G41-F41) which is:
early end time minus early start time
normal end time minus normal start time PLUS 12 hours
late end time minus late start time
Which gives me output like this:
What I cannot seem to achieve is, the ability to sum the daily totals into something which shows me the total hours worked over 1-week. If I attempt to sum the daily totals together for the example image shown, I get some wild figure such as 1487:25:00 when formatting as 'Duration' or 23:25:00 when formatted as 'Time'!
All my cells where I record the hours worked are formatted as 'Time'
When using arithmetic operations on date values in Google Sheets, it's important to remember that the internal representation of a date is numeric, and understood as the number of days since January 1, 1970.
What follows from that, is that if you want to add 12 hours to a time duration, you should not write "+12" because that will in fact add 12 days. Instead add "+12/24". In other words, try the following formula instead of the one you are using now:
=(C41-B41)+(E41-D41)+(12/24+G41-F41)

A DATE with the ORACLE - The Time Zone Dilemma. Is it midnight or is there no time?

So I'm writing some code trying to convert some oracle dates I got into a different time zone. The issue I'm having is that when the time portion is 00:00:00 I don't now how to determine if it is legitimately midnight or if the date was meant to not include a time.
Currently, I'm making the assumption that if the time is 00:00:00 then the value is just a time-free date, because unfortunately that is sometimes the case, but while statistically small, there is a chance that the date is legitimately midnight so I'm trying to find a better approach with no success.
I can't assume all 00:00:00 are midnight, because if the data was intended to only have a date then converting to most other US time zones would change the date.
Any suggestions?
Check for other values in the same column to see what the distribution of 00:00:00's is. If all entries are 00:00:00 then the column is definitely dates, if it's roughly 1 in (24*60*60) occurrences then it's definitely times, if it's somewhere in between then you've got a problem.
You could also look for a check constraint to see if times are constrained to be midnight.
You could look at the semantics of the column also -- what does the name tell you?

How to handle recurring times?

First off, I marked this question as language agnostic, but I'm using PHP and MySQL. It shouldn't affect the question itself very much tho.
I'm creating an application which shows times of certain shows throughout the week. Every single show is recurring (on weekly basis) and there might be shows which are airing through 2 days - eg. starting on Sunday at 23:30, ending on Monday at 00:30. I'm storing start of the show (day of the week - Monday, Tuesday... - it's never exact date; time) and duration. There are never shows that would take more than 24 hours.
My problem is with validation if newly added shows aren't overlapping some old ones. Especially if it comes to Sunday-Monday shows.
How are such recurring events usually handled on both DB side and server side?
tl;dr version with stuff I considered
My first idea was to create some custom validation algorithm, but it seemed too cumbersome and complicated. Not that I'd whine about complicated hand-made solutions, but I'm interested if there isn't something more basic that I'm missing.
Other alternative that came to mind was to change table structure to use datetime (instead of "day of week" and "time"), and use a fake fixed date range to store the data. For example all Mondays would be set to 5th Jan 1970, Sundays would use 11th Jan 1970. There would be one exception to this rule - if there would be some show which starts on Sunday and ends on Monday, it would be stored as 12th Jan 1970. This solution would allow more flexible quering of the DB than the original one, and it would also simplify queries for shows which overlap between individual weeks (since we can do the comparison directly in the query). There are some disadvantages to this solution as well (for one, using fake dates might make it confusing).
Both solutions smell of wrong algorithms to me and would love to hear some opinions from more experienced fellow developers.
Sounds like you could just store the starting minute of each show as an integer number of minutes since the start of the week (10,080 possible values).
Then a show starting at minute $a with duration $dur_a will overlap $b if and only if
(10080 + $b - $a) % 10080 < $dur_a
For example consider a show starting at 11pm Sunday and another starting at 12.30am Monday. Here $a == 10020 and $dur_a == 120 and $b == 30. (10080 + $b - $a) % 10080 == 90. This is less than $dur_a and hence the shows overlap.
This problem could be simplified by converting the data into a format that is amenable to the calculations that are required. I recommend creating a type that represents the start times as the number of minutes from Sunday at midnight. Then simple integer range comparisons could be used to find overlapping shows.
The internal representation must, of course, be hidden and abstracted. You may, at some point, want to change the representation from minutes to seconds, for example.
I would opt for a custom validation algorithm:
For each show, compute all showing intervals [start1, end1], [start2, end2], ... [startN, endN], where N is the number of recurrence of the show.
For a new show, also compute these intervals.
Now check if any of these new intervals intersect any old intervals. This is the case if the start or the end of one interval is contained in the other.

can i increment date using xpath?

i need to increment current date by 7 days and i'm wondering if it's possible to do that using a xpath function.
thanks !!
It is possible in XPATH 2.0. There are a number of date functions.
current-date() + xs:dayTimeDuration('P7D')
If your date is in some numeric format (CTIME, seconds since 1970 (32 bit int), or FILETIME, 100 nanosecond counts since 1601 (64 bit)) then incrementing time is easy. Just add the correct number of seconds (or 100 nanosecond intervals) to the time.
You could convert your format to CTIME via the Java time function library, add the correct number of seconds (86,400 seconds in a day), and then convert it back to your string format, I suppose. Probably not the worlds most efficient approach though.

Calculating task start times

I have a requirement that goes as follows (trust me, I'm way too old for homework grin)
I have a bunch of tasks that run with various frequencies. They also have a start "seed" date/time . The start seed is sometime in the past, could be one minute ago, could be 5 years ago.
I need to calculate the next run time for the task, using the start seed date/time and the frequency - it cannot simply be "now" + the task frequency (for those of you who have scheduled jobs on MS SQL Server this is a familiar concept)
Now the silly way to do it is to take the start seed and keep adding the frequency until it becomes greater than "now". That's hardly optimal. The naive way to do it would be to take the start seed date, change it to today's date and leave the time as is, then add the frequency until it's greater than now, but that assumes the frequency is a multiple of 24 hours.
So what's the best/quickest way to do this? Bonus points for a C# solution, but this is generic enough to make an interesting puzzle for any language :)
A better method would be to take the difference between the start timestamp and the current timestamp, divide that by the frequency, round the resulting multiplier up to the nearest integer, multiply by the frequency again, and add that to the start timestamp once more.
The act of rounding up will provide the proper offset.
Your answer would essentially be this:
next_time = ceiling((now - seed)/frequency) * frequency + seed
Using the ceiling function ensures that next_time will be >= now.
You would have to do the necessary conversions to be able to perform this arithmetic on the dates (e.g., translate to UNIX time, which is number of seconds since Jan 1, 1970.)
I am not familiar with C# so I can't offer the code, but I assume that C# has date/time utility classes for dealing with date/time arithmetic operations.
Interesting puzzle, thanks for the challenge :)
This should do it in c#. Could almost certainly be slimmed down, but its verbose enough to explain whats going on.
// Initialise with date the event started, and frequency
DateTime startDate = new DateTime(2009, 8,1,9,0,0);
TimeSpan frequency = new TimeSpan(0, 15, 0);
// Store datetime now (so that it doesnt alter during following calculations)
DateTime now = DateTime.Now;
// Calculate the number of ticks that have occured since the event started
TimeSpan pastTimeSpan = now.Subtract(startDate);
// Divide the period that the event has been running by the frequency
// Take the remaining time span
TimeSpan remainingTimeSpan = new TimeSpan(pastTimeSpan.Ticks % frequency.Ticks);
// Calculate last occurence the event ran
DateTime lastOccurence = now.Subtract(remainingTimeSpan);
// Calculate next occurence the event will run
DateTime nextOccurence = lastOccurence.Add(frequency);

Resources