• Warren (unregistered)

    As dates go, this one's got to be stoned.

  • Bill (unregistered)

    Love the way getDateString returns a number

  • Walky_one (unregistered)

    It even includes error checking! The first 11 1/2 days of 1970 are invalid anyway. So let's just return -1...

  • (cs)

    For some purposes that calculation might actually be faster than the library function.

    One of the more complex features of C++ too that I have seen most coders get wrong.

    There is a concept in C++ of streaming to convert between strings and data objects, and dates and times are among those. In order to perform such a conversion you can create a "facet" which then gets used when you parse or print a date.

    It is good, of course, to create a facet and reuse it many times, especially in parsing, as it might be more efficient.

    Unfortunately I have seen user's code whereby the same facet is created time and again for every single date, then attached to a new locale and imbued. And it is, of course, very inefficient. Thank-you to certain profiling tools that enabled me to discover this inefficiency. I have fixed it at least 2 supposedly reputable companies.

    Remember that, when you print with a "printf" style format, something somewhere has to parse that format string. If we're going to use it multiple times, let's parse it just once and "store" the parsed result. But then lifetime management is one of the things that makes programming (in any language) less than trivial.

    DateFormat / SimpleDateFormat has been part of Java for a long time and does of course address that situation, but you need to hold on to your DateFormat object as long as you need it.

  • Xavier (unregistered)

    That's going to be fun when the code starts to be multithreaded, with the static Calendar instance

  • faoileag (unregistered)
    private static Calendar cal = Calendar.getInstance(); 
    cal.setTimeInMillis(currtime);

    That's the first time I have ever seen someone making a temporary reference holder introduced to keep lines short a static member of a class!

  • faoileag (unregistered) in reply to Xavier
    Xavier:
    That's going to be fun when the code starts to be multithreaded, with the static Calendar instance
    Not "when". "If".

    And if there is no intention to ever introduce multithreading into the application of which the given code is a part, then there is no need to make its classes thread-safe.

    Oh, and even if "cal" would not be a static member, the code would not be thread safe because in Java "cal" will hold a reference, not a copy. Especially since Calendar.getInstance() looks like the singleton pattern.

    So I assume multithreading will never be an issue with the code.

    Alternatively, the coders might still be on a level where they simply don't know about multithreading and its perils. Then of course they will be in for a nice surprise if the code is run as part of a muktithreaded application.

  • (cs)

    Of the last five articles here, three of them had something to do with dates. Has this turned into a dating site?

  • faoileag (unregistered) in reply to faoileag
    faoileag:
    since Calendar.getInstance() looks like the singleton pattern.
    I should read the relevant documentation before writing a post, not after.

    Turns out that Calendar.getInstance() returns an object with the relevant fields set to the current time and date, according to the docs.

    So I assume multiple calls to getInstance() will return references to different instances, although I couldn't find any clarification on that in the docs.

  • faoileag (unregistered) in reply to ochrist
    ochrist:
    Of the last five articles here, three of them had something to do with dates. Has this turned into a dating site?
    Dreaming of Gertrude, eh?

    Now why do I all of a sudden have a craving for the dried fruit of phoenix dactylifera?

  • (cs) in reply to faoileag
    faoileag:
    And if there is no intention to ever introduce multithreading into the application of which the given code is a part, then there is no need to make its classes thread-safe.
    The "My" in the classname is a code convention to indicate that there is only one instance and it shall never be used by different users at the same time.

    Actually it indicates that even one user at the same time can be troublesome.

    MySQL, MySpace, My Verizon, My Little Pony.

  • faoileag (unregistered) in reply to no laughing matter
    no laughing matter:
    Actually it indicates that even one user at the same time can be troublesome.

    MySQL, MySpace, My Verizon, My Little Pony.

    In the case of MySQL that would be Bobby, wouldn't it?

  • ZoomST (unregistered)

    Wait! I think I'm getting it:

        cal.setTimeInMillis(currtime);
        rv += 1000L*((long)cal.get(Calendar.SECOND)); 
        rv += 100000L*((long)cal.get(Calendar.MINUTE)); 
        rv += 10000000L*((long)cal.get(Calendar.HOUR_OF_DAY)); 
        rv += 1000000000L*((long)cal.get(Calendar.DAY_OF_MONTH)); 
        rv += 100000000000L*((long)(1+cal.get(Calendar.MONTH))); 
        rv += 10000000000000L*((long)cal.get(Calendar.YEAR)); 
        rv += 1000000000000000L*((long)cal.get(Calendar.CENTURY)); 
        rv += 100000000000000000L*((long)cal.get(Calendar.MILLENNIUM)); 
        return rv; 
    
    I'll add more lines as soon as I figure out what comes after the millennium (Falcon, perhaps?).

    Hey! If you tilt your head to the right, all these 0L nearly becomes LOLOLOLOL or something. So clever that is genius.

  • faoileag (unregistered) in reply to ZoomST
    ZoomST:
    Wait! I think I'm getting it:
        cal.setTimeInMillis(currtime);
        rv += 1000L*((long)cal.get(Calendar.SECOND)); 
        rv += 100000L*((long)cal.get(Calendar.MINUTE)); 
        rv += 10000000L*((long)cal.get(Calendar.HOUR_OF_DAY)); 
        rv += 1000000000L*((long)cal.get(Calendar.DAY_OF_MONTH)); 
        rv += 100000000000L*((long)(1+cal.get(Calendar.MONTH))); 
        rv += 10000000000000L*((long)cal.get(Calendar.YEAR)); 
        rv += 1000000000000000L*((long)cal.get(Calendar.CENTURY)); 
        rv += 100000000000000000L*((long)cal.get(Calendar.MILLENNIUM)); 
        return rv; 
    
    There's a bug in your code. Of the type "pattern trap".
  • (cs) in reply to faoileag
    faoileag:
    no laughing matter:
    Actually it indicates that even one user at the same time can be troublesome.

    MySQL, MySpace, My Verizon, My Little Pony.

    In the case of MySQL that would be Bobby, wouldn't it?

    I think that's very inconsiderate for all Bobbys across the world.

  • (cs) in reply to Bobby Tables
    Bobby Tables:
    faoileag:
    no laughing matter:
    Actually it indicates that even one user at the same time can be troublesome.

    MySQL, MySpace, My Verizon, My Little Pony.

    In the case of MySQL that would be Bobby, wouldn't it?
    I think that's very inconsiderate for all Bobbys across the world.
    I had a son once that was Bobby, and let me tell you, it was no laughing matter.

  • (cs) in reply to Severity One
    Severity One:
    Bobby Tables:
    faoileag:
    no laughing matter:
    Actually it indicates that even one user at the same time can be troublesome.

    MySQL, MySpace, My Verizon, My Little Pony.

    In the case of MySQL that would be Bobby, wouldn't it?
    I think that's very inconsiderate for all Bobbys across the world.
    I had a son once that was Bobby, and let me tell you, it was no laughing matter.

    I'd imagine - that wording leaves for some unfortunate implications.

  • Pock Suppet (unregistered) in reply to Cbuttius
    Cbuttius:
    For some purposes that calculation might actually be faster than the library function.
    "Let's see, we've removed 99.999999999% of the bottlenecks in our system; what's next? Ah, yes, date-to-string conversion."
  • ¯\(°_o)/¯ I DUNNO LOL (unregistered) in reply to faoileag
    faoileag:
    There's a bug in your code. Of the type "pattern trap".
    I saw it, too. Hint: how many centuries in a millennium? That's not even getting to the part where 'year' already includes the other two.
  • faoileag (unregistered) in reply to ¯\(°_o)/¯ I DUNNO LOL
    ¯\(°_o)/¯ I DUNNO LOL:
    faoileag:
    There's a bug in your code. Of the type "pattern trap".
    I saw it, too. Hint: how many centuries in a millennium?
    Oh, the centuries should be fine provided they are zero-based (Calendar uses zero-based numbers for the months, so that would fit the pattern). The digit for the millenium however...
  • faoileag (unregistered) in reply to faoileag
    faoileag:
    (Calendar uses zero-based numbers for the months...)
    Reading that again, here's the next bug in the code sample presented in the article - an off-by-one error for the months which is probably not intended looking at the timestamp pattern.
  • bob (unregistered)

    "you could leverage the handy built-in utilities"

    Spoken like someone who's never had to use them.

    Saying that, it looks as though they've sorted it in Java 8 - we'll see.

  • Charles F. (unregistered) in reply to faoileag
    faoileag:
    So I assume multithreading will never be an issue with the code.
    Thus was born many a WTF.

    Multithreading is frequently never an issue during testing. All of the Java (and C# etc., for that matter) code I've seen posted here is intended to run in a multi-threaded service container, so multi-threading is almost always an issue.

  • Charles F. (unregistered) in reply to Cbuttius
    Cbuttius:
    For some purposes that calculation might actually be faster than the library function.
    That might be true if the GregorianCalendar object in Java wasn't such a horrible pig. Setting the time causes a lot of internal state to be updated. You can go from epoch time to formatted dates in more direct ways, even in Java.
  • faoileag (unregistered) in reply to Charles F.
    Charles F.:
    faoileag:
    So I assume multithreading will never be an issue with the code.
    Thus was born many a WTF. ... All of the Java (and C# etc., for that matter) code I've seen posted here is intended to run in a multi-threaded service container
    How do you know from just the code snippets?
    Charles F.:
    so multi-threading is almost always an issue.
    Be that as it may but then you shouldn't use Calendar.getInstance()

    How can Akismet think a link to stack overflow is spam???

  • Charles F. (unregistered) in reply to faoileag
    faoileag:
    How do you know from just the code snippets?
    Usually there's accompanying context like "Hanzo found this in his university web application."
    faoileag:
    Charles F.:
    so multi-threading is almost always an issue.
    Be that as it may but then you shouldn't use Calendar.getInstance()
    Calendar.getInstance() is not the threading problem here. Storing the result in what amounts to a global variable is the problem.

    CAPTCHA: ingenium A rare element with a depressingly short half life.

  • (cs)
    third Circle of Hell ("dates")

    Interesting, just finished reading the Divine Comedy a few weeks back and (Who am I kidding, I read Inferno, sue me) I was thinking about this programming's hell too.

  • (cs) in reply to ochrist
    ochrist:
    Of the last five articles here, three of them had something to do with dates. Has this turned into a dating site?

    Quoth snoofle, "Dates are complicated things."
    Yep, they sure are. It starts with "It's not about the nail." http://vimeo.com/66753575 and goes into deeper madness from there.

  • (cs) in reply to ochrist
    ochrist:
    Of the last five articles here, three of them had something to do with dates. Has this turned into a dating site?

    Yeah, it happened on the frist of the month.

  • Martijn (unregistered)

    In defense of this abomination, I know of no standard library that handles DateTime(zone) stuff in a way that is not completely broken. Staying the hell away from it and rolling your own - even this - is not such a bad thing.

  • (cs) in reply to Martijn
    Martijn:
    I know of no standard library that handles DateTime(zone) stuff in a way that is not completely broken.
    You should get out more.
  • (cs) in reply to dkf
    dkf:
    Martijn:
    I know of no standard library that handles DateTime(zone) stuff in a way that is not completely broken.
    You should get out more.

    He would, but his Calendar Tool is broken 'cause the DateTime calculator backend crashes and he can't figure out when he was going to go where.

  • Chris Angelico (unregistered)

    I dread the day when someone will pick up that code, point out that it doesn't support sub-second displays, and change it all to use floating-point.

  • Done Right (unregistered)

    The correct format with SimpleDateFormat is "yyyyMMddHHmmss": h: Hour in am/pm (1-12) H: Hour in day (0-23)

    It's also a good idea to set the TimeZone, so it doesn't depend on the plaform's timezone. :)

  • Mason Wheeler (unregistered) in reply to Martijn
    Martijn:
    In defense of this abomination, I know of no standard library that handles DateTime(zone) stuff in a way that is not completely broken. Staying the hell away from it and rolling your own - even *this* - is not such a bad thing.
    A few months back, I was working on some code that was handling timezone conversions in a horribly broken way, leading to some very unhappy customers whenever the ST/DST time changed. So I looked at the code and said "this code is horribly broken. We ought to just use the standard library functions built in to the Delphi RTL." And I reworked it to do that, and suddenly things were fixed.
  • Martijn (unregistered) in reply to cellocgw
    cellocgw:
    dkf:
    Martijn:
    I know of no standard library that handles DateTime(zone) stuff in a way that is not completely broken.
    You should get out more.

    He would, but his Calendar Tool is broken 'cause the DateTime calculator backend crashes and he can't figure out when he was going to go where.

    I only have few things I want a DateTime object to do. Sadly I know of no DateTime in any lanugage that supports the following operations.

    • A datetime should be able to parse a datetimestring in a number of reasonable formats, at any valid ISO 8601 string combined with a timezone (an UTC offset is not an acceptable replacement, DST is a thing)
    • A datetime should be able to format to a number of reasonable formats, at least some form of ISO 8601
    • If I have a DateTime object, I should be able to ask its timezone
    • If I have a DateTime object and a TimeZone object, I should have an operation that returns a DateTime that represents the same instant in time, with that TimeZone
    • If I have two DateTime objects, I should have an operation that gives me the duration between the instants they represent, even if one of them is in one timezone, the other is in another timezone, DST changes in the period between them for one of them, and a leap second is added for the other.
    • Bonus points for being able to add convenience time spans like x weeks, months, days, hours and years. A day is not necessarily the same amount of hours or seconds (but this is no replacement of any of the others)
    • Some more bonus points if you have some of the following (again, no replacement for any of the others) ** A way to represent a time without a date or timezone (i.e. "7 P.M.") ** Convenience wrappers for a specific time interval ("from instant x to instant y")

    Joda/Noda works, but cumbersome - which is amazing enough apparently - and isn't a standard library. Other than that I wouldn't know.

  • Developer Dude (unregistered) in reply to faoileag
    faoileag:
    Xavier:
    That's going to be fun when the code starts to be multithreaded, with the static Calendar instance
    Not "when". "If".

    And if there is no intention to ever introduce multithreading into the application of which the given code is a part, then there is no need to make its classes thread-safe.

    Oh, and even if "cal" would not be a static member, the code would not be thread safe because in Java "cal" will hold a reference, not a copy. Especially since Calendar.getInstance() looks like the singleton pattern.

    So I assume multithreading will never be an issue with the code.

    Alternatively, the coders might still be on a level where they simply don't know about multithreading and its perils. Then of course they will be in for a nice surprise if the code is run as part of a muktithreaded application.

    While I agree that I agree that there may be no reason to go to great lengths to make code threadsafe if you don't know it will ever be used in multi-threaded code, there are some very simple practices that make code both more threadsafe and better code when not used in multi-threaded apps.

    That aside, Calendar.getInstance() is not a singleton pattern - it creates a new instance of Calendar for the given locale (if not locale is given, then it uses the current locale at time of invocation).

    The observation that static instance of the Calendar would be an issue with multi-threaded code is correct because the same Calendar object instance would be used by each instance of MyDateString, and setting the current "time" value for that instance could easily conflict with another thread setting that value concurrently.

    If the Calendar instance was not static, i.e., a new instance for each instance of MyDateString, and each thread had its own instance of MyDateString, then that would not be an issue.

    IMO, the author of the code probably thought he/she was saving memory by creating a static copy of Calendar - a case of premature optimization

  • (cs) in reply to Martijn
    Martijn:
    Sadly I know of no DateTime in any lanugage that supports the following operations.

    Natural solves most of these, but is mostly used on mainframes: http://documentation.softwareag.com/natural/nat638unx/pg/pg_furth_date.htm

    (although there are such things as Natural for Open Systems and Natural for Ajax)

  • Martijn (unregistered) in reply to ochrist
    ochrist:
    Martijn:
    Sadly I know of no DateTime in any lanugage that supports the following operations.

    Natural solves most of these, but is mostly used on mainframes: http://documentation.softwareag.com/natural/nat638unx/pg/pg_furth_date.htm

    (although there are such things as Natural for Open Systems and Natural for Ajax)

    After writing this I realised I haven't looked at Java 8's new DateTime API yet. It might handle this. It's still a shite state of affairs that these operations are not the norm.

  • anon (unregistered)

    or...don't use java. it's pure evil!

  • Josh (unregistered) in reply to Bobby Tables
    Bobby Tables:
    Severity One:
    Bobby Tables:
    faoileag:
    no laughing matter:
    Actually it indicates that even one user at the same time can be troublesome.

    MySQL, MySpace, My Verizon, My Little Pony.

    In the case of MySQL that would be Bobby, wouldn't it?
    I think that's very inconsiderate for all Bobbys across the world.
    I had a son once that was Bobby, and let me tell you, it was no laughing matter.

    I'd imagine - that wording leaves for some unfortunate implications.

    Dammit Bobby!

  • n_slash_a (unregistered) in reply to ochrist
    ochrist:
    Of the last five articles here, three of them had something to do with dates. Has this turned into a dating site?
    Cue stream of jokes about "the president's daughter"
  • Martijn (unregistered) in reply to anon
    anon:
    or...don't use java. it's pure evil!

    True, but it might turn out to be the only reasonable DateTime library in the stdlib. C? no. C++? no. Python? no. Ruby? no. Lua? what stdlib? .NET? no. SQL? lolno. Rust? no.

    Maybe Go or Haskell, I wouldn't know about those.

  • evilspoons (unregistered) in reply to bob
    bob:
    "you could leverage the handy built-in utilities"

    Spoken like someone who's never had to use them.

    Saying that, it looks as though they've sorted it in Java 8 - we'll see.

    I'll be happy with Java 8 if the only change they make is the ceasing of attempting to trick users into installing %$#&ing Ask Toolbar. Every damn time Java updates I have to head down to the finance person's PC - they need Java for the bank's 2-factor auth - and remove Ask Toolbar (or perform the update myself).

    A runtime for a programming language should not come bundled with adware. Grr.

    (Is there any way around this I'm not aware of?)

  • SmaugsLair (unregistered) in reply to ochrist

    I'm hoping to get hooked up with Paula Bean!

  • (cs) in reply to n_slash_a
    n_slash_a:
    ochrist:
    Of the last five articles here, three of them had something to do with dates. Has this turned into a dating site?
    Cue stream of jokes about "the president's daughter"
    No, we want Irish girl back.
  • Jim (unregistered) in reply to Martijn
    Martijn:
    cellocgw:
    dkf:
    Martijn:
    I know of no standard library that handles DateTime(zone) stuff in a way that is not completely broken.
    You should get out more.

    He would, but his Calendar Tool is broken 'cause the DateTime calculator backend crashes and he can't figure out when he was going to go where.

    I only have few things I want a DateTime object to do. Sadly I know of no DateTime in any lanugage that supports the following operations.

    • A datetime should be able to parse a datetimestring in a number of reasonable formats, at any valid ISO 8601 string combined with a timezone (an UTC offset is not an acceptable replacement, DST is a thing)
    • A datetime should be able to format to a number of reasonable formats, at least some form of ISO 8601
    • If I have a DateTime object, I should be able to ask its timezone
    • If I have a DateTime object and a TimeZone object, I should have an operation that returns a DateTime that represents the same instant in time, with that TimeZone
    • If I have two DateTime objects, I should have an operation that gives me the duration between the instants they represent, even if one of them is in one timezone, the other is in another timezone, DST changes in the period between them for one of them, and a leap second is added for the other.
    • Bonus points for being able to add convenience time spans like x weeks, months, days, hours and years. A day is not necessarily the same amount of hours or seconds (but this is no replacement of any of the others)
    • Some more bonus points if you have some of the following (again, no replacement for any of the others) ** A way to represent a time without a date or timezone (i.e. "7 P.M.") ** Convenience wrappers for a specific time interval ("from instant x to instant y")

    Joda/Noda works, but cumbersome - which is amazing enough apparently - and isn't a standard library. Other than that I wouldn't know.

    "None of them are complete/perfect" is quite different to "completely broken"

    And usually the "roll your own" one are less functional then the existing libs....so unless you expect people to roll their own with all the functionality you've mentioned above I'm not sure you can make a case for "Staying the hell away from it and rolling your own - even this - is not such a bad thing".

    Or perhaps you've been rolling your own.....

  • Øyvind (unregistered) in reply to Martijn
    Martijn:
    I only have few things I want a DateTime object to do. Sadly I know of no DateTime in any lanugage that supports the following operations. [...]
    I almost cried the first time I read the new Java Timing API, after wrestling time zones for the nth time:

    http://download.java.net/jdk8/docs/api/index.html?java/time/package-summary.html

  • (cs)

    Is it just me, or are 'long' variables limited to 32 bits. If so, this code has a bunch more problems than being an obtuse method of fancying up a date to a bunch of digits to play with.

    In other words: "Use the system routines, they have (we hope) been tested/used by others".

    Note to self: Retire before 2038 (maybe before Jan 19, 2038). Pick up the end of year bonus, and wait a week into the new year!

  • (cs) in reply to Martijn
    Martijn:

    I only have few things I want a DateTime object to do. Sadly I know of no DateTime in any lanugage that supports the following operations.

    • A datetime should be able to parse a datetimestring in a number of reasonable formats, at any valid ISO 8601 string combined with a timezone (an UTC offset is not an acceptable replacement, DST is a thing)
    • A datetime should be able to format to a number of reasonable formats, at least some form of ISO 8601
    • If I have a DateTime object, I should be able to ask its timezone
    • If I have a DateTime object and a TimeZone object, I should have an operation that returns a DateTime that represents the same instant in time, with that TimeZone
    • If I have two DateTime objects, I should have an operation that gives me the duration between the instants they represent, even if one of them is in one timezone, the other is in another timezone, DST changes in the period between them for one of them, and a leap second is added for the other.
    • Bonus points for being able to add convenience time spans like x weeks, months, days, hours and years. A day is not necessarily the same amount of hours or seconds (but this is no replacement of any of the others)
    • Some more bonus points if you have some of the following (again, no replacement for any of the others) ** A way to represent a time without a date or timezone (i.e. "7 P.M.") ** Convenience wrappers for a specific time interval ("from instant x to instant y")

    Joda/Noda works, but cumbersome - which is amazing enough apparently - and isn't a standard library. Other than that I wouldn't know.

    Try XQuery

Leave a comment on “Date Formatting Done Right”

Log In or post as a guest

Replying to comment #426627:

« Return to Article