How do I store time in a variable? - java

One of my classes Event will have an instance field which is called timeStamp. Now, I have another class which will set the timeStamp according to some other algorithm which is not really relevant here.
My question is what type should I store this timeStamp in? From what I've researched so far I have the impression that it should be calculated in milliseconds and thus store it in a double perhaps.
Basically the Clock class I have simulates time in the following format : hh:mm:ss. However, since it's a discrete event simulation that I'm developing it jumps from event to event, which it determines by timeStamp value i.e. each event object has a timeStamp value which is stored in a PrioityQueue. So I thought about storing the timeStamp in the same format as the Clock , which I guess would involve me creating a new class TimeStamp that then becomes the type of the timestamp. Or should I just make the clock simulate time in milliseconds?
What are your thoughts on this? I'm not sure on the most efficient/clean way to implement this.

When a date is stored as milliseconds since the epoch, you should use a long.
There's no need for a double, since you're not interested in fractions of a millisecond.
You can't use an int because the maximum int value is only large enough to represent approximately one month in millis.
You can get such a value like this:
long millisSinceEpoch = Calendar.getInstance().getTimeInMillis();

Store the milliseconds in a long.
You can use the DateTime class in Joda Time to perform all sorts of intricacies on the resulting number. This overload allows you to plug the milliseconds value directly into a DateTime object.

Related

Java - Store amount of time (not interval)

I work with an spring4 webapp that needs the logic of storing and calculating an amount of time(hours and minutes), but it isn't an interval since the amount is inserted by user or retrieved by third part app with the HH:MM format.
By now it's done with Float values which I want to change because in float the minutes are in 100 base, and not in 60 base as it's correct.
I've tried the java.time.LocalTime but it doesn't work since it's not acceptable more than 24 hrs.
I think there may be a cleaner way to deal with it.
Thanks in advance
-----EDIT
This webapp calculate overtime work. The user inputs the amount of hours the employee have worked off contractual time.
At the moment it is mapped as a float field, which is converted an calculated as below:
float hours = //Conversion of the HH:MM string input to HH.MM float within the framework
valueToPay = hours * employee.getHourSalary();
This way isn't right because the minutes are not being calculated correctly. I could convert the entire time to amount of minutes, but I'm searching for a cleaner way, since the java.time API offers a lot.
LocalTime is for time of the day.
If you need a ducation, you have java.time.Duration. For example, a duration of 30 hours (which would not fit in a LocalTime):
Duration thirtyHours = Duration.ofHours(30);
use org.joda.time.Duration
from javadoc:
An immutable duration specifying a length of time in milliseconds.
A duration is defined by a fixed number of milliseconds. There is no concept of fields, such as days or seconds, as these fields can vary in length. A duration may be converted to a Period to obtain field values. This conversion will typically cause a loss of precision however.
Duration is thread-safe and immutable.

Time handling with timestamp and offset

I'm creating a custom data type that needs to store a set of exact timestamps (to millisecond accuracy) in a way that is both efficient and correct. I'm not particularly famiilar with the intricacies of timestamp handling so thought I would ask here for some wise advice.
I can see many options:
Store a Joda Instant for every timestamp.
Store a Joda DateTime for every timestamp.
Store a single Joda DateTime object once for the data type, and have a long offset for all the other timestamps relative to the main DateTime
Express every timestamp as a long offset to a fixed point (e.g. the Unix epoch of 1970-01-01T00:00:00Z )
.....other combinations.....
Questions:
What is the best way to store a sequence of timestamps?
What are the key tradeoffs?
Any pitfalls to watch out for?
Each of your storage options makes sense, and it's nice to see all of your options are with actual instants and never local datetimes (e.g., without time zones).
Your custom class will really be defined by its interface, so if you choose to store longs (epoch offsets) you can always provide interface methods to get the values from the sequence (and I assume other things like "deltas" -- or intervals, durations, or periods in Joda-speak) in human readable datetimes and periods if you like.
As you asked a number of questions, involving trade-offs, here's what I can offer:
Storing a sequence of longs is the most space-efficient.
Longs are not really as bad as you might think, since if your interface methods want to return datetimes, you just pass the long to the DateTime constructor.
Instants are thin wrappers over longs and provide convenience methods if you need to add durations to them or compute durations from instants; your code might look a little nicer than if you do your own math on longs and then construct a DateTime or Period or Duration around them.
DateTimes are great if you don't have excessive storage requirements and the actual date and time-of-day matter to the clients of your custom data type. Will your users care that a timestamp is on October 10th at 16:22 in the America/Los Angeles time zone? Or is the duration between the timestamps all that matter?
Storing a datetime or instant plus an array of offsets looks like a messy implementation since there are two concepts in play. I would think storing a single sequence of instants/datetimes only, and not mixing in durations, make a lot more sense. If you need to work with durations, just compute them in your interface methods.
I would say the only pitfalls to watch out for involve dealing with time zones if you are storing longs and your clients need to be thinking in datetimes.
In terms of tradeoffs, I only really see that longs, being primitive, save space, and I would guess a miniscule amount of time since DateTimes are objects and there is all that heap allocation and deallocation that takes place. But again, unless you are severely memory-constrained, I would say the best thing is to store DateTimes. Joda-Time can do all the time zone management for you. The parsing and formatting routines are easy and thread-safe. There are tons of convenience methods in place. And you won't have to do any conversion of your own from datetimes to longs. Storing longs only feels like a premature optimzation to me. Strangely enough, FWIW, I would probably do that in Python, since Python's datetime objects are naive, rather than timezone-aware, by default! Jada-Time makes IMHO a very nice and easy to understand distinction between Instants and Local DateTimes, so sticking with DateTimes everywhere will be, I believe, your best bet.

Want to get minutes between two ISO 8601 times in two different time zones with joda

I have two strings from an android application in ISO 8601 format that I am trying to find the amount of minutes in between the two times. I was pointed to Joda Time which has been immensely helpful. However I have discovered now that one String is in UTC time and the other is my local time.
For example
"2012-05-11T02:34:18+00:00" is UTC and
"2012-05-10T21:44:09-05:00" is my local time
I have the following block of code which finds the number of minutes between the two times. My question is how can I go about to change the UTC time to my local time in order to get an accurate minutes in between
DateTime start = new DateTime(currentTime);
DateTime end = new DateTime(laterTime);
int min = Minutes.minutesBetween(start,end).getMinutes();
How do I go about to change the UTC time to my local time in order to get an accurate minutes in between?
My understanding is that you don't need to.
A DateTime instance represents a point on the time line, together with a timezone which controls how the time-point is mapped to a time frame (e.g. when you call the getters). When you take a time difference between a pair of DateTime instance, you get a measure representing the duration between two points on the timeline. This is independent of the timezones.
In other words, assuming that the two DateTime instances were created properly, your code should work as-is.

Time stamp class in org.apache.commons.net package

I want to use time stamp as part of my application(I am using JAVA).I was asked to use Network Time Protocol(NTP).I have searched in google and I was able to find a package "org.apache.commons.net" where there is a TimeStamp class.I have gone through this link to know more about the class.
What should I pass to the constructors of this class(what is the significance of each constructor). Actually TS class should return us the time stamp,instead it is asking to input time stamp.I am confused with that.
You can use the following overload of the constructor to create the TimeStamp Object.
public TimeStamp(Date d)
pass an object of java.util.Date as argument.
This will give you a timestamp value which is represented as a
64-bit unsigned fixed-point number in seconds relative to 0-hour on 1-January-1900.
The main significance is that it is a protocol, a standard followed by different systems. Different systems present in a network may not have their clock synchronized, and may not understand how others are measuring time, may follow different time zones. using NTP they synchronize their clock to UTC
You can use the static getCurrentTime() to get a timestamp that represents the current time measured to the nearest milliseconds:
Timestamp myTs = Timestamp.getCurrentTime();

How to determine if a timestamp is within working hours?

Given a any unix timestamp (i.e. 1306396801) which translates to 26.05.2011 08:00:01, how can I determine if this is within a given timeframe (i.e. 08:00:00 and 16:00:00)?
This needs to work for any day. I just want to know if this timestamp is within the given time-interval, on any future (or past) day, the date is unimportant. I don't care if it is on the 25th or 26th, as long as it is between 08:00 and 16:00.
I am on the lookout for a java solution, but any pseudo code that works will be ok, I'll just convert it.
My attempts so far has been converting it to a java Calendar, and reading out the hour/min/sec values and comparing those, but that just opened up a big can of worms. If the time interval I want it between is 16.30, I can't just check for tsHour > frameStartHour && tsMin > frameStartMin as this will discard any timestamps that got a minute part > 30.
Thank you for looking at this :)
To clarify.
I am only using and referring to UTC time, my timestamp is in UTC, and the range I want it within is in UTC.
I think I understand what you want. You want to test for any day, if it's between 8am and 4pm UTC. Take the timestamp mod 24*3600. This will give you the number of seconds elapsed in the day. Then you just compare that it's between 8*3600 and 16*3600. If you need to deal with timezones, things get more complicated.
Given your timestamp (in seconds) and the desired time zone, Jodatime gives you the hour which leads you to a simple integer range check.
new org.joda.time.DateTime(timestamp*1000L, zone).getHourOfDay()
With java.util.* its more difficult.
If I understood you correctly, you only need to normalize your dates to some common value. Create three instances of Calendar - one with your time, but day, month, and year set to zero, and two with start and end of your timeframe, other fields also zeroed. Then you can use Calendar.after() and Calendar.before() to see if the date is within the range.
Your unix timestamp is an absolute time. Your time frame is relative. You need some kind of time zone information in order to solve this problem. I just answered some of this for PostgreSQL a few minutes ago. Hopefully that article is of use.
Convert the beginning of your range to a unix timestamp, and the end of your range to a unix tmestamp, then it's a simple integer check.

Categories