- Feature Articles
- CodeSOD
- Error'd
- Forums
-
Other Articles
- Random Article
- Other Series
- Alex's Soapbox
- Announcements
- Best of…
- Best of Email
- Best of the Sidebar
- Bring Your Own Code
- Coded Smorgasbord
- Mandatory Fun Day
- Off Topic
- Representative Line
- News Roundup
- Editor's Soapbox
- Software on the Rocks
- Souvenir Potpourri
- Sponsor Post
- Tales from the Interview
- The Daily WTF: Live
- Virtudyne
Admin
What? I didn't say anything about "1970-year+3"...
Am I sure it correctly converts to Unix time? Not completely, but fairly confident.
Am I sure it facilitates correctly computing the difference in days between two dates? Yes.
Admin
Rounding up at .5 is not symmetric. 1.5 is exactly as close to 1 as it is to 2.
1.0 -> 1 (-0.0) 1.1 -> 1 (-0.1) 1.2 -> 1 (-0.2) 1.3 -> 1 (-0.3) 1.4 -> 1 (-0.4) 1.5 -> 2 (+0.5) 1.6 -> 2 (+0.4) 1.7 -> 2 (+0.3) 1.8 -> 2 (+0.2) 1.9 -> 2 (+0.1) 2.0 -> 2 (-0.0) 2.1 -> 2 (-0.1) 2.2 -> 2 (-0.2) 2.3 -> 2 (-0.3) 2.4 -> 2 (-0.4) 2.5 -> 3 (+0.5) 2.6 -> 3 (+0.4) 2.7 -> 3 (+0.3) 2.8 -> 3 (+0.2) 2.9 -> 3 (+0.1)
Add up the adjustments, and you get +1. If it was symmetric, it should be 0. In fact, if you use the "round half to even" rule (IEEE 745), then you do get 0, because the +0.5 at 1.5 and the -0.5 at 2.5 cancel each other out.
Admin
Tell that to your doctor. We'll see how much longer you live.
Admin
That was a fix for my algorithm. Actually I think it's year-1970+3. My while is missing an ineffectual +1 as well.
I like how yours theoretically supports unsigned unixtime by checking for leap centuries by the way and also offers some support for 64bit unixtime.
Admin
There are two bugs in the conversion to the Unix Epoch:
Leap years are not every 4 years. (http://en.wikipedia.org/wiki/Leap_year#Algorithm)
It does not account for a leap year in the part of the algorithm that examines the day value due to months.
There are also naming problems here. The function should be ConvertToUnixEpoch(). That would make things much clearer.
I also agree that using the built in language functions would be a better choice.
The principle of using the Unix Epoch for date calculations is sound however. The fact that it's on a Windows server shouldn't matter unless the program is providing the server with the date in that format.
For those interested here's a discussion on how to more cleanly find the Unix Epoch in C#: http://stackoverflow.com/questions/906034/calculating-future-epoch-time-in-c-sharp
Admin
I fixed it for him.
return ((year-1970)*365+(year-1969>>2)+new int[]{0,31,59,90,120,151,181,212,243,273,304,334}[month-1]+day+(year%4==0&&month>2?0:-1))*86400;
This one definitely works, I discovered csc.exe on my system and tested it.
Who knew C# was so easy?
Admin
That got me, too.
Admin
NO, and wow you are retarded (unless you are trolling, but given what I've seen here you're probably not). Using banker's rounding you round it up because it's larger than 0.5. Period.
And FYI IEEE 754 does take into account all the extra digits when rounding after each operation. So if 1.01000000000000000000001 (binary) has to be rounded, it rounds to 1.1. Believe it or not they actually did the math and chose the way that would give the smallest error.
Admin
Admin
Admin
Four pages of comments. And still nobody pointing out that their definition of YEAR is equal to 364 * DAY.
The way their code computes the elapsed days is fairly efficient, but difficult to get right. The good thing I can say about it is, that it is easy to unit test. Writing code to iterate through every single date from 1700 to 3000 is fairly easy and will run in a split second on modern hardware. You just need to check the elapsed days since some fixed point in the past and verify that it increases by one every time you proceed to the next day.
There is nothing wrong with code as clever as shown as long as you use enough unit testing to find and fix all the bugs. And in case your unit test finds the code to be flawless the first time you run it, that means there is a bug in the unit test.
Admin
QFT.
In my company, the constant YEAR wouldn't have passed a code review because (365 * 86400) is just as efficient as writing some huge number and a lot clearer. In other words, in a code review I wouldn't give a damn whether their number is right or wrong, the fact that I need a calculator to check it makes it a WTF.
Well, the name "YEAR" wouldn't have passed a code review in the first place, because the name doesn't give any indication what it actually means. Setting year to 365 makes just as much sense. So it should have been SECONDS_PER_YEAR, for example.
The rest of the code is obviously idiotic. Hint: In a correct calculation, 1st of March is usually 86400 seconds later than 28th of February, but sometimes it is 2 x 86400 seconds later. There must be something in the code to achieve this, and there isn't.
Admin
The constant naming is bad and there should never be a constant for seconds per year because it isn't constant.
However, when it comes to code the first thing that should concern anyone is whether it works or not. You're right on the constants but it's not by far the biggest issue or the hardest to spot and fix. It's not even the kind of fault that is daily WTF worthy.
Kasper is correct that it should be unit tested. Except his proposed date range is too large for unixtime and I have a sneaky suspicion that for generating test dates you would be using library functions that either are the same as, or one step away from ones that are from those that you are testing. The first thing I would do to unit test it? Use a library that I can reasonably rely on to work correctly that does the same thing and compare results. Totally redundant.
Admin
If you don't need the code to cover that many years, then feel free to leave it out of the unit test. Just keep in mind that code tends to never survive for exactly as long as you expected. Usually it will either never make it to production or outlive the expectation by an order of magnitude. If your unit tests only cover the range of dates that can be represented in 32 bit unix time, then you can use that inside your implementation and pass the unit tests.
My point just was that it is completely feasible to cover such a large range in a unit test. And since the calendar repeats every 400 years (except from the phase of the moon), then it makes sense to cover a period a bit longer than that to ensure you didn't miss a corner case.
That's not how I would do it. I would start the unit test with a fixed date far in the past. Then I would have one counter for the number of days tested so far, and another set of variables representing year, month, day of the month. Then at every itteration increase the counter as well as day of the month. Then followed by a few ifs to reset day of month and month to 1 and increase month and year.You'd be writing the code once for the actual routine and once for the unit test. But the version in the unit test needing only to increase from one date to the following date would be totally different and a lot easier to get right. The risk of making the same flaw in both of them, and having the code reviewer miss them both is tiny.
I'd write the unit test code roughly like this. Given the different structure, the risk of introducing the same flaw in both is tiny. Even if I made a mistake in this unit test code, I'm confident that would also be revealed by running the unit test.
Admin
holy shit, please stick to building WordPress blogs from here on out if you're not aware how computers handle decimals.
Admin
It sucks not to understand what goes on in integer division. I wonder if some people are confused who have only used loosely typed languages. In that case a division between two integers can result in a floating point result. But yes, wheel's comment is just daft.
Admin
If I saw a developer using bit shifting for multiplication in C#, I'd have them fired. Out of a cannon.
There's no reason for that kind of confusion-inducing performance optimisation tricks in a modern app where the compiler can inevitably do a better job of it than the average code monkey (and most of the higher primates, too)
Admin
(checks the file history)
"Oh. Never mind..."
Admin
Yeah, it's bizarre how many people fail to understand the century year criteria for a leap year.
I usually take the time to explain the reasons for it. The Julian calendar assumed a solar year length of 365 and a quarter days and so had a leap year every 4 years wihout exception but the solar years is actually 11 minutes less. Which may not seem like much but it accounts for 3 days every 4 centuries. Hence the Gregorian reform ensured that only 1 century year in 4 is a leap year.
The Julian calendar still follows the old rule and because it has more Feb 29ths inserted it's now 13 days "behind" the Gregorian calendar.
Admin
Using epoch seems really like a nice idea to circumvent problems in precisely timed transactions over timezones.
Admin
I used it because it's more portable, although if you really want your algorithm to be truly portable you would explicitly floor.
Admin
Greece can't afford to any more
Admin
1976 - I was using a 150 column printer attached to a mainframe in the very early 1980s
Admin
More portable for those systems that don't support multiplication.
Admin
Big difference between rounding and truncation.
Double to Int uses truncation. That is it chops off the decimal part.
Admin
Two things.
Who reviews printed code anymore???
Admin
Just my 0.02$ on this story, nothing says that he actually found and/or reported that the code was buggy in any way. Just saying "this code could be simpler and better using the built-in date functions" isn't a bug report, at least not unless you've put something very specific in the contract. If I ever tried to outsource something I'd probably try to include something like:
"Reimplementing functionality already present in the stanadard library shall be concidered a C-level bug (with A being critical, B major, C minor). This includes but is not limited to:
That way I could at least point to it and say this isn't just poor code, we've agreed doing this is a bug. Don't know if they'd accept it, but I'd be afraid to sign on any company that clearly wouldn't.
Admin
I'd have to say I agree with the designers.
Admin
Admin
The reason it's not done much? There's reasons, I'll start off with two.
I could probably think of more, but it's the end of the day and I'm mostly spent from arguing with users.
Admin
One of the other reasons that it's not done much, is that there is simply so much shitty code, and it's everywhere. EVERYWHERE.
Why? Because anyone and everyone can be a programmer right? And who wouldn't want to be a programmer?
Admin
Nobody seemed to notice: public const int YEAR = 31449600;
That's 364 days a year. Good thing it isn't use...
Admin
Unsubscribe me!!!