2

I am having milliseconds value and want to display the time subtracting 5 minutes from current milliseconds value in hh:mm:ss format.

Code

String str = String.format("%02d:%02d:%02d", 
                                TimeUnit.MILLISECONDS.toHours((cal.getTimeInMillis()-300000)),
                                TimeUnit.MILLISECONDS.toMinutes(cal.getTimeInMillis()-300000) - 
                                TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(cal.getTimeInMillis()-300000)),
                                TimeUnit.MILLISECONDS.toSeconds(cal.getTimeInMillis()-300000) - 
                                TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(cal.getTimeInMillis()-300000)));

Toast.makeText(getApplicationContext(), "Alarm Set."+str, Toast.LENGTH_LONG).show()

Output now

Alarm Set. 386467:25:00

Output Required

Alarm Set. 07:25:00

As you see minutes and seconds are getting retrieved quiet right but there's some problem with hours.

P.S

1.I referred this post.They say it works fine.But don't know why not in my case.

2.I am sure about what i want to get as hours value i.e 07 as i have set the value using Calendar.HOUR and its getting displayed too if i use cal.get(Calendar.HOUR).cal is of course object of Calendar class.

Alternative Solution

 SimpleDateFormat sdf = new SimpleDateFormat("hh:mm:ss");
 String str1 = sdf.format(new Date(cal.getTimeInMillis()-300000));
 Toast.makeText(getApplicationContext(), "Alarm Set."+str1, Toast.LENGTH_LONG).show();
Cœur
  • 32,421
  • 21
  • 173
  • 232
Sash_KP
  • 5,403
  • 2
  • 22
  • 34
  • Use SimpleDateFormat, as I see someone has suggested. Then just format your time - the appropriate number of millis. – user1676075 Jan 31 '14 at 15:03
  • I did use that and solved the problem.Thanks.But still want to know what's the problem in this code snippet as others say this is working fine. – Sash_KP Jan 31 '14 at 15:32
  • 1
    That solution as written won't work. Take just the first hours value for instance. If the current time is 2 seconds after the hour, it will still display the current hour, because you're not subtracting any time from the hours value. What about minutes? If the current minutes is 2, and you subtract 5, what will it get you? The right approach is to get the time in millis, subtract 5 minutes, then just output the values. That ought to work. But even then using SimpleDateFormat makes more sense. – user1676075 Jan 31 '14 at 18:43
  • What does First hour mean?And i have nothing to do with current hour and current minute in this case.I just set an alarm in my app which will trigger before 5 minutes of the set time. – Sash_KP Jan 31 '14 at 18:56
  • 1
    Ah, what wasn't clear is that you're looking for relative time (your milliseconds value is already supposed to be just time remaining until the timer expires). The other post you reference is a "time remaining in millis" (so, timerExpiration - System.currentTimeMillis(), for example). As I think one of the answers explains, your value is off for hours because you're showing time at which it expires, not time remaining until it expires. I think that explains the confusion. – user1676075 Jan 31 '14 at 20:03
  • Wow.Now i got it.It was so difficult for me to understand even why those subtractions were taking place.Thanks a lot.Could you please have a look at [this post](http://stackoverflow.com/questions/21488830/confusion-regarding-number-of-alarms-needed-to-be-set) too? – Sash_KP Jan 31 '14 at 20:29
  • please see [this post](http://stackoverflow.com/questions/21508611/alarm-cancel-button-not-working-correctly) if you could please help me. – Sash_KP Feb 02 '14 at 10:09

3 Answers3

5

Check this solution. It's more elegant

SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss", Locale.getDefault());
String str = sdf.format(new Date(System.currentTimeMillis()));
Toast.makeText(getApplicationContext(), "Alarm Set."+str, Toast.LENGTH_LONG).show()
Dragan
  • 328
  • 2
  • 12
  • Thanks for your suggestion.It worked with just a slight modification i.e `HH:mm:ss` to `hh:mm:ss`.I admit it's more elegant than the other one.But i just wanted to know what's the problem there in that snippet. – Sash_KP Jan 31 '14 at 15:31
2

It is working fine as is, the only reason you see such a huge offset is because it is calculating the total number of hours since the UNIX epoch.

When you do a Calendar.getInstance() it gets you the current point in time. Converting it to milliseconds are the total millis since the UNIX epoch.

You can check the total number of hours since the epoch:

//Check for the hours since the UNIX Epoch
System.out.println(System.currentTimeMillis() / 3600000);

Output:

386439

You code below would also produce this result appended with the minutes and seconds of the current point in time:

Calendar cal = Calendar.getInstance();

String str = String
        .format("%02d:%02d:%02d",
                TimeUnit.MILLISECONDS.toHours((cal.getTimeInMillis() - 300000)),
                TimeUnit.MILLISECONDS.toMinutes(cal.getTimeInMillis() - 300000)
                        - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS
                                .toHours(cal.getTimeInMillis() - 300000)),
                TimeUnit.MILLISECONDS.toSeconds(cal.getTimeInMillis() - 300000)
                        - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS
                                .toMinutes(cal.getTimeInMillis() - 300000)));

System.out.println(str);

Output:

386439:38:20

Note: Your reference example considers a constant value of millis (3600000) hence it gets a readable time there.

The better solution is provided in the other answer which provides for your requirement.

PopoFibo
  • 8,281
  • 2
  • 29
  • 47
  • That's exactly they call a Superb explanation.You're a gem.Thanks a lot for explaining. – Sash_KP Jan 31 '14 at 18:52
  • Thanks.If i am not annoying you could you please look at [this post](http://stackoverflow.com/questions/21488830/confusion-regarding-number-of-alarms-needed-to-be-set) too! – Sash_KP Jan 31 '14 at 19:53
  • @Sash_kp I guess android gurus would be able to help you with that :) – PopoFibo Feb 01 '14 at 04:56
  • Thanks for your concern.But i haven't got any answers till now.I wonder if you could throw some light on this. – Sash_KP Feb 01 '14 at 05:50
  • please see [this post](http://stackoverflow.com/questions/21508611/alarm-cancel-button-not-working-correctly) if you could please help me. – Sash_KP Feb 02 '14 at 10:08
1

Using the Joda-Time library makes this work much easier.

// Note that milliseconds-since-epoch needs to be a "long" rather than an "int".
long millis = new DateTime().getMillis(); 

// Specify a time zone rather than rely on default.
DateTimeZone timeZone = DateTimeZone.forID( "Asia/Kolkata" ); // Formerly known as Calcutta India.

// Instantiate a DateTime object from number of milliseconds since Unix epoch.
DateTime dateTime = new DateTime( millis, timeZone );

// Go back 5 minutes.
DateTime dateTimeEarlier = dateTime.minusMinutes( 5 );

// Get a formatter to render a string of the time portion.
DateTimeFormatter formatter = ISODateTimeFormat.hourMinuteSecond();

// Use the formatter to create a string.
String output = formatter.print( dateTimeEarlier );

Dump to console…

System.out.println( "millis: " + millis );
System.out.println( "dateTime: " + dateTime );
System.out.println( "dateTimeEarlier: " + dateTimeEarlier );
System.out.println( "output: " + output );

When run…

millis: 1391391422174
dateTime: 2014-02-03T07:07:02.174+05:30
dateTimeEarlier: 2014-02-03T07:02:02.174+05:30
output: 07:02:02
Basil Bourque
  • 218,480
  • 72
  • 657
  • 915