Int->String formatting method

Discussion in 'Java' started by Deniz Dogan, Sep 26, 2006.

  1. Deniz Dogan

    Deniz Dogan Guest

    Hello again! Yes, I have yet another problem for all of you great
    programmers in here.

    This should actually be a pretty easy task to complete, but somehow the
    blood in my veins doesn't seem to flow the right way just now. Here's
    the problem:
    I have an amount of milliseconds, in the range [0,Integer.MAX_VALUE] and
    I want to format it to a String of the format "HH:nn:ss,mmm" where HH
    ranges between 00-99, nn between 00-59, ss between 00-59 and mmm between
    000-999 (all of the ranges inclusive).
    The only thing I can come up with now as a solution is a bunch of
    if-then-else statements, but really now, we shouldn't have to go and do
    that, do we?

    I love stating problems. Looking forward to your help.

    /Deniz Dogan
     
    Deniz Dogan, Sep 26, 2006
    #1
    1. Advertising

  2. Deniz Dogan

    Deniz Dogan Guest

    Deniz Dogan wrote:
    > Hello again! Yes, I have yet another problem for all of you great
    > programmers in here.
    >
    > This should actually be a pretty easy task to complete, but somehow the
    > blood in my veins doesn't seem to flow the right way just now. Here's
    > the problem:
    > I have an amount of milliseconds, in the range [0,Integer.MAX_VALUE] and
    > I want to format it to a String of the format "HH:nn:ss,mmm" where HH
    > ranges between 00-99, nn between 00-59, ss between 00-59 and mmm between
    > 000-999 (all of the ranges inclusive).
    > The only thing I can come up with now as a solution is a bunch of
    > if-then-else statements, but really now, we shouldn't have to go and do
    > that, do we?
    >
    > I love stating problems. Looking forward to your help.
    >
    > /Deniz Dogan


    Disregard my post, a friend of mine solved it on four rows of code and
    O(1) fashion.
     
    Deniz Dogan, Sep 26, 2006
    #2
    1. Advertising

  3. Deniz Dogan

    Oliver Wong Guest

    "Deniz Dogan" <> wrote in message
    news:efanv0$l2m$...
    > Deniz Dogan wrote:
    >> Hello again! Yes, I have yet another problem for all of you great
    >> programmers in here.
    >>
    >> This should actually be a pretty easy task to complete, but somehow the
    >> blood in my veins doesn't seem to flow the right way just now. Here's the
    >> problem:
    >> I have an amount of milliseconds, in the range [0,Integer.MAX_VALUE] and
    >> I want to format it to a String of the format "HH:nn:ss,mmm" where HH
    >> ranges between 00-99, nn between 00-59, ss between 00-59 and mmm between
    >> 000-999 (all of the ranges inclusive).
    >> The only thing I can come up with now as a solution is a bunch of
    >> if-then-else statements, but really now, we shouldn't have to go and do
    >> that, do we?
    >>
    >> I love stating problems. Looking forward to your help.
    >>
    >> /Deniz Dogan

    >
    > Disregard my post, a friend of mine solved it on four rows of code and
    > O(1) fashion.


    You should have post the solution, in case someone in the future
    stumbles upon this post via google and has a similar problem and is looking
    for the solution.

    here's my guess at the solution:

    public static String toTimeString(long milliseconds) {
    final long MS_PER_SEC = 1000;
    final long MS_PER_MIN = MS_PER_SEC * 60;
    final long MS_PER_HOUR = MS_PER_MIN * 60;
    final long hours = milliseconds / MS_PER_HOUR;
    milliseconds %= MS_PER_HOUR;
    final long minutes = milliseconds / MS_PER_MIN;
    milliseconds %= MS_PER_MIN;
    final long seconds = milliseconds / MS_PER_SEC;
    milliseconds %= MS_PER_SEC;
    StringBuffer sb = new StringBuffer();
    sb.append(hours);
    sb.append(":");
    sb.append(minutes);
    sb.append(":");
    sb.append(seconds);
    sb.append(",");
    sb.append(milliseconds);
    return sb.toString();
    }

    - Oliver
     
    Oliver Wong, Sep 26, 2006
    #3
  4. Deniz Dogan

    Deniz Dogan Guest

    Oliver Wong wrote:
    >
    > "Deniz Dogan" <> wrote in message
    > news:efanv0$l2m$...
    >> Deniz Dogan wrote:
    >>> Hello again! Yes, I have yet another problem for all of you great
    >>> programmers in here.
    >>>
    >>> This should actually be a pretty easy task to complete, but somehow
    >>> the blood in my veins doesn't seem to flow the right way just now.
    >>> Here's the problem:
    >>> I have an amount of milliseconds, in the range [0,Integer.MAX_VALUE]
    >>> and I want to format it to a String of the format "HH:nn:ss,mmm"
    >>> where HH ranges between 00-99, nn between 00-59, ss between 00-59 and
    >>> mmm between 000-999 (all of the ranges inclusive).
    >>> The only thing I can come up with now as a solution is a bunch of
    >>> if-then-else statements, but really now, we shouldn't have to go and
    >>> do that, do we?
    >>>
    >>> I love stating problems. Looking forward to your help.
    >>>
    >>> /Deniz Dogan

    >>
    >> Disregard my post, a friend of mine solved it on four rows of code and
    >> O(1) fashion.

    >
    > You should have post the solution, in case someone in the future
    > stumbles upon this post via google and has a similar problem and is
    > looking for the solution.
    >
    > here's my guess at the solution:
    >
    > public static String toTimeString(long milliseconds) {
    > final long MS_PER_SEC = 1000;
    > final long MS_PER_MIN = MS_PER_SEC * 60;
    > final long MS_PER_HOUR = MS_PER_MIN * 60;
    > final long hours = milliseconds / MS_PER_HOUR;
    > milliseconds %= MS_PER_HOUR;
    > final long minutes = milliseconds / MS_PER_MIN;
    > milliseconds %= MS_PER_MIN;
    > final long seconds = milliseconds / MS_PER_SEC;
    > milliseconds %= MS_PER_SEC;
    > StringBuffer sb = new StringBuffer();
    > sb.append(hours);
    > sb.append(":");
    > sb.append(minutes);
    > sb.append(":");
    > sb.append(seconds);
    > sb.append(",");
    > sb.append(milliseconds);
    > return sb.toString();
    > }
    >
    > - Oliver


    And here's my friend's solution:

    public static String formatMillis(int millis) {
    int ihh = millis/3600000; //amount of hours
    int inn = (millis - ihh*3600000) / 60000; //amount of minutes
    int iss = (millis - (ihh*3600000) - (inn * 60000)) / 1000; //amount
    of seconds
    int immm = (millis - (ihh*3600000) - (inn * 60000)) - iss*1000;
    //amount of milliseconds
    //String representations of the integers:
    String mmm = "" + immm, ss = "" + iss, nn = "" + inn, hh = "" + ihh;
    //Making sure the lengths of the Strings are correct:
    if (mmm.length() == 1) mmm = "00" + mmm;
    else if (mmm.length() == 2) mmm = "0" + mmm;
    if (ss.length() == 1) ss = "0" + ss;
    if (nn.length() == 1) nn = "0" + nn;
    if (hh.length() == 1) hh = "0" + hh;
    return hh + ":" + nn + ":" + ss + "," + mmm;
    }

    I have a question for you Oliver (or anyone else who'd want to answer
    this question), is your solution faster than mine? I considered using
    the modulo operator, but I wasn't sure how the JVM would implement it. I
    figured it would just do a lot of division operations until it couldn't
    divide it any more, but perhaps it implements it in a different manner?

    - Deniz Dogan
     
    Deniz Dogan, Sep 27, 2006
    #4
  5. Deniz Dogan wrote:
    > I have a question for you Oliver (or anyone else who'd want to answer
    > this question), is your solution faster than mine?


    It does not matter. Unless you have evidence that an implementation
    really affects an application's performance in an unacceptable way there
    are more important criteria to judge an algorithm's implementation. E.g.
    maintainability, or robustness regarding change.

    > I considered using
    > the modulo operator, but I wasn't sure how the JVM would implement it. I
    > figured it would just do a lot of division operations until it couldn't
    > divide it any more, but perhaps it implements it in a different manner?


    That would be an extremely brain-dead thing to do. Sun programmers do a
    lot of strange and stupid things in the JDK, but I can't imagine they
    would do such a brain-dead modulo operator in the VM. They probably use
    the C modulo operator which is probably translated into a modulo
    assembler instruction - if the particular CPU provides such an
    instruction. Or it is translated into a call into some assembler library
    - if an old CPU doesn't provide such an assembler instruction or one
    that doesn't fit the JLS modulo definition.

    Simplified and broad speaking, the reminder is a by-product of binary
    integer division algorithms, and as such usually does take the same or
    similar time as a single integer division, whether done in hardware
    (CPU' ALU) or software. Don't they teach binary arithmetic in school
    any more?

    But again, it doesn't matter. As long as you have no evidence that a
    particular operation affects your application in an unacceptable way,
    you are wasting your time trying to "optimize" such things.

    /Thomas
    --
    The comp.lang.java.gui FAQ:
    http://gd.tuwien.ac.at/faqs/faqs-hierarchy/comp/comp.lang.java.gui/
    ftp://ftp.cs.uu.nl/pub/NEWS.ANSWERS/computer-lang/java/gui/faq
     
    Thomas Weidenfeller, Sep 27, 2006
    #5
  6. Deniz Dogan

    Wibble Guest

    Thomas Weidenfeller wrote:
    > Deniz Dogan wrote:
    >> I have a question for you Oliver (or anyone else who'd want to answer
    >> this question), is your solution faster than mine?

    >
    > It does not matter. Unless you have evidence that an implementation
    > really affects an application's performance in an unacceptable way there
    > are more important criteria to judge an algorithm's implementation. E.g.
    > maintainability, or robustness regarding change.
    >
    >> I considered using the modulo operator, but I wasn't sure how the JVM
    >> would implement it. I figured it would just do a lot of division
    >> operations until it couldn't divide it any more, but perhaps it
    >> implements it in a different manner?

    >
    > That would be an extremely brain-dead thing to do. Sun programmers do a
    > lot of strange and stupid things in the JDK, but I can't imagine they
    > would do such a brain-dead modulo operator in the VM. They probably use
    > the C modulo operator which is probably translated into a modulo
    > assembler instruction - if the particular CPU provides such an
    > instruction. Or it is translated into a call into some assembler library
    > - if an old CPU doesn't provide such an assembler instruction or one
    > that doesn't fit the JLS modulo definition.
    >
    > Simplified and broad speaking, the reminder is a by-product of binary
    > integer division algorithms, and as such usually does take the same or
    > similar time as a single integer division, whether done in hardware
    > (CPU' ALU) or software. Don't they teach binary arithmetic in school
    > any more?
    >
    > But again, it doesn't matter. As long as you have no evidence that a
    > particular operation affects your application in an unacceptable way,
    > you are wasting your time trying to "optimize" such things.
    >
    > /Thomas

    That said, Oliver's use of StringBuffer instead of + will
    make his code much faster.
     
    Wibble, Sep 27, 2006
    #6
  7. Deniz Dogan

    Deniz Dogan Guest

    Wibble wrote:
    > Thomas Weidenfeller wrote:

    [snip]
    > That said, Oliver's use of StringBuffer instead of + will
    > make his code much faster.


    I trust you on that one, but I feel obliged to ask why?

    - Deniz Dogan
     
    Deniz Dogan, Sep 27, 2006
    #7
  8. Deniz Dogan

    Oliver Wong Guest

    "Deniz Dogan" <> wrote in message
    news:efds1n$msv$...
    > Wibble wrote:
    >> Thomas Weidenfeller wrote:

    > [snip]
    >> That said, Oliver's use of StringBuffer instead of + will
    >> make his code much faster.

    >
    > I trust you on that one, but I feel obliged to ask why?


    First of all, my code is incorrect, because I forgot to check if I need
    to prefix '0' before certain of the numbers. For example, I might generate
    "1:1:1,1" instead of "01:01:01,0001".

    The exact reason that StringBuffer is faster is that String is difficult
    to explain. With a lot of hand waving, the overall reason is String is
    immutable, but StringBuilder is not, so String has to do a lot of
    contortions to progressively build up the output String, whereas
    StringBuilder can perform the String construction in the "obvious" way.

    - Oliver
     
    Oliver Wong, Sep 27, 2006
    #8
  9. Deniz Dogan

    Oliver Wong Guest

    "Thomas Weidenfeller" <> wrote in message
    news:efddev$c86$...
    > Deniz Dogan wrote:
    >> I considered using the modulo operator, but I wasn't sure how the JVM
    >> would implement it. I figured it would just do a lot of division
    >> operations until it couldn't divide it any more, but perhaps it
    >> implements it in a different manner?

    >
    > That would be an extremely brain-dead thing to do. Sun programmers do a
    > lot of strange and stupid things in the JDK, but I can't imagine they
    > would do such a brain-dead modulo operator in the VM. They probably use
    > the C modulo operator which is probably translated into a modulo assembler
    > instruction - if the particular CPU provides such an instruction. Or it is
    > translated into a call into some assembler library - if an old CPU doesn't
    > provide such an assembler instruction or one that doesn't fit the JLS
    > modulo definition.


    I think that modern x86 Intel and AMD chips have a built in modulo
    operator. For CPUs which don't have modulo, you could implement it like
    this:

    C = A % B

    temp = A / B
    temp = B * A
    C = A - temp

    So worst case, an integer modulo would take up 3 "normal" integer
    operations worth of time. The usage of "temp" implies an extra register, but
    "temp" and "C" could use the same register.

    - Oliver
     
    Oliver Wong, Sep 27, 2006
    #9
  10. Deniz Dogan

    Deniz Dogan Guest

    Oliver Wong wrote:
    >
    > "Deniz Dogan" <> wrote in message
    > news:efds1n$msv$...
    >> Wibble wrote:
    >>> Thomas Weidenfeller wrote:

    >> [snip]
    >>> That said, Oliver's use of StringBuffer instead of + will
    >>> make his code much faster.

    >>
    >> I trust you on that one, but I feel obliged to ask why?

    >
    > First of all, my code is incorrect, because I forgot to check if I
    > need to prefix '0' before certain of the numbers. For example, I might
    > generate "1:1:1,1" instead of "01:01:01,0001".


    Yes, that's exactly why I didn't quite see how your code was faster.
    (And also, the milliseconds should be 001, not 0001 ;-))

    > The exact reason that StringBuffer is faster is that String is
    > difficult to explain. With a lot of hand waving, the overall reason is
    > String is immutable, but StringBuilder is not, so String has to do a lot
    > of contortions to progressively build up the output String, whereas
    > StringBuilder can perform the String construction in the "obvious" way.


    I think I got it, thanks a lot for your help!
     
    Deniz Dogan, Sep 27, 2006
    #10
  11. Thomas Weidenfeller wrote:
    > Deniz Dogan wrote:
    >> I have a question for you Oliver (or anyone else who'd want to answer
    >> this question), is your solution faster than mine?

    >
    > It does not matter. Unless you have evidence that an implementation
    > really affects an application's performance in an unacceptable way there
    > are more important criteria to judge an algorithm's implementation. E.g.
    > maintainability, or robustness regarding change.


    Yep.

    I would consider the following good enough even though
    it is 3 times slower than the proposed code:

    private final static DateFormat df = new
    SimpleDateFormat("HH:mm:ss,SSS");
    public static String formatMillis3(int millis) {
    return df.format(new Date(millis -
    TimeZone.getDefault().getOffset(millis)));
    }

    Arne
     
    =?UTF-8?B?QXJuZSBWYWpow7hq?=, Sep 30, 2006
    #11
  12. Wibble wrote:
    > That said, Oliver's use of StringBuffer instead of + will
    > make his code much faster.


    No it does not.

    When I test the String code and the StringBuffer code
    (fixed to properly add leading zeroes), then the String
    code as actually fastest.

    That may vary based on platform, Java version etc..

    But it is not much faster.

    There are simply too few appends on too short
    strings to really bring up the StringBuffer advantage.

    Arne
     
    =?UTF-8?B?QXJuZSBWYWpow7hq?=, Sep 30, 2006
    #12
  13. Deniz Dogan

    Deniz Dogan Guest

    Arne Vajhøj wrote:
    > Thomas Weidenfeller wrote:
    >> Deniz Dogan wrote:
    >>> I have a question for you Oliver (or anyone else who'd want to answer
    >>> this question), is your solution faster than mine?

    >>
    >> It does not matter. Unless you have evidence that an implementation
    >> really affects an application's performance in an unacceptable way
    >> there are more important criteria to judge an algorithm's
    >> implementation. E.g. maintainability, or robustness regarding change.

    >
    > Yep.
    >
    > I would consider the following good enough even though
    > it is 3 times slower than the proposed code:
    >
    > private final static DateFormat df = new
    > SimpleDateFormat("HH:mm:ss,SSS");
    > public static String formatMillis3(int millis) {
    > return df.format(new Date(millis -
    > TimeZone.getDefault().getOffset(millis)));
    > }
    >
    > Arne


    This code was actually what I was looking for in the first place! I
    love pretty Java, no matter how slow it is.
     
    Deniz Dogan, Oct 1, 2006
    #13
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Schnoffos
    Replies:
    2
    Views:
    1,220
    Martien Verbruggen
    Jun 27, 2003
  2. Hal Styli
    Replies:
    14
    Views:
    1,646
    Old Wolf
    Jan 20, 2004
  3. arun
    Replies:
    8
    Views:
    457
    Dave Thompson
    Jul 31, 2006
  4. aling
    Replies:
    8
    Views:
    957
    Jim Langston
    Oct 20, 2005
  5. Replies:
    9
    Views:
    436
    James Kanze
    Apr 17, 2007
Loading...

Share This Page