Text cannot be parsed to a Duration in java8 - java

I am trying to parse a text to duration as follow:
final Duration duration = TimeUtil.parseDuration("1.0:00:00");
But I get the following error,
Text cannot be parsed to a Duration
so can anyone tells me where my problem is?

If you are using protocol buffers' TimeUtil you specify a duration with seconds separated from nanoseconds by a period. The value may be lead by a minus sign, if the duration is negative (so that adding the duration to a time would move into the past relative to the time). The string must end in "s".
You can see the pretty simple parse and toString of a protocol buffer's duration in the public git[hub] repo's TimeUtil.
Given the type of duration, I'm guessing they're used for calculations on date-times that are internally represented as signed 64 bit nano seconds since unix epoch.
In other words it looks like these are valid durations:
"1s" // one second forward
"1.0s" // one second forward
"1.01s" // one second, 10,000,000 nano seconds forward
"-1.01s" // one second, 10,000,000 nano seconds backward
"60s" // one minute forward
"-86400s" // yesterday (one day backward)
// [assuming no daylight saving changes or leap seconds happened]
The Protocol Buffers' TimeUtil.parseDuration would not give you the error message you say you got, and is not at all like Duration.parse, which is more clearly documented and might give that kind of error message.

If guessed API:
parseDuration(String duration) takes as parameters:
duration - "3h" or "2mn" or "7s" or null.
Taken from java.lang.Object ninja.utils.TimeUtil API. It returns the number of seconds.
Then "1.0:00:00" is obviously not to be parsed.

Related

How to indicate some fields are not supported

Trying to move from Calendar to the new Java 8 time on Android. Is there a way to indicate that a time or date field is not supported? I can use the 'Truncate' method that will set all time fields of a shorter duration to zero, so a time stamp like 2020-09-30T10:37:15.345-04:00 can be truncated say at the minutes level. But that will leave 2020-09-30T10:00:00.00-04:00.
However, what I want to indicate is that the clock does not have minutes or less precision so that when one tries to read the minutes or seconds, there will be some indication that there are no such fields or that they are unknown. Zero is a valid value.
Right now in the Calendar case I have to add numerous methods to a class to indicate that. For example, I made a class called TimeStruct which wraps a Calendar. If I take a time stamp like 2020-10-01T04:55 it does not have minutes. So to keep that information I have a variable 'isSecondsSet' and set it to false. I create the Calendar from the elements I DO have. But as soon as I call something like Calendar.getTimeInMillis() the seconds and milliseconds fields get set to 0 and are indicated as set. So my additional variables let me know that there was no seconds field.
I was hoping that the new classes would no longer require me to keep my own indicators and I would also be able to parse something like 2020-10-01T04:55. I could not, but I could parse a full time stamp. So if I do that and truncate, can I indicate that the truncated fields are not supported? That way I wont use a value of 0 in the seconds.

Store android timestamp value in millisecond without losing its precission in a string variable

Hi all i am trying to store android current timestamp value in a string variable without losing its precision but i am losing last 3 digits when i try to print timeStamps value. Actually its having 13 digits but only 10 digits getting printed.
String timeStamp = String.valueOf(TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis()));
I got the above snippet from this answer I am in the process to get the recently updated contacts based on CONTACT_LAST_UPDATED_TIMESTAMP for which precision seems important.Please guide me
The documentation says that CONTACT_LAST_UPDATED_TIMESTAMP is:
Timestamp (milliseconds since epoch) of when this contact was last updated
System.currentTimeMillis() returns the milliseconds since epoch representing the current time.
Your primary problem is that you are converting milliseconds to seconds, which is unnecessary and incorrect for this use case.
Your secondary problem is that you are converting the value to a String, which AFAIK should not be necessary for this particular column.
So, just use System.currentTimeMillis(), without any conversions.

How can I find out the exact time if the access to the network is not permanent?

It takes UTC + 0 for the application to work, but the exact minutes and seconds are needed.
Since access to the network is not permanent, The exact time can not always be determined. If the method is still like that, determine the exact time.
If your application is dependent on the network time, what you can do is the following.
When network becomes available:
use the network to get the time
get system time
calculate the difference
store the difference
use the network time
When network is not available:
get the stored difference
get system time
calculate the needed time
use the calculated time
use System.currentTimeMillis() to get current timestamp and then convert it to minutes with following method
public long getCurrentMinOfHour()
{
Calendar c = Calendar.getInstance();
c.setTimeInMillis(System.currentTimeMillis());
return (long)((c.get(Calendar.MINUTE) * 60 * 1000)) ;
}

Why don't the timestamps in Java and Wireshark match?

In Java I am getting a timestamp this way:
Date date= new java.util.Date();
return (new Timestamp(date.getTime())).toString();
Output is for example:
Start - 2015-02-16 13:59:41.427
Then I write a packet to a socket.
However, in Wireshark, the first packet is dated as follows:
62 2015-02-16 13:59:41.421115000 ...
What???
Ok, I don't want someone to tell me the timestamps are off. Is there a way to change the Java code to make it produce timesstamp that are more in line with Wireshark?
Thanks
EDIT: Code Requested
System.err.println("Start - "+currentTimestamp());
int sent = socketChannelOut.write(data);
I suspect this is simply down to the to the accuracy of how your system measures time. To quote from the java doc:
"Returns the current time in milliseconds. Note that while the unit of
time of the return value is a millisecond, the granularity of the
value depends on the underlying operating system and may be larger.
For example, many operating systems measure time in units of tens of
milliseconds."
Since the discrepancy you are seeing is 0.005885s and this is less than 10ms I do not think there is an expectation that a comparison with another process measuring time will be accurate to less than 10ms granularity. Which is to say this time 41.427 that you got from Java is really 41.427 +/-10ms

Working with MS's Integer8/LargeInteger in Java?

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.

Categories

Resources