This question already has answers here:
Time consts in Java?
(12 answers)
Closed 3 years ago.
Working with Java, I'm parsing a integer DAYS to HOURS.
Looks like this:
float hours = myvardays*24;
It works, but constant 24 is a magic number, and best avoided.
Is there any constant on Calendar, Date or any other to get total hours in a day (24)? or maybe a method?
I am interested only in generic 24-hours, ignoring anomalies such as Daylight Saving Time (DST) that result in other day lengths.
Let's not go reinventing stuff, this is all baked into the JDK:
Java 8 and later
Use Duration.ofDays with toDays method.
long hours = Duration.ofDays(myvardays).toHours(); // Java 8+
Java 5, 6, & 7
Use the TimeUnit enum.
long hours = TimeUnit.DAYS.toHours(myvardays); // Java 5+
In JDK 8 you have the Duration class where you can perform conversions between units of time.
Example:
Duration.ofDays(1).toHours() //24hs
Duration.ofHours(1).toMinutes() //60 minutes
I don't know of anything in the Java Standard Libraries that does quite what you are looking for.
However if you have static numbers in your calculations there really is no reason to remove them. Unless you feel that they will change in the future or will need to be updated in many places should the needs of the application change (e.g. on mars where there may be a different number of hours in the day)
One could make an argument that it is unclear exactly what is going on (why 24, oh right...). You may want to make a small class containing your own constants with clear names simply to make the code more readable.
For example:
public final class TimeIntervals {
// ...
public static final int HOURS_IN_DAY = 24;
public static final int DAYS_IN_WEEK = 7;
//...
}
and then use it as
float hours = days * TimeIntervals.HOURS_IN_DAY;
Related
I'm aware that you can use DateUtils.formatElapsedTime(seconds) to convert a number of seconds into a String with the format HH:MM:SS. But are there any utility functions that let me perform the same conversion but without the seconds?
For example, I want to convert 3665 seconds into 1:01, even though it's exactly 1:01:05. In other words, simply dropping the seconds part.
Would strongly prefer an answer that points to a utility function (if one exists) rather than a bunch of home rolled algorithms.
Use Apache Commons Lang
You could use utility class DateFormatUtils of Apache's well known utility library Commons Lang, combined with TimeUnit to convert from seconds to milliseconds:
static String format(long durationSeconds) {
long durationMillis = TimeUnit.SECONDS.toMillis(durationSeconds);
// Commons lang:
return DurationFormatUtils.formatDuration(durationMillis, "HH:mm");
}
Use with input 3665 it prints:
01:01
Personally I'd prefer to use Java8 or Java9 standard library (see the other answers) rather than introducing a dependency just to make it 1 method call.
MadProgrammer has already provided a good Java 8 answer (which will work in Java 6 and 7 too when you use the ThreeTen Backport). In Java 9 still a bit more of the calculation can be done in the library:
int seconds = 3665;
Duration dur = Duration.ofSeconds(seconds);
String formatted = String.format("%d:%02d", dur.toHours(), dur.toMinutesPart());
System.out.println(formatted);
Output:
1:01
The toMinutesPart method and other toXxxPart methods were introduced in Java 9.
Based on the available information, you seem to be wanting to format a duration based value. Lucky for us, since Java 8, there is now a new java.time API which includes a Duration class.
Unfortunately, it doesn't (at least the last time checked) support a formatter for it.
However, you could easily roll your own...
protected static String format(Duration duration) {
long hours = duration.toHours();
long mins = duration.minusHours(hours).toMinutes();
return String.format("%02d:%02d", hours, mins);
}
Which when used with something like...
System.out.println(format(Duration.ofSeconds(3665)));
prints out 01:01.
Now I know you'd "prefer" utility methods, but you're unlikely to find something that fits your "every" need and this at least gives you a starting point. Besides, you could always make a pull request ;)
I'm trying to setup my addToDay function. I'm currently stuck on how to proceed with this or even write it correctly. The function itself will take a variable that ranges from -100 to 100. So you would basically add that variable to the current and if it was below the 0 then subtract a month or if it was above the months max day then add a month. Which i have that function setup so all i would have to do is call addToMonth with the correct amount. My problem lies within the amount of days each month has. For example, October has 31 days while November has 30. I have a function that will return the number of days in the current set month so i can call that to get how many max days should be in the current month. I'm thinking maybe a while loop would work but i just wanted to get anyone's thoughts on the best way to set it up.
I have 3 private ints: month, day, year. These are what need to be changed. I have both addTo functions for month and year setup already.
Here are some other functions i have created that can be used in this:
1. addToMonth(int delta) - changes the current month depending on the given parameter
2. getDaysInMonth() - will return the days in a month depending on the month itself
3. validateDay() - Will return true or false if the days fall outside the wanted requirements.
I don't want to use the calendar utility
I also don't want to use any other utilities. Just the base code with Junit for testing
Joda's plusDays() function and Java 8 LocalDate already has the logic that you are trying to achieve
Alright so i ended up just copying my original addToMonth function and modifying it abit to fit with days. So far it works but i do think it'll fail in the cases of different amounth of days not lining up.
I am looking to calculate the number of minutes given the time of the day.
Eg.: when input is 11:34, the output should be 11*60+34. The date doesn't matter.
I only need it down to the minutes scale. Seconds, milliseconds... don't matter.
Is there a method somewhere in Java doing this the neat way without me calculating it?
Right now, i'm using theTime.split(":"), theTime is a String holding "11:34" here, parsing the integers on each side and doing the calculation.
I saw Time but what I'm doing right now seemed more direct.
Nothing in Systems either.
There is no build in method for it. However here is a one-liner for it:
int timeInMins = Calendar.getInstance().get(Calendar.HOUR_OF_DAY) * 60 + Calendar.getInstance().get(Calendar.MINUTE);
Your approach looks good and sound, however to answer your question it would be simple to say that there is no such build in method which does that. You have to calculate it the way you are doing it right now.
Hi maybe you could use JodaTime? Below example how to get number of minutes from parsed string and from current time. In java 8 there is similar api but I haven't found exactly method like minutesOfDay()
#Test
public void learnHowManyMinutesPassedToday() {
DateTime time = DateTimeFormat.forPattern("HH:mm").parseDateTime("11:34");
System.out.println(time.getMinuteOfDay());
System.out.println(DateTime.now().getMinuteOfDay());
}
If you are looking to have input not from a String, take a look at
Java.util.Calendar.
It has Calendar.HOUR_OF_DAY and Calendar.HOUR and Calendar.MINUTE which could be your input. I'm not sure what the "neat" way of doing this would be. It is a simple calculation.
Calendar rightNow = Calendar.getInstance();
int hour = rightNow.get(Calendar.HOUR);
int min = rightNow.get(Calendar.MINUTE);
System.out.println("TimeMinutes:" + hour * 60 + min);
EDIT:
Except using split use the above.
I came across the XMLGregorianCalendar class a while ago and I was impressed by the way it made GregorianCalendar look lightweight. ;)
Recently, I noticed a method BitInteger getEon() which baffles me.
From the Javadoc for XMLGregorianCalendar
getYear() is a value between -(10^9-1) to (10^9)-1 or DatatypeConstants.FIELD_UNDEFINED.
getEon() is high order year value in billion of years.
It occurs to me that as the length of day on Earth changes significantly over the millions of year and there for the number of days in a year has changed. The Gregorian calendar wouldn't make sense a billion years ago or a billion years hence. So getEon() can only be sensibly set to 0 or left undefined which has much the same outcome.
My question: Am I missing something? Is there a sensible use for the getEon() method?
Well, according to http://www.merlyn.demon.co.uk/critdate.htm the unix time using 64 bits integer will end around the year 3E11. Given that Java uses milliseconds instead of seconds, Java time (64 bits) will end around 3E8. So this provides some expansion beyond the limits of the JVM.
In a more practical note, when you use this scale of time you are talking about geological, evolutionary or cosmological events, so the rest of the data in a date (year, month, day...) is meaningless. It is better if you use a long with the year (or even an int with the eon) and forget about the rest of it.
It looks like somebody was really, really bored (and boring).
Edit: Of course, there is always some crazy problems that can use it, but not real world problems (as in: "if we have a Hanoi Towers with 64 discs and move a disc a second, when would we finish swapping the towers").
I am working with AD via LDAP (using Spring LDAP) and I ran into a odd problem while working with Integer8/LargeInteger being used as timestamps which are outlined here. Namely, my attempts to write to fields of that type have resulted in...
Malformed 'field name here' attribute value
I've tried putting Longs and Strings in hopes that the underlying implementation would do any needed conversions but no luck. Here is how I am doing my math...
/* AD Keeps track of time in 100 NS intervals (UTC) since Jan 1st 1601 */
long winEpocMS = new GregorianCalendar(1601, Calendar.JANUARY, 1).getTimeInMillis();
long nowMS = System.currentTimeMillis();
long winTime100NS = (nowMS - winEpocMS) * 10000;
Is there a easy/elegant way to pack this data correctly? Are there any Java libs prebuilt to handle reading/writing these rather odd time values?
Bonus points to anyone that can explain why we need a 64bit timestamp at the 100NS resolution.
Ok here's the breakdown...
/* time since Jan 1st 1601 00:00:00 UTC */
final long WIN_EPOC_MS = 11644473600000L;
final long now_ms = System.currentTimeMillis();
final long now_win_ns = (now_ms + WIN_EPOC_MS) * 10000L;
The reverse should be obvious from the above code. If you want to double check the convertions use w32tm. For example, the following shows that we have the right convertion time to the Unix epoc (note that I am in CST)
w32tm /ntte 116444736000000000
134774 00:00:00.0000000 - 12/31/1969
06:00:00 PM (local time)
Finally, when working with AD make sure the field accepts any value. Some fields take "-1" to mean "now" and "0" may have special meaning. Also, in some cases it seems to matter if the time attribute modification is bundled with other attribute modifications (such as pwdLastSet and unicodePwd).
One last note, I would avoid GregorianCalendar unless you know you have your timezones right (it's easy to mess up).
I not know any Java library that handle the time with that Microsoft-specific format (100 nanosecond intervals since 1601). I think this ways is correct.
You can define winEpocMS as a constant and use:
long winTime100NS = (System.currentTimeMillis() - winEpocMS) * 10000L;
Why we need 64bit timestamp is simple. With 32bit you got 2^32 values (roughly 4,000,000,000), enough to handle seconds since 1970 until 2038 (know as the 2000-year effect on Unix). If you need microseconds or 100 nanoseconds precision, you use bigger values that have to be managed as 64 bit numbers. Java uses milliseconds since 1970 to represent dates and requires long type that is a signed 64 bit number.