Question

I want to get the time of a day in milliseconds, I do not this day to have any specific date, just a time. I made something, thought it worked, but then went debugging and concluded that it doesn't work how I want it to.

I want to use this to check if the current time is between both my specified startTime and endTime.

    long startTime = settings.getLong("startTime", 0);
    long endTime = settings.getLong("endTime", 0);

    if ((currentTime.getMillis() >= startTime)
            && (currentTime.getMillis() <= endTime)) {
            //Do stuff here

 }

How I am setting the time of the propeties startTime and endTime:

                        Calendar startTime = Calendar.getInstance();
                        startTime.set(Calendar.HOUR_OF_DAY, 16);
                        startTime.set(Calendar.MINUTE, 00);
                        editor.putLong("startTime",
                                startTime.getTimeInMillis());

                        Calendar endTime = Calendar.getInstance();
                        endTime.set(Calendar.HOUR_OF_DAY, 16);
                        endTime.set(Calendar.MINUTE, 00);
                        endTime.add(Calendar.HOUR_OF_DAY, 11);
                        editor.putLong("endTime",
                                endTime.getTimeInMillis());
                        editor.commit();

However this will mean that both startTimeand endTime will have this a specific date attached to it.

I hope I explained it well, any help is appreciated!

Was it helpful?

Solution

Avoid Milliseconds

No need to mess with milliseconds for your purpose. Using milliseconds for date-time is confusing and error-prone.

What you need is a decent date-time library rather than the notoriously troublesome bundled java.util.Date & .Calendar classes.

Joda-Time

If you are certain you want to ignore dates and ignore time zones, here's some example code using the LocalTime class offered by the third-party free-of-cost Joda-Time library.

LocalTime start = new LocalTime( 10, 0, 0 );
LocalTime stop = new LocalTime( 14, 30, 0 );
LocalTime target = LocalTime.now();
boolean isNowInSpan = !( ( target.isBefore( target ) ) | ( target.isAfter( stop ) ) );

Adjust that last line according to your business logic needs. You might want:

  • The beginning and ending are inclusive
  • The beginning and ending are exclusive
  • "Half-Open" where the beginning is inclusive and the ending is exclusive
    (usually best for date-time work)

Dump to console…

System.out.println( "start: " + start );
System.out.println( "stop: " + stop );
System.out.println( "target: " + target );
System.out.println( "isNowInSpan: " + isNowInSpan );

When run…

start: 10:00:00.000
stop: 14:30:00.000
target: 23:49:37.779
isNowInSpan: false

Another Example

Time-of-day-only is not usually the right way to go. When new to date-time work, a naïve programmer may at first think that time-only simplifies things. On the contrary, this example shows how spinning around the clock creates complications. Using date+time+timeZone is usually the best approach in the long run.

LocalTime now = LocalTime.now();
LocalTime start = new LocalTime( 13, 0, 0, 0 );
LocalTime stop = start.plusHours( 11 );

System.out.println( "now: " + now );
System.out.println( "start: " + start );
System.out.println( "stop: " + stop );

if ( now.isAfter( start ) ) {
    System.out.println( "After start" );
}

if ( now.isBefore( stop ) ) {
    System.out.println( "Before stop" );
}

When run…

now: 14:00:32.496
start: 13:00:00.000
stop: 00:00:00.000
After start

java.time

Java 8 brings the new java.time package, inspired by Joda-Time, defined by JSR 310.

In java.time, you will find a LocalTime class similar to the one in Joda-Time.

OTHER TIPS

A new approach with Java 8 onward.

int millisecondsOfDay = LocalTime.now().get(ChronoField.MILLI_OF_DAY);

Reference: https://o7planning.org/13669/java-localtime#a64448233

Time without Date is meaning less. In Java timestamp it's using the Unix UTC and the timestamp start 0 on 01/01/1970. So, you startTime/endTime.getTimeInMillis() tell you the time different from UTC. Which mean your midnight is your base and your endTime.getTimeInMillis() will be the offset.

  Calendar cal = Calendar.getInstance();
  // set to mid-night
  cal.set(Calendar.HOUR_OF_DAY, 0);
  cal.set(Calendar.MINUTE, 0);
  cal.set(Calendar.SECOND, 0);
  cal.set(Calendar.MILLISECOND, 0);
  long midnight = cal.getTimeInMillis();

  cal.set(Calendar.HOUR_OF_DAY, 16);
  cal.set(Calendar.MINUTE, 00);
  long startTime = cal.getTimeInMillis();
  editor.putLong("startTime", (startTime - midnight));

  cal.add(Calendar.HOUR_OF_DAY, 11);
  long endTime = cal.getTimeInMillis();
  editor.putLong("endTime", (endTime - midnight));
  editor.commit();

java.time.LocalTime

I recommend that you use java.time, the modern Java date and time API, for your time work. Use a LocalTime object for time of day (it’s what it’s for).

    LocalTime time = LocalTime.of(16, 0);
    System.out.println(time);

Output:

16:00

If you cannot store a LocalTime object in your settings, convert to a string for human readability (a great advantage in debugging and support cases):

    String timeString = time.toString();
    LocalTime parsedBack = LocalTime.parse(timeString);
    System.out.println(parsedBack);

16:00

To answer the question as asked, in case you need to, converting to milliseconds is straightforward (when you know how):

    int milliOfDay = time.get(ChronoField.MILLI_OF_DAY);
    System.out.println(milliOfDay);

57600000

The milliseconds too can be converted back to a LocalTime object:

    LocalTime recreatedLocalTime
            = LocalTime.MIN.with(ChronoField.MILLI_OF_DAY, milliOfDay);
    System.out.println(recreatedLocalTime);

16:00

Link

Oracle tutorial: Date Time explaining how to use java.time.

In case what you need is to get how many milliseconds since the start of this day and you have now in milliseconds you can get the milliseconds you want as simple as this

val nowMilliSeconds = System.currentTimeMillis() % 86400000

Where 86400000 is the number of milliseconds in a day so you will just get the remainder

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top