6

How do you get the total number of minutes in the day so far in Java (Android)? Is this possible? For example, if it was 12:37am, I would want it to return int 37 (37 minutes so far that day). Or if it was 1:41am, I would want it to return int 101 (101 minutes so far that day), or if it 12:20pm, it would return int 740 (740 total minutes that day).

user2864740
  • 60,010
  • 15
  • 145
  • 220
I'm_With_Stupid
  • 1,112
  • 4
  • 16
  • 35
  • 2
    I would do math using the result of [`Calendar.get`](http://developer.android.com/reference/java/util/Calendar.html) for the various (hour, minute, second) fields on the time representing now. It is also possible to compute the difference between now and "the start of today", for which duplicate questions surely exist. – user2864740 Sep 09 '14 at 03:52
  • 3
    what problem you face on doing this? If you can get the current time, then all you need to do is just a simple math I guess – Baby Sep 09 '14 at 03:53
  • @TheQuickBrownFox, wow I can't believe that never occurred to me. – I'm_With_Stupid Sep 09 '14 at 03:54
  • @Jonjongot No, **you cannot just use simple math**. Daylight Saving Time means days can be 23, 24, or 25 hours long. For example, 03:00 could be 120 or 180 minutes. Besides DST, you need to account for other anomalies in various places. And you need time zone to know when a day starts (ex: Paris vs Montréal). Use a good date-time library for such work. In Android, that means [Joda-Time](http://www.joda.org/joda-time/). See [my answer](http://stackoverflow.com/a/25738113/642706). – Basil Bourque Dec 10 '14 at 19:10

5 Answers5

16

I actually used the Calendar class to figure this out.

Here is the code, with currentMinuteOfDay being the total number of minutes.

Calendar now = Calendar.getInstance();
        int hour = now.get(Calendar.HOUR_OF_DAY);
        int minute = now.get(Calendar.MINUTE);

        int currentMinuteOfDay = ((hour * 60) + minute);
Bryan Bryce
  • 1,310
  • 1
  • 16
  • 29
I'm_With_Stupid
  • 1,112
  • 4
  • 16
  • 35
7

tl;dr

ZoneId z = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime zdt = ZonedDateTime.now( z ) ;
long minutesIntoTheDay = ChronoUnit.MINUTES.between( 
    zdt.toLocalDate().atStartOfDay( z ) ,
    zdt 
);

Time Zone

The other answers are incorrect in that they fail to account for time zone. If you want minutes since start of day, which day? The day starting in Kolkata, Paris, or Montréal? A 23-hour, 24-hour, 25-hour, or some other length day?

Specify a proper time zone name. Never use the 3-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).

Using java.time

Get the current moment, ZonedDateTime, for your desired/expected time zone by specifying a ZoneId.

ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime now = ZonedDateTime.now( zoneId );

To get the number of minutes into the day, get the first moment of the day, and then calculated elapsed time.

ZonedDateTime startOfDay = now.toLocalDate().atStartOfDay( z );

Calculate elapsed time either as a Duration or use the ChronoUnit enum.

Duration duration = Duration.between( startOfDay , now );
long minutesIntoTheDay = duration.toMinutes();

…or…

long minutesIntoTheDay = ChronoUnit.MINUTES.between( startOfDay , now );

Example: Europe/Amsterdam

Here is an example showing the DST cutover (“Spring forward”) for the Netherlands in time zone Europe/Amsterdam this year of 2017, on March 26 at 2 AM.

LocalDate march26 = LocalDate.of ( 2017, Month.MARCH, 26 );
LocalTime twoAm = LocalTime.of ( 2, 0 );
ZoneId z = ZoneId.of ( "Europe/Amsterdam" );
ZonedDateTime start = march26.atStartOfDay ( z );
ZonedDateTime stop = ZonedDateTime.of ( march26, twoAm, z );
long minutes = ChronoUnit.MINUTES.between ( start, stop );
Duration duration = Duration.between ( start, stop );
long durationAsMinutes = duration.toMinutes ( );
int minuteOfDay = stop.get ( ChronoField.MINUTE_OF_DAY );

Dump to console.

System.out.println ( "start: " + start );
System.out.println ( "stop: " + stop );
System.out.println ( "minutes: " + minutes );
System.out.println ( "FYI: 4 * 60 = " + ( 4 * 60 ) + " | 3 * 60 = " + ( 3 * 60 ) + " | 2 * 60 = " + ( 2 * 60 ) );
System.out.println ( "duration.toString(): " + duration + " | durationAsMinutes: " + durationAsMinutes );
System.out.println ( "minuteOfDay: " + minuteOfDay );

You can see this code run live at IdeOne.com.

start: 2017-03-26T00:00+01:00[Europe/Amsterdam]

stop: 2017-03-26T03:00+02:00[Europe/Amsterdam]

minutes: 120

FYI: 4 * 60 = 240 | 3 * 60 = 180 | 2 * 60 = 120

duration.toString(): PT2H | durationAsMinutes: 120

minuteOfDay: 180

Note in the output:

  • The offset-from-UTC changes by an hour, going from +01:00 to +02:00.
  • The time-of-day we requested was 2 AM, but there is no such time-of-day on that date. Two o’clock in the morning simply does not exist on that date as the clocks jumped ahead an hour. Of course, space-time did not bend nor warp. Only two hours of actual time elapsed between midnight and 3 AM, not three. The designers of the java.time classes chose to resolve the problem by adjusting the time-of-day value ahead to the valid time-of-day. Read the doc to be sure you understand and agree with such behavior.
  • The result of ChronoField.MINUTE_OF_DAY is not correct/precise because that feature accounts only for generic 24-hour days rather than actual anomalous dates such as this date with DST cutover. We see 180 minutes whereas only 120 minutes actually elapsed.

CORRECTION: This Answer formerly advised using ChronoField.MINUTE_OF_DAY. That was poor advice as that feature uses generic 24-hour days. Anomalies such as Daylight Saving Time (DST) are ignored. So the results may not be precise/correct for particular dates in certain time zones. This behavior is clearly documented:

ChronoField MINUTE_OF_DAY

public static final ChronoField MINUTE_OF_DAY

The minute-of-day.

This counts the minute within the day, from 0 to (24 * 60) - 1. This field has the same meaning for all calendar systems.

When parsing this field it behaves equivalent to the following: The value is validated in strict and smart mode but not in lenient mode. The value is split to form MINUTE_OF_HOUR and HOUR_OF_DAY fields.


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?

kenny_k
  • 3,831
  • 5
  • 30
  • 41
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
  • 1
    On the day daylight saving times starts (f.i. 2017/03/26 12:00 in Europe/Amsterdam), `MINUTE_OF_DAY` reports 720 (12*60), but the we just skipped 60 minutes from 1:59 to 3:00. So it should be 660. JodaTime does the same. On the other hand, `dstStartDayAtStartOfDay.until(dstStartDayAtNoon,ChronoUnit.MINUTES)` reports the correct 660 minutes (and with `HOURS` 11h). When DST end, the pattern repeats: `.until()` give 13h/780min from midnight until lunch time on 2017/10/29. So far I could not find an explanation for the discrepancy between the two results. – Ivin Mar 26 '17 at 07:41
  • @Ivin You are correct, my suggestion to use `ChronoField.MINUTE_OF_DAY` is ill-advised. That feature works only for generic 24-hour days, not for an anomalous date such as DST cutover. I revised this Answer to suggest other features instead. – Basil Bourque Mar 26 '17 at 09:05
5

I'm with stupid,

Here's the pseudo algorithm:

  1. Get the current time in hours and minutes
  2. Multiple hours * 60 + minutes, and this is your answer!

I would recommend using the Date class:

 Date date = new Date();

You can read up more on the Date class here.

Please let me know if you have any questions!

Devarsh Desai
  • 5,984
  • 3
  • 19
  • 21
  • 1
    AM/PM are artificial designators; all Calendar/Date objects use 24-hour clocks (but note odd access like HOUR vs HOUR_OF_DAY). – user2864740 Sep 09 '14 at 03:57
  • ahh, I see; I wasn't aware of that. Thank you for the new knowledge and clarification @user2864740! :0) – Devarsh Desai Sep 09 '14 at 03:58
  • 1
    This answer ignores time zone. The java.util.Date class has no time zone, and represents only UTC. If you want the number of minutes since start of day, you have to do something else. The day starts at different times in Kolkata, Paris, and Montréal. – Basil Bourque Sep 09 '14 at 06:27
1

Set your start time at midnight. Then when you want the total number of minutes that have passed just grab the current time. Then grab the whole number of both times, subtract startTime_hour from currentTime_hour.

Then grab the minutes component of the times, in your case only from currentTime minutes. Convert the minutes to decimal using this relation:

30mins/.50

Which is simply, 30 minutes = 0.50. In code it will look like this:

currentTime_mins_decimal = .50 * currentTime_mins / 30;

Now you want to add the result from the first subtraction to currentTime_mins_decimal and multiply the whole thing by 60.

Then convert from decimal to minutes by using the same relation: 30mins/.50 The benefit of changing was that if your start time is not midnight but something with minutes, let's say 12:55 when you do your arithmetic you won't get accurate results.

apxcode
  • 7,696
  • 7
  • 30
  • 41
1

Based onn the answer to Get current time and date on Android post:

public int getTodayMinutesAsOfNow() {
    Calendar c = Calendar.getInstance(); 
    return c.get(Calendar.HOUR_OF_DAY)*60 + c.get(Calendar.MINUTE);
}
Community
  • 1
  • 1
PM 77-1
  • 12,933
  • 21
  • 68
  • 111