using only currentTimeMillis() to get the date - java

So I'm totaly lost. I have to print out the actual Date and time using only currentTimeMillis() and nothing else. Getting the time was no problem:
long t = java.lang.System.currentTimeMillis();
long seconds = (t / 1000) % 60;
long minutes = (t / (1000 * 60)) % 60;
long hours = (t / (1000 * 60 * 60) % 24) + zone;
But how can I calculate the date taking leap years into consideration?
Edit: It's homework, hence this weird question. And we are not allowed to use any other methodes besides currentTimeMillis(). Operators and alike are fine.

For the timezone related problem, following fix can be used. However this is just one case: other cases need to be handled as well.
//let's say time zone is +5:30
long zone = 6; //instead of 5, keeping value 6, thus added extra 30 minutes
long minuten = (t / (1000 * 60)) % 60;
long stunden = (t / (1000 * 60 * 60) % 24) + zone;
if(minuten < 30){ // this is to take care of the cases where hour has moved ahead
stunden--;
minuten+=30;
} else{
minuten-=30; // else deduct those additional 30 minutes
}

There is no way to do this without using anything else. You have to be more clear about which restrictions there are and why? Is this homework?
The simplest way I can think of is:
long t = java.lang.System.currentTimeMillis();
System.out.println(new Date(t));
But I am sure that's not what you need. Please elaborate...

Related

how to convert a certain number to hours/minutes?

Hello everyone well i have a certain long number and i wish to divide it and show how many minutes and hours remaining :
timeToReceive = Utils.currentTimeMillis() + (60 * 1000 * 60 * 8); // 8 hours
here is my timeToReceive long.
I want to show how much time is remaining for the timeToReceive(it's set for 8 hours in the future).
So i do this :
(timeToReceive - Utils.currentTimeMillis()) / (1000 * 60)
this displays it in minutes, however i want to display it in hours and minutes, how will i go bout doing that?
thanks.
timeInMinutes = (timeToReceive - Utils.currentTimeMillis()) / (1000 * 60);
hours = timeInMinutes / 60;
minutes=timeInMinutes % 60;
This works fine
First count the time in minutes
minutes = (timeToReceive - Utils.currentTimeMillis()) / (1000 * 60)
Then use / operation and % operation
minutes / 60; // will just divide and truncate - gives you hours
minutes % 60; // will give you the rest that is left after dividing - the part that was truncated when you used / operator

Print milliseconds only (0 to 999)

I have worked a bit on the following code but still unable to print milliseconds (not all the millisecond from epoch time to user defined time).
Where am I lacking to print remaining milliseconds e.g. If seconds are 30 exactly, milliseconds should be only 0. Milliseconds should not be more than 999 obviously.
// Sets current date by default
Calendar ob = Calendar.getInstance();
// Sets user defined date with year, month, day of month respectively
Calendar dob = Calendar.getInstance();
dob.set(1990, 3, 25);
// Want to get milliseconds only (0 - 999)
long milli = dob.getTimeInMillis() - ( 60 * 60 * 24 * 30 * 12 * ( ob.get(Calendar.YEAR) - dob.get(Calendar.YEAR) ) );
System.out.println(milli);
Why not do
long justMillis = dob.getTimeInMillis() % 1000;
You want what's called the modulus operator, %. This basically finds the remainder of division.
long milli = dob.getTimeInMillis() % 1000;
System.out.println(milli % 1000);

Calculating difference in two time

I am calculating the difference between two times and i am able to get the difference in hours and minuted using separate equations,is there any single equation from which i can get hours and minutes at one go.I am using like:
here diff is the difference between two time value
long diffHours1 = diff / (60 * 60 * 1000);
long min=diff/(60*1000);
I'm not sure it is helpful here, but Joda Time seems to have a little more verbose solution using Period e.g.
Period p = new Period(startDate, endDate)
int minutes = p.getMinutes(); //returns the left over minutes part
int seconds = p.getSeconds(); //returns the seconds part
I'm not sure that for this particular case you need something else than what you have, I agree with aix's
is there any single equation from which i can get hours and minutes at one go
No, not easily. A Java expression can only have one result; returning several things is not impossible, but would require additional machinery (a wrapper class, a tuple etc). This would result in code that's significantly more complicated than what you have right now.
What you can do to simplify things a little bit is compute minutes first, and then compute hours based on minutes:
long diffMinutes = diff / (60*1000);
long diffHours = diffMinutes / 60;
Yes there is:
String oneGo = (diff / (60 * 60 * 1000)) + " " + (diff / (60 * 1000));
:-)
Well, two equations are not that bad (actually using more lines makes it easier to read), although you might change the order, correct the equation and cache some results.
diff = //time difference in milliseconds
long diffInMinutes = diff / (60 * 1000);
//get the number of hours, e.g. 140 / 60 = 2
long hours = diffInMinutes / 60;
//get the left over minutes, e.g. 140 % 60 = 20
long minutes = diffInMinutes % 60;
If the reason you want one equation is ease of use, try using an alternative library like Joda Time.

Formatting a *relative* amount of time (ms) in Java?

I want to log certain events by their relative timing. I don't care at what hour of the day something happened, I just want to know that an event happened 2 minutes, 13 seconds and 243 milliseconds ago. Let's say I have:
long event_ms = [some time in ms since the Epoch];
long now_ms = [current time in ms since the Epoch];
long diff_ms = now_ms - event_ms;
diff_ms contains the number of milliseconds AGO that the event occurred. I just want to format this time (using the format HH:mm:ss.SSS). What's the easiest way to do this? Thanks!
The class TimeUnit contains methods to convert millis in to hours, minutes and seconds:
String.format("%d min, %d sec",
TimeUnit.MILLISECONDS.toMinutes(millis),
TimeUnit.MILLISECONDS.toSeconds(millis) -
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis))
);
P.S Note that TimeUnit is available only in 1.5+
A simpler approach
String.format("%d min, %d sec, %d ms",
millis/60/1000, millis/1000%60, millis%1000);
You don't need TimeUnit to do simple integer operations such as division and module, nor you need to use TimeZone(s), since you are dealing with a delta, which is time-zone independent. Here's the solution I would have used:
long millis = 123456L;
String delta = String.format(
"%02d:%02d:%02d.%03d",
(millis / (1000L * 60L * 60L)),
(millis / (1000L * 60L)) % 60,
(millis / 1000L) % 60,
millis % 1000L
);
The following code works fine for me:
int diff_ms = 61200;
SimpleDateFormat fmt = new SimpleDateFormat("HH:mm:ss.SSS");
fmt.setTimeZone(TimeZone.getTimeZone("GMT"));
String str = fmt.format(new Date(diff_ms));
System.out.println(str);
It prints 00:01:01.200
Pay attention on setting the timezone. Otherwise the result depends on your default timezone and will be wrong everywhere except GMT.

milliseconds to days

i did some research, but still can't find how to get the days... Here is what I got:
int seconds = (int) (milliseconds / 1000) % 60 ;
int minutes = (int) ((milliseconds / (1000*60)) % 60);
int hours = (int) ((milliseconds / (1000*60*60)) % 24);
int days = ????? ;
Please help, I suck at math, thank's.
For simple cases like this, TimeUnit should be used. TimeUnit usage is a bit more explicit about what is being represented and is also much easier to read and write when compared to doing all of the arithmetic calculations explicitly. For example, to calculate the number days from milliseconds, the following statement would work:
long days = TimeUnit.MILLISECONDS.toDays(milliseconds);
For cases more advanced, where more finely grained durations need to be represented in the context of working with time, an all encompassing and modern date/time API should be used. For JDK8+, java.time is now included (here are the tutorials and javadocs). For earlier versions of Java joda-time is a solid alternative.
If you don't have another time interval bigger than days:
int days = (int) (milliseconds / (1000*60*60*24));
If you have weeks too:
int days = (int) ((milliseconds / (1000*60*60*24)) % 7);
int weeks = (int) (milliseconds / (1000*60*60*24*7));
It's probably best to avoid using months and years if possible, as they don't have a well-defined fixed length. Strictly speaking neither do days: daylight saving means that days can have a length that is not 24 hours.
Go for TImeUnit in java
In order to import use, java.util.concurrent.TimeUnit
long millisec=System.currentTimeMillis();
long seconds=TimeUnit.MILLISECONDS.toSeconds(millisec);
long minutes=TimeUnit.MILLISECONDS.toMinutes(millisec);
long hours=TimeUnit.MILLISECONDS.toMinutes(millisec);
long days=TimeUnit.MILLISECONDS.toDays(millisec);
java.time
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 convenient methods were introduced.
Demo:
import java.time.Duration;
public class Main {
public static void main(String[] args) {
// Duration between the two instants
Duration duration = Duration.ofMillis(1234567890L);
// Print Duration#toString
System.out.println(duration);
// Custom format
// ####################################Java-8####################################
String formattedElapsedTime = String.format(
"%d Day %02d Hour %02d Minute %02d Second %d Millisecond (%d Nanosecond)", duration.toDays(),
duration.toHours() % 24, duration.toMinutes() % 60, duration.toSeconds() % 60,
duration.toMillis() % 1000, duration.toNanos() % 1000000000L);
System.out.println(formattedElapsedTime);
// ##############################################################################
// ####################################Java-9####################################
formattedElapsedTime = String.format("%d Day %02d Hour %02d Minute %02d Second %d Millisecond (%d Nanosecond)",
duration.toDaysPart(), duration.toHoursPart(), duration.toMinutesPart(), duration.toSecondsPart(),
duration.toMillisPart(), duration.toNanosPart());
System.out.println(formattedElapsedTime);
// ##############################################################################
}
}
A sample run:
PT342H56M7.89S
14 Day 06 Hour 56 Minute 07 Second 890 Millisecond (890000000 Nanosecond)
14 Day 06 Hour 56 Minute 07 Second 890 Millisecond (890000000 Nanosecond)
Learn more about the modern date-time API from Trail: Date Time.
int days = (int) (milliseconds / 86 400 000 )
public static final long SECOND_IN_MILLIS = 1000;
public static final long MINUTE_IN_MILLIS = SECOND_IN_MILLIS * 60;
public static final long HOUR_IN_MILLIS = MINUTE_IN_MILLIS * 60;
public static final long DAY_IN_MILLIS = HOUR_IN_MILLIS * 24;
public static final long WEEK_IN_MILLIS = DAY_IN_MILLIS * 7;
You could cast int but I would recommend using long.
You can’t. Sorry. Or more precisely: you can if you know a time zone and a start time (or end time). A day may have a length of 23, 24 or 25 hours or some other length. So there isn’t any sure-fire formula for converting from milliseconds to days. So while you can safely rely on 1000 milliseconds in a second, 60 seconds in a minute (reservation below) and 60 minutes in an hour, the conversion to days needs more context in order to be sure and accurate.
Reservation: In real life a minute is occasionally 61 seconds because of a leap second. Not in Java. Java always counts a minute as 60 seconds because common computer clocks don’t know leap seconds. Common operating systems and Java itself do know not only summer time (DST) but also many other timeline anomalies that cause a day to be shorter or longer than 24 hours.
To demonstrate. I am writing this on March 29, 2021, the day after my time zone, Europe/Copenhagen, and the rest of the EU switched to summer time.
ZoneId myTimeZone = ZoneId.of("Europe/Copenhagen");
ZonedDateTime now = ZonedDateTime.now(myTimeZone);
ZonedDateTime twoDaysAgo = now.minusDays(2);
ZonedDateTime inTwoDays = now.plusDays(2);
System.out.println(ChronoUnit.MILLIS.between(twoDaysAgo, now));
System.out.println(ChronoUnit.MILLIS.between(now, inTwoDays));
Output:
169200000
172800000
So how many milliseconds are in two days depends on which two days you mean. And in which time zone.
So what to do?
If for your purpose you can safely define a day as 24 hours always, for example because your days are counted in UTC or your users are fine with the inaccuracy, use either Duration or TimeUnit. Since Java 9 the Duration class will additionally tell you how many hours, minutes and seconds there are in addition to the whole days. See the answer by Arvind Kumar Avinash. For the TimeUnit enum see the answers by whaley and Dev Parzival. In any case the good news is that it doesn’t matter if you suck at math because the math is taken care of for you.
If you know a time zone and a starting point, use ZonedDateTime and ChronoUnit.DAYS. In this case too the math is taken care of for you.
ZonedDateTime start = LocalDate.of(2021, Month.MARCH, 28).atStartOfDay(myTimeZone);
long millisToConvert = 170_000_000;
ZonedDateTime end = start.plus(millisToConvert, ChronoUnit.MILLIS);
long days = ChronoUnit.DAYS.between(start, end);
System.out.format("%d days%n", days);
2 days
If you additionally want the hours, minutes and seconds:
Duration remainingTime = Duration.between(start.plusDays(days), end);
System.out.format(" - and an additional %s hours %d minutes %d seconds%n",
remainingTime.toHours(),
remainingTime.toMinutesPart(),
remainingTime.toSecondsPart());
- and an additional 0 hours 13 minutes 20 seconds
If instead you had got an endpoint, subtract your milliseconds from the endpoint using the minus method (instead of the plus method used in the above code) to get the start point.
Under no circumstances do the math yourself as in the question and in the currently accepted answer. It’s error-prone and results in code that is hard to read. And if your reader sucks at math, he or she can spend much precious developer time trying to verify that you have done it correctly. Leave the math to proven library methods, and it will be much easier for your reader to trust that your code is correct.
In case you solve a more complex task of logging execution statistics in your code:
public void logExecutionMillis(LocalDateTime start, String callerMethodName) {
LocalDateTime end = getNow();
long difference = Duration.between(start, end).toMillis();
Logger logger = LoggerFactory.getLogger(ProfilerInterceptor.class);
long millisInDay = 1000 * 60 * 60 * 24;
long millisInHour = 1000 * 60 * 60;
long millisInMinute = 1000 * 60;
long millisInSecond = 1000;
long days = difference / millisInDay;
long daysDivisionResidueMillis = difference - days * millisInDay;
long hours = daysDivisionResidueMillis / millisInHour;
long hoursDivisionResidueMillis = daysDivisionResidueMillis - hours * millisInHour;
long minutes = hoursDivisionResidueMillis / millisInMinute;
long minutesDivisionResidueMillis = hoursDivisionResidueMillis - minutes * millisInMinute;
long seconds = minutesDivisionResidueMillis / millisInSecond;
long secondsDivisionResidueMillis = minutesDivisionResidueMillis - seconds * millisInSecond;
logger.info(
"\n************************************************************************\n"
+ callerMethodName
+ "() - "
+ difference
+ " millis ("
+ days
+ " d. "
+ hours
+ " h. "
+ minutes
+ " min. "
+ seconds
+ " sec."
+ secondsDivisionResidueMillis
+ " millis).");
}
P.S. Logger can be replaced with simple System.out.println() if you like.

Categories

Resources