• Division Byzero (unregistered)

    The WTF is out there...

    in the comments.

  • loneprogrammer (cs)

    The problem here is that this code reinvents the wheel as an octagon -- not a smooth ride, but it will get you there eventually.

    A similar WTF would happen fairly often when a C programmer learned C++.  The first thing he would do is write his very own String class.  Usually they worked pretty well, except some gifted individuals would manage to screw it up.  Of course, then your String class would have a different interface than Fred's version of Strings.  And in modern times, C++ has its very own String class, so there's no longer any excuse for writing your own, except for homework assignments / experimentation.

    What I don't understand about today's WTF is why use base 36 numbers?  Is it a way to save space when converting a number to a string?  Why not use base 255 and save even more space?  Actually, maybe you could somehow store a number in a computer without converting it to a string first?  I've heard there's a way to do this now . . .

  • Mike R (cs) in reply to loneprogrammer

    On std::string. Personally, I don't like how it works, I prefer MFC's CString, but thats just personal preference.

    Back to the topic. Why bother with that method at all.. It should have been stored as YYYY-MM-DD HH:II:SS

    Where Y is the 4 digit year, M is a two digit month (i.e. 02), D is a two digit day, H is the 2 digit hour in 24h format, I is 2digit min, S is 2 digit second.

    Sorts cleanly.

  • JamesCurran (cs)

    that seem a bit off, that was actually from another guy. With the same name. Who worked at the same place. And the other same place. Yes, that did get a bit weird.

    Well, it's not quite as weird as one has just recently left the company, but, at my office the developers sit a open-form area (it's actually 4 cubicals without the inner walls). 

    Going around the area, the developers are:  James, Miguel, James, Miguel and James.

  • b0b0b0b (unregistered) in reply to loneprogrammer

    My guess is he picked base 36 because you can use [0-9A-Z] to represent it.  duuuuuuuuude

  • Graeme Cole (unregistered) in reply to loneprogrammer

    About why base-36 is used: other than that 36 happens to be the number of letters and digits we have, taking a lower base might mean that a new digit is added on the front too early, meaning that it won't sort correctly. For example, if it were stored in base ten, then 999,999,999 would be considered greater than 1,000,000,000 (since it's sorted alphabetically), and the system would have broken in 2001.

  • cm5400 (cs)

    Hmmm... In developing a licensing class for my apps, I did something similar with dates, and with some funky number mashing to make it more cryptic and then tying it to the local PC.  This gave me the ability to have an experation date on the license tied to a single computer.  <sarcasm> (now why the hell would I want my software to expire and be tied to a single 'puter?) </sarcasm> [:D]

  • Pete Krawczyk (unregistered)
    Alex Papadimoulis:

    Of course, I'd be the first to admit to my own mistake. I'm still waiting for that day to come.  If it ever does, you'll here it first from me.



    Does here instead of hear count?
  • Anonymous (unregistered) in reply to Pete Krawczyk

    WTFs submitted by the author are definately not as much fun...

  • Charles Nadolski (cs) in reply to Anonymous
    Anonymous:
    WTFs submitted by the author are definately not as much fun...


    So the embarathy factor outweights even the best self-depricating humor?  I for one think the code written by me when I was 13 for QBASIC is pure WTF.  I think it would be neat to share our best personal WTF moments (ala "what is was your most embarassing moment") in a seperate thread.
  • bat (cs) in reply to Charles Nadolski

    Funny thing: I wrote some accounting software in the late 1980s in Turbo/Borland Pascal 5.5-7.0 for DOS, and it's still some of the best stuff I've ever written: clean, disciplined and largely bug-free.  Stuff I've written more recently has been much uglier.  A lot of it has to do with modern languages: they encourage you to write much more quickly, unlike TP which, thanks to the too-clever-by-half TurboVision DOS GUI system, required very careful steps and a lot of caffeine.

  • kentcb (cs) in reply to Mike R

    Mike R:
    On std::string. Personally, I don't like how it works, I prefer MFC's CString, but thats just personal preference.

    Back to the topic. Why bother with that method at all.. It should have been stored as YYYY-MM-DD HH:II:SS

    Where Y is the 4 digit year, M is a two digit month (i.e. 02), D is a two digit day, H is the 2 digit hour in 24h format, I is 2digit min, S is 2 digit second.

    Sorts cleanly.

    Each night I thank God for my wife, child and std::string.

  • blasterz (cs) in reply to loneprogrammer
    loneprogrammer:


    What I don't understand about today's WTF is why use base 36 numbers?  Is it a way to save space when converting a number to a string?  Why not use base 255 and save even more space?



    I used base 36 because that's as high as javascript's parseInt() will go. With 5 characters, you can express any minute between sometime in 1973 (10000) and December of 2084 (zzzzz).

    An additional WTF is that I was casting all fields retrieved from the database as strings. I was getting a bunch of bad dates displaying on the page - 2/12/1972 11:45 AM CST. Based on my rather, um, original format, that translates as "null".
  • mattparkins (cs) in reply to Charles Nadolski
    Charles Nadolski:
    I think it would be neat to share our best personal WTF moments (ala "what is was your most embarassing moment") in a seperate thread.


    I would but I don't think I've had one.  Come to think of it I can't remember the last time I generated an error, or even a warning...  ;)

    Mr Lint
  • mattparkins (cs) in reply to mattparkins

    Well...  ok...  apart from little gems like in some texture packing code :

        u =+ 4;

    when I meant :

        u += 4;


    (um, there might be more)

  • bat (cs) in reply to mattparkins

    I think =+ used to be a synonym for += in really really early C, so now most C/C++ compilers notice it and issue a warning.  I don't have an easily accessible C compiler at my fingertips (I'd have to start up a Linux virtual machine) so I can't check.  Presumably the other C dialects (C#, Java, Perl, etc) that use += would have the potential to catch this bug at compile time; I wonder how many do.  I can check one easily right now:

    C:\>perl -e "$u = 1; $u =+ 4; print $u;"
    4

    Hmm!

  • Welcome To The Machine (unregistered) in reply to blasterz

    blasterz:
    loneprogrammer:


    What I don't understand about today's WTF is why use base 36 numbers?  Is it a way to save space when converting a number to a string?  Why not use base 255 and save even more space?



    I used base 36 because that's as high as javascript's parseInt() will go. With 5 characters, you can express any minute between sometime in 1973 (10000) and December of 2084 (zzzzz).

    An additional WTF is that I was casting all fields retrieved from the database as strings. I was getting a bunch of bad dates displaying on the page - 2/12/1972 11:45 AM CST. Based on my rather, um, original format, that translates as "null".

    Fair play to you blasterz for owning up to your own WTF. We should definitely have more people who are humble enough to admit their own mistakes!

  • Welcome To The Machine (unregistered) in reply to bat
    bat:
    I think =+ used to be a synonym for += in really really early C, so now most C/C++ compilers notice it and issue a warning.  I don't have an easily accessible C compiler at my fingertips (I'd have to start up a Linux virtual machine) so I can't check.  Presumably the other C dialects (C#, Java, Perl, etc) that use += would have the potential to catch this bug at compile time; I wonder how many do.  I can check one easily right now:

    C:\>perl -e "$u = 1; $u =+ 4; print $u;"
    4


    Hmm!

    Isn't that just doing $u = +4, the compiler implying a space?

  • ammoQ (unregistered)

    It's not uncommon that date/time-information is stored in character fields, especially if the program is meant to run on different database systems. This way, problems with different meanings/behaviours of some database systems and drivers (like the Oracle10 jdbc driver removing time information when accessing Oracle9 databases) can be avoided. The trick with base36 is uncommon, but ingenious. Most of the time, people use a "YYYYMMDDhhddss" format.

  • ammoQ (unregistered) in reply to ammoQ

    oops, I meant "YYYYMMDDhhmmss"

  • Mike R (cs) in reply to kentcb
    kentcb:

    Mike R:
    On std::string. Personally, I don't like how it works, I prefer MFC's CString, but thats just personal preference.

    Each night I thank God for my wife, child and std::string.



    What advantage does std::string have over the CString class, aside from the fact that it is part of the STL. I guess its the same reason I prefer to use good ol' C file handling routines rather than the stream objects, they just feel kludgy and nasty. I can't remember the specifics, but its easier to use CString.Format("%03i: %s\n", n, msg); rather than the following:


        std::string s;
        std::ostringstream ss;
        ss << std::setw(3) << std::setfill('0') << n << ": " << msg << std::endl;
        s = ss.str();


    Which, btw, required about 30 mins of searching the docs to figure out how in the hell to use the manipulators.

    Please excuse the double-spaced code. This edit control sucks. [:(]
  • ammoQ (unregistered) in reply to Mike R

    ss << std::setw(3) << std::setfill('0') << n << ": " << msg << std::endl;

    I hope a very special co-worker of mine does not see this code... nobody can imagine the WTFs he
    would make out of it.

  • loneprogrammer (cs) in reply to bat
    bat:

    C:\>perl -e "$u = 1; $u =+ 4; print $u;"
    4

    Hmm!



    You shouldn't ever use Perl without strict and warnings:

    % perl -Mstrict -Mwarnings  -e 'my $u = 1; $u =+ 4; print $u'
    Reversed += operator at -e line 1.
    4

  • JamesCurran (cs) in reply to Mike R

    Mike R:
    I can't remember the specifics, but its easier to use CString.Format("%03i: %s\n", n, msg);

    Change n from an int to a MyClass and then try it.......

  • brandonh6k (cs) in reply to Mike R
    Mike R:

    What advantage does std::string have over the CString class, aside from the fact that it is part of the STL.

    I would think the big advantage is the fact that CString is MFC and you introduce another dependency.  Granted, these days, it's all C# for me so I have a ~30Mb dependency.... [:P]
  • loneprogrammer (cs) in reply to bat
    bat:
    I think =+ used to be a synonym for += in really really early C, so now most C/C++ compilers notice it and issue a warning. 


    gcc 2.96 issues no warning even with -Wall.

  • Ben Hutchings (cs) in reply to bat

    Originally the augmented assignment operators in C were always written as =+, =- etc. However this was found to result in errors because the meaning of many expressions could be changed by the insertion or deletion of a space after an = sign. The Unix C compiler was changed to accept the modern versions of these operators between version 6 and version 7. The first edition of The C Programming Language, published in 1978, uses the modern versions and includes a note about the old problematic versions. Given that that was over a quarter-century ago, I think such warnings are unnecessary now.

  • alan (unregistered) in reply to bat

    You forgot your warnings, dude.

    % perl -wle '$u = 1; $u =+ 4; print $u'
    Reversed += operator at -e line 1.
    4

  • redtetrahedron (cs) in reply to JamesCurran
    JamesCurran:

    Mike R:
    I can't remember the specifics, but its easier to use CString.Format("%03i: %s\n", n, msg);

    Change n from an int to a MyClass and then try it.......

    As long as MyClass has an operator int and you cast it...

     

  • Charles Nadolski (cs) in reply to redtetrahedron
    redtetrahedron:
    JamesCurran:

    Mike R:
    I can't remember the specifics, but its easier to use CString.Format("%03i: %s\n", n, msg);

    Change n from an int to a MyClass and then try it.......

    As long as MyClass has an operator int and you cast it...

     



    Now that we're on the topic of MFC vs Std C... The "advantage" of doing ofstream << on objects is also a weakness.  With MFC you can serialize ANY object and pack it bitwise into a file.  Try doing that with streams, and you're stuck with a text-conversion of your MyClass object.  If you try and save pi for instance, MFC will stuff that double into 8 bytes and not lose any precision.  With std <<, it will output something like "3.141592".  You only get 6 decimal places of accuracy, and take up 8 bytes of memory, assuming it will *not* save to unicode.  Save to unicode (which is what windows will often do), and it will baloon to 16 bytes.
  • kentcb (cs) in reply to brandonh6k

    brandonh6k:
    Mike R:

    What advantage does std::string have over the CString class, aside from the fact that it is part of the STL.

    I would think the big advantage is the fact that CString is MFC and you introduce another dependency.  Granted, these days, it's all C# for me so I have a ~30Mb dependency.... [:P]

    Yep, and std::string is a standard container, which means you can use a lot of existing algorithms and stuff against it. Don't get me wrong, I've used CString and found it quite usable. I just prefer std::string because it's, um, standard.

  • vdboor (unregistered) in reply to ammoQ
    Anonymous:
    ss << std::setw(3) << std::setfill('0') << n << ": " << msg << std::endl;

    I hope a very special co-worker of mine does not see this code... nobody can imagine the WTFs he
    would make out of it.

    Agreed.. Wouldn't using Qt and QStrings make C++ programming a lot easier?

  • Matt (unregistered)

    I've had to recently had to convert System36 data - produced by code written circa '84.  They always stored date as text.  Though the solution to the sorting problem I've seen employed there is simply using the format YYYYMMDD.   Text field, sortable by date.

  • JamesCurran (cs) in reply to Charles Nadolski

    Charles Nadolski:

    Now that we're on the topic of MFC vs Std C... The "advantage" of doing ofstream << on objects is also a weakness.  With MFC you can serialize ANY object and pack it bitwise into a file. 

    Try doing that with streams, and you're stuck with a text-conversion of your MyClass object.  

    Nonsense.  Streams can write binary data just as well as text.  You will have to write a custom outputter function, but you'd have to do that for MFC as well.

    class MyClass
    {
        private:
          /// blah-blah-blah
         public:
          fstream& OutputTo(fstream& fstr) const
         {
                fstr.write( (const char*) this, sizeof(MyClass));
               return fstr;
          }
       };

    inline fstream& operator<<(fstream& lhs,  const MyClass rhs)
    {     return rhs.OutputTo(lhs);    }

    If you try and save pi for instance, MFC will stuff that double into 8 bytes and not lose any precision. 

    Which would look pretty sad on a printout. 

    With std <<, it will output something like "3.141592".  You only get 6 decimal places of accuracy, and take up 8 bytes of memory

    << was intended for console output.  Don't blame C++ or the Standard Library because you don't know how to use them.

  • Alan (unregistered)

    The open-sauce Java search engine Lucene actually uses base36 as well for its date(time) storage.

    The algorithm takes seconds-since-epoch, multiplies by 1000, and then painfully shifts the low bits into a new string that consists of the letters 0..9 and a..z. Finally the end result is forced into a string of 10 characters (if I remember right, could have been 9 too).

    The reason? Sortability, of course.

    The Perl implementation of Lucene called PLucene is quite wtf-ish, with like dozen classes related to parsing that declare one method that just returns a regex etc. But that's due to its Java roots.

  • war gold (unregistered)
    Comment held for moderation.
  • JMR (unregistered)

    There are two legitimate ways to store dates, everything else is crapola and should result in immediate smack of large fish to the face.

    One is epoch time. The other is putting all the date elements (YYYY, MM, DD, hh, mm, ss, nn, etc.) in order so that a normal text sort still works. Personally I prefer epoch time for everything (since it allows math to work against the date with minimal hassle), but my experience has been that enough people are unfamiliar with it that I will use YYYYMMDDhhmmssnn if I'm working on something that lots of people will see.

    I couldn't count how many times I've seen dates stored in some locale format (usually en-usa), with all the associated garbage code to work around that stupid choice.

Leave a comment on “Obvious Datetime Storage”

Log In or post as a guest

Replying to comment #:

« Return to Article