• NULLPTR (unregistered)

    NULL == NULL;

  • Ondřej Vágner (google)

    How to Write Your Own Date Parser

    1. Don't.

    Addendum 2019-09-05 06:43: How to Find Out TDWTF Parses Markdown in Comments.

  • P (unregistered)

    No mentions on the entirely unnecessary usage of global?

  • bvs23bkv33 (unregistered)
             01  MONTH-ALPHA            PIC       X(36).
             01  filler                 REDEFINES MONTH-ALPHA.
               05  MONTH-TABLE          OCCURS    12
                                        PIC       XXX.
    
           MOVE "JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC"
                                TO MONTH-ALPHA.
    
  • (nodebb)

    In addition to explode, I suggest BOMB to trim spaces, SEEK to find a string inside another, DESTROY to replace all occurrences, NUKE to check if string is null or empty, and ANNIHILATE to get the length.

  • Ondřej Vágner (google) in reply to Mr. TA

    It's obviously HUNT to find a string inside another string.

  • Pnovdenx (unregistered)

    The creativity on date handling is limitless... My best WTF was the following ABAP (SAP) code I discovered in January.... month = month + 1 Which passes many tests as you may have 14 months (periods) in SAP...

  • RLB (unregistered)

    "Supplies are running low. We might not survive the winter." Tell that to Michael Gove...

  • Debra (unregistered)

    It's really beautiful in its own way. And the way how dates must be (judging from this code, at least) internally stored in the slash-delimited US-centric MM/DD/YY just makes me moist.

  • WTFGuy (unregistered)

    STOMP() is used to replace a substring with different contents.

    In years gone by I've used this trick many times: $MonthName = substr("JanFebMarAprMayJunJulAugSepOctNovDec", $TempDate[0] * 3 - 3, 3);

    For improved elegance, remove the "- 3" bias at the end and start the string param with a filler like "***JanFebMar...".

    It's amazing what heavy exposure to APL & SNOBOL early in one's career can do to one's taste in clear code.

  • (nodebb) in reply to bvs23bkv33

    Figures. Some people can program COBOL in any programming language!

  • (nodebb)

    I prefer it Remy when you do it like you did here, not explaining the WTF, letting the commenters do that.

    Addendum 2019-09-05 08:43: TRWTF is not allowing comments to be deleted.

  • scriptninja (github) in reply to WTFGuy

    I'll chime in. "DECIMATE" to parse a string as a decimal. If it fails to parse, it returns the length of the input string...divided by 10.

  • Little Bobby Tables (unregistered) in reply to scriptninja

    "Decimate" did not mean "to reduce to a tenth, it meant to reduce by a tenth. That is, to remove every tenth soldier, leaving 90% behind.

  • (nodebb) in reply to scriptninja

    I'll chime in. "DECIMATE" to parse a string as a decimal. If it fails to parse, it returns the length of the input string...divided by 10.

    I hope this means we also get: BINARATE, HEXAGONATE, OCTOGONATE, BOOLEANATE (TRIANGULATE?), NULLIFY (to reset a variable), and of course, STRINGIFY

  • (nodebb) in reply to WTFGuy

    I was coming here to reminisce about my APL coding days, but it's already taken.

  • (nodebb) in reply to Ondřej Vágner

    HUNT is for case insensitive.

  • Argle (unregistered)

    I think using a string as an instant array of boilerplate text isn't really a trick. I almost consider it standard technique. The best "trick" someone tossed at me was one of my students years ago. The assignment was to take an unsigned int and print the bits in binary. His bright idea was to cast the value to signed, check for negative and output 1 or 0 and then left-shift. Repeat 16 times. (This was a long time ago.) He became a friend and respected co-worker.

  • Argle (unregistered)

    I think using a string as an instant array of boilerplate text isn't really a trick. I almost consider it standard technique. The best "trick" someone tossed at me was one of my students years ago. The assignment was to take an unsigned int and print the bits in binary. His bright idea was to cast the value to signed, check for negative and output 1 or 0 and then left-shift. Repeat 16 times. (This was a long time ago.) He became a friend and respected co-worker.

  • eric bloedow (unregistered)

    reminds me of an old story on this site where someone used something like that "JanFebMar" string to VALIDATE dates...so it would accept "anF" or "nFe" as valid dates!

  • Brian Boorman (google) in reply to scriptninja

    Wrong. DECIMATE should return the length of the input string multiplied by 9/10ths, since the historical definition was the killing of 1 out of every 10 soldiers.

  • (nodebb) in reply to Argle

    He became a friend and respected co-worker.

    That would have been before or after you slapped him around for invoking undefined behaviour?

  • tbo (unregistered) in reply to Debra

    It's probably stored in a standard format, just formatted like that when retrieved.

  • Gene Wirchenko (unregistered) in reply to Mr. TA

    With the Hewlett-Packard 2000F BASIC, each command was unique for the first three characters so some were quite interesting. There was an operator command for moving a file to high-speed disk: SANCTIFY. There was a command to move the file back to normal storage: DESECRATE.

  • (nodebb) in reply to Pnovdenx

    If you're dealing with fiscal periods, then 13 is not unheard of:

    • if they're aligning with weeks rather than months (I have at least one client that uses fiscal "months" like this)
    • if they're transitioning from one fiscal calendar to another
    • if they define a one-day period for end-of-year corrections (to keep them separate from the last normal period of the fiscal year)

    I've worked with at least one off-the-shelf package that allowed up to 365 (366?), in case you wanted to get especially wacky about it.

  • RichP (unregistered)

    I don't know if I should be impressed/worried/sad/happy/confused that the original coder expected the program to last until 2020. (or that they expected it to be replaced before 2024).

  • (nodebb) in reply to emurphy

    On the other hand, one package I work with absolutely refuses to let you have any number of weekly periods in a year except 52. So in order to keep our periods aligned with the fiscal year, every five years or so we have one weekly period that's two weeks long. (We usually have a week over Chistmas/New Year where we don't do a payment run, so the double periods go there.)

  • (nodebb) in reply to Bananafish

    Serialising to an external resource would be EXTERMINATE.

  • (nodebb) in reply to Scarlet_Manuka

    I did work on a package for a customer who had fit all their accounting periods around the ISO calendar. Most quarters had 13 weeks, except the last which sometimes had 14 (again, though, this would be the Christmas/New Year period). ISO leap weeks aren't as frequent as Gregorian leap days, but they're a lot messier to forecast.

  • (nodebb)

    To those of us who learned in the old days the idea of chopping pieces out of a string in lieu of an array is second nature. Fewer CPU cycles, less memory consumption. (I got my start when we had 40k available.)

    Now, if you want to get creative: (Note, I don't speak PHP, I probably butchered the syntax):

    $DaysInMonth = substr("0303232332323", $TempDate[0], 1) + 28;

  • chazz (unregistered) in reply to P

    P: In PHP, variables are purely scoped within the function. If you want to use a variable defined outside the function, you must declare it global inside the function.

  • ichbinkeinroboter (unregistered) in reply to Bananafish

    javascript has JSON.stringify)= ...

  • I love oneliners (unregistered)

    return date('d', strtotime('-1 day', strtotime('+1 month first day of', DateTime::createFromFormat('d/m/Y', $SeasonStartDate)->getTimestamp())));

  • doubting_poster (unregistered) in reply to Argle

    I've done that to generate a simple random value on a bell curve - generate a random 32 bit number and count the ones. Though I did mod % 2 followed by shift right, which avoids ugly casting.

  • markm (unregistered) in reply to bvs23bkv33

    Love the COBOL definitions, but where is the PROCEDURE section to use it?

  • markm (unregistered)

    I've used the equivalent of

    $MonthName = substr("JanFebMarAprMayJunJulAugSepOctNovDec", $TempDate[0] * 3 - 3, 3);

    and it's inverse (month string to integer by searching for the first match and dividing by 3) before, in Turbo C and in various BASIC dialects that lacked a sufficiently powerful date-time library. (The PHP formula may be the same as the BASIC formula, but I think it would be off by one because the first letter of the string is index 1 rather than 0.) I hope that in the inverse conversion, I remembered to check that the int result was divisible by 3 so things like "anF" wouldn't slip through.

    OTOH, the leap year check makes me wonder if this programmer ever passed Algebra - or didn't bother to look up either the Julian or the Gregorian calendar. It's quite easy to write this to be good from 2001 to 2399, which normally should exceed the useful life of the software:

    leapYear = false; if((year % 4) == 0) leapYear = true; // It's easier to fully parenthesize than to look up the operator precedence

  • markm (unregistered)

    Excuse my error: The above formula is only good from 2001 to 2099. (And a lot of software written in the 1900's went off by one day on Feb 29, 2000.) If you think your software might still be running in 2100, see the longer formula below.

    If your language does not have a modulo operator ('%') or function, make sure 'year' is defined as an integer so year/4 is rounded down, and change that to

    if(((year/4) * 4) == year) leapYear = true;

    If you want this to be good from the establishment of the Gregorian calendar to whenever it is replaced in the far future, then:

    leapYear = false; if ((year % 400) != 100 && (year % 400) != 200 && (year % 400) != 300) if ((year % 4) == 0) leapYear = true;

    That is, to correct a slight drift in the Julian calendar (with a leap year every 4 years), Pope Gregory decreed that there are 97 leap years in 400 years instead of 100. That is, instead of 365.25 days in the year, it was 365.25 - 3/400 = 365.2425. The omitted leap years are the years divisible by 100 but not 400, that is 1700, 1800, 1900, 2100, 2200, 2300, 2500, etc. I find this formula to be remarkably simple, considering how accurate it is; the error is currently about 0.0003 days per year or 26 seconds a year. (Look up "mean tropical year").

    Eventually the Gregorian calendar will also drift out of synchronization with the seasons badly enough to need to be updated. I'm not sure if this will first happen because of any slight inaccuracy in his formula, or because the Earth's rotation is slowing, the precession is not entirely steady, etc.

  • (nodebb) in reply to markm

    $leapYear = !($year % (400 - 396 * ($year % 100 != 0)));

  • a person (unregistered) in reply to RichP

    Yes. Yes, you should.

  • (nodebb) in reply to Watson

    $leapYear = !($year % ($year % 100 ? 4 : 400));

  • jgh (unregistered)

    Yep, I've done both those substring month-name-to-number and day-in-month things way back when, when creating date manipulation libraries where none previously existed. But, unless you are the one creating the library itself, yes there's no need for the end-programmer to be doing that themselves.

    (Akcherly, you've given me an optimisation. I used "312831303130 etc" split by two, rather than 28+"303232 etc.)

  • JP (unregistered) in reply to P

    Because it's not unnecessary?

Leave a comment on “Give Your Date a Workout”

Log In or post as a guest

Replying to comment #:

« Return to Article