-1

I am trying to solve this wrong output but nothing helped me:

Calendar cal = Calendar.getInstance();
cal.setTimeZone( TimeZone.getDefault() );
long oraPrecisa     =   cal.getTimeInMillis();
Log.e( "" , "oraPrecisa: " + new DateFormat().format( "HH:mm", oraPrecisa ).toString() );

cal.set( Calendar.HOUR_OF_DAY, 0 );
cal.set( Calendar.MINUTE, 0 );
cal.set( Calendar.SECOND, 0 );
cal.set( Calendar.MILLISECOND, 1 );

oraPrecisa  =   oraPrecisa - cal.getTimeInMillis();
Log.e( "" , "OraPrecisa 2: " + new DateFormat().format( "HH:mm", oraPrecisa ).toString() );

Returns this output:

OraPrecisa: 13:58
OraPrecisa 2: 14:58

I get one hour error (due to the timezone I guess since I am in GMT+1), any help?

Soul
  • 590
  • 1
  • 7
  • 17
  • 1
    What is it you're trying to do exactly? I don't understand. I am in GMT+1 too, so why not just use the first `oraPrecisa` ? – Vucko Jun 02 '18 at 12:09
  • https://stackoverflow.com/questions/36155927/calendar-hour-of-day-confusion Is it perhaps a daylight savings time issue? – BobtheMagicMoose Jun 02 '18 at 12:09
  • 1
    check the Calendar android document and tell us why the first time is not enough for you? – Bita Mirshafiee Jun 02 '18 at 12:13
  • 1
    @BitaMirshafiee because I need the absolute time in millisecs from the beginning of the day – Soul Jun 02 '18 at 12:14
  • Why set Calendar.MILLISECOND, too?, set the three first one that you did then you can get it in millisecond – Bita Mirshafiee Jun 02 '18 at 12:39
  • If you want the difference, i mean : now - beginning of the day, the het the two time in millisecond and differentiate them – Bita Mirshafiee Jun 02 '18 at 12:42
  • Your calculation of time since the beginning of day is correct except if the day doesn’t begin at 00:00:00 (in some time zones the day may begin at, say, 01:00:00 when summer time starts in the spring). It’s only your formatting of the calculated time that has an issue. So don’t do that. – Ole V.V. Jun 04 '18 at 11:41

3 Answers3

2

java.time

If you want to convert the time of day to milliseconds:

    ZoneId zone = ZoneId.of("Europe/Rome");
    LocalTime timeOfDay = LocalTime.now(zone);
    long milliOfDay = TimeUnit.NANOSECONDS.toMillis(timeOfDay.toNanoOfDay());
    System.out.println(milliOfDay);

If instead I am to take it literally when you asked for number of milliseconds since the start of the day:

    ZonedDateTime now = ZonedDateTime.now(zone);
    ZonedDateTime startOfDay = now.toLocalDate().atStartOfDay(zone);
    Duration dur = Duration.between(startOfDay, now);
    long millisSinceStartOfDay = dur.toMillis();
    System.out.println(millisSinceStartOfDay);

When I ran the two snippets just now (15:18:28 in Italy), they both printed

55108833

Is there any difference, then? In by far the most cases, the two snippets above will print the same result. However, if for example there is a transition to or from summer time (daylight saving time) earlier the same day, the local time will not reflect the time passed since the start of day, and then the snippets will give different results. So you should choose carefully which one of them you want.

Since the number of milliseconds since midnight will never overflow an int, you can safely cast to that type if you prefer.

Rather than the long outdated and poorly designed Calendar class I am using java.time, the modern Java date and time API. It is so much nicer to work with.

Question: Can I use java.time on Android?

Yes, java.time works nicely on older and newer Android devices. It just requires at least Java 6.

  • In Java 8 and later and on newer Android devices (from API level 26, I’m told) the modern API comes built-in.
  • In Java 6 and 7 get the ThreeTen Backport, the backport of the new classes (ThreeTen for JSR 310; see the links at the bottom).
  • On (older) Android use the Android edition of ThreeTen Backport. It’s called ThreeTenABP. And make sure you import the date and time classes from org.threeten.bp with subpackages.

Links

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
0

pay attention to the set part for your Calendar class, something is wrong there:

set(f, value) changes calendar field f to value. In addition, it sets an internal member variable to indicate that calendar field f has been changed. Although calendar field f is changed immediately, the calendar's time value in milliseconds is not recomputed until the next call to get(), getTime(), getTimeInMillis(), add(), or roll() is made. Thus, multiple calls to set() do not trigger multiple, unnecessary computations. As a result of changing a calendar field using set(), other calendar fields may also change, depending on the calendar field, the calendar field value, and the calendar system. In addition, get(f) will not necessarily return value set by the call to the set method after the calendar fields have been recomputed. The specifics are determined by the concrete calendar class.

refrence

Bita Mirshafiee
  • 600
  • 8
  • 14
  • This is not the issue here (though it’s a fact that does confuse many). The asker is calling `getTimeInMillis()`, and according to your quote this triggers a recomputation of the calendar's time value in milliseconds, so the correct value is returned. – Ole V.V. Jun 04 '18 at 11:27
0

I think the problem is because you are trying to treat the difference between two dates as a date.

If you run your code in this other way the difference is shown correctly:

import java.util.Calendar;
import java.util.TimeZone;
import java.text.DateFormat;
public class HelloWorld{

     public static void main(String []args){
        Calendar cal = Calendar.getInstance();
        cal.setTimeZone( TimeZone.getDefault() );
        long oraPrecisa     =   cal.getTimeInMillis();


        cal.set( Calendar.HOUR_OF_DAY, 0 );
        cal.set( Calendar.MINUTE, 0 );
        cal.set( Calendar.SECOND, 0 );
        cal.set( Calendar.MILLISECOND, 1 );

        oraPrecisa  =   oraPrecisa - cal.getTimeInMillis();

        oraPrecisa = oraPrecisa / 1000; 
        int hh = (int)(oraPrecisa  / 60 / 60);
        int mm = (int) ( ( oraPrecisa - (hh * 60 * 60) ) / 60 );
        int ss = (int) (oraPrecisa - hh * 60 * 60 - mm * 60);

        System.out.println(String.format("Diff: %2d:%2d:%2d",hh,mm,ss));

    }
}
Juan
  • 5,525
  • 2
  • 15
  • 26