-5

I need to get the number days, hours, minutes, seconds from a long value. But I am getting wrong number of days from a following code.

public static String formatTimeUTC(long value, String pattern) {
    final SimpleDateFormat format = new SimpleDateFormat(pattern, Locale.US);
    format.setTimeZone(TimeZone.getTimeZone("UTC"));
    Date date = new Date(value);
    String formatString = format.format(date);
    return formatString;
}

When I pass 106988550 and "dd:HH:mm:ss" to this method, I am getting "02:05:43:08"

Expected actual answer is : "01:05:43:08".

I don't know where it is wrong and how I can achieve the actual answer.

halfer
  • 19,824
  • 17
  • 99
  • 186
Gunaseelan
  • 14,415
  • 11
  • 80
  • 128
  • 2
    Add code as text not as image – Jens Dec 09 '16 at 12:36
  • You could be around long enough to understand that one **never** ever puts up code as **screen shot**. It is text; and we have **markup** for code here! And then I am wondering: creating a date from a long value has (on a first glance) nothing to do with how that date is formatted. Are you sure that the incoming value is what you expect?! Long story short: put up a http://stackoverflow.com/help/mcve – GhostCat Dec 09 '16 at 12:36
  • 2
    No, you dont have that. Create an mcve; because all the things that matter for your question can be shown as pure TEXT. – GhostCat Dec 09 '16 at 12:39
  • how are you parsing the string to date? – ΦXocę 웃 Пepeúpa ツ Dec 09 '16 at 12:39
  • @Gunaseelan you are right but if you add image to show us debug values but if you also code then this will be useful for others image if image was removed later. – Sohail Zahid Dec 09 '16 at 12:41
  • 1
    @Gunaseelan Again, you do **not** use a debugger screenshot to show the values you are using. You create a mcve that gives them in text and allows for **repros**. Heck, it takes **less* time to put down the code for that than creating those screenshots and attaching them here. – GhostCat Dec 09 '16 at 12:43
  • @GhostCat Thanks for your info, If you don't mind May I know what is mcve? And how to create it. – Gunaseelan Dec 09 '16 at 12:47
  • 1
    @Gunaseelan See the second comment; I put a link there! – GhostCat Dec 09 '16 at 12:50

4 Answers4

1

The expression System.out.println(formatTimeUTC(106988550L, "dd:HH:mm:ss")); is indeed expected to print one day extra (02:05:43:08). Why?

Abstract:

The class SimpleDateFormat is NOT designed to print durations but points in time. The same can be said for the old type java.util.Date which is not a duration but an instant.

Concrete:

The pattern part "dd" instructs the formatter to print the nominal day-of-month, not the count of days since UNIX epoch. In this case, it is part of the calendar date 1970-01-02T05:43:08.550. So you need to subtract one day from the original date 1 on UNIX epoch.

Alternatives:

As you can see it gets pretty awkward to print durations this way (by misusing the class SimpleDateFormat which is not designed for this purpose). I recommend to use better APIs. For example Joda-Time or my library Time4J:

Joda-Time (based on builder-approach):

PeriodFormatter pf =
    new PeriodFormatterBuilder().minimumPrintedDigits(2).appendDays().appendLiteral(":")
    .appendHours().appendLiteral(":").appendMinutes().appendLiteral(":").appendSeconds()
    .toFormatter();
long v = 106988550L;
System.out.println(
    pf.print(new Period(v, PeriodType.dayTime()).normalizedStandard())); // 01:05:43:08

For Android: Use the adaptation Joda-Time-Android.


Time4J (based on pattern approach):

long v = 106988550L;
Duration<IsoUnit> duration = Duration.of(v, ClockUnit.MILLIS);
System.out.println(
    Duration.formatter("DD:hh:mm:ss").format(duration.with(Duration.STD_PERIOD))
); // 01:05:43:08

For Android: Use the sister project Time4A.


You might also investigate the class DateUtils built into Android platform although I am not sure if it is suitable for your purpose since its API is awkward (you would need to set a combination of bit flags anyway).

Meno Hochschild
  • 42,708
  • 7
  • 104
  • 126
1

The Answer by Hochschild is correct. You are handling a span of time as a date-time, liking mixing apples with oranges.

java.time

The java.time classes supplant the troublesome old date-time classes. Makes easy work of this.

You do not actually explain, but I am guessing your number is a count of elapsed milliseconds.

long input = 106_988_550L ;

We represent that as a Duration.

Duration d = Duration.ofMillis( input );

We can represent that value as a string formatted with a subset of standard ISO 8601 format for durations, PTnHnMnS.

String output = d.toString();

PT29H43M8.55S

See live code in IdeOne.com.

In Java 9 and later, you can access each component of that value by calling the to…Part methods such as toDaysPart, toHoursPart, etc.


About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

Where to obtain the java.time classes?

  • Java SE 8 and SE 9 and later
    • Built-in.
    • Part of the standard Java API with a bundled implementation.
    • Java 9 adds some minor features and fixes.
  • Java SE 6 and SE 7
    • Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
  • Android

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

Community
  • 1
  • 1
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
0

change your TimeZone this

format.setTimeZone(TimeZone.getTimeZone("UTC"));

to this

format.setTimeZone(TimeZone.getTimeZone("GMT+0:00"));

and check the output.

Harshad Pansuriya
  • 20,189
  • 8
  • 67
  • 95
0

You can use java.time.Duration which is modelled on ISO-8601 standards and was introduced with Java-8 as part of JSR-310 implementation. With Java-9 some more convenience methods were introduced.

Demo:

import java.time.Duration;

public class Main {
    public static void main(String[] args) {
        long value = 106988550;

        Duration duration = Duration.ofMillis(value);
        // Default format
        System.out.println(duration);

        // Custom format
        // ####################################Java-8####################################
        String formattedElapsedTime = String.format("%02d:%02d:%02d:%02d", duration.toDays(), duration.toHours() % 24,
                duration.toMinutes() % 60, duration.toSeconds() % 60);
        System.out.println(formattedElapsedTime);
        // ##############################################################################

        // ####################################Java-9####################################
        formattedElapsedTime = String.format("%02d:%02d:%02d:%02d", duration.toDaysPart(), duration.toHoursPart(),
                duration.toMinutesPart(), duration.toSecondsPart());
        System.out.println(formattedElapsedTime);
        // ##############################################################################
    }
}

Output:

PT29H43M8.55S
01:05:43:08
01:05:43:08

Learn about the modern date-time API from Trail: Date Time.

Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110