I'm pretty surprised that I haven't yet found a really easy way considering how often ISO8601 is used in JSON.
Basically, I'm taking a string that looks like this: 2014-10-23T00:35:14.800Z and converting it into something like 50 minutes ago.
First, I have to change 2014-10-23T00:35:14.800Zto 2014-10-23'T'00:35:14.800Z, then I need to convert it to milliseconds, then it is easy.
My current code:
private void setTimestamp(String timeCreated) {
int indexOfT = timeCreated.indexOf('T');
String properFormat = new StringBuilder(timeCreated).insert(indexOfT + 1, "'")
.insert(indexOfT, "'")
.toString();
timeStamp = (String) DateUtils.getRelativeTimeSpanString(Long.parseLong(properFormat),
System.currentTimeMillis(),
DateUtils.SECONDS_IN_MILLIS);
}
The culprit is Long.parseLong(properFormat). I need to convert properFormat into milliseconds.
tl;dr
Instant.parse( "2014-10-23T00:35:14.800Z" )
.toEpochMilli()
One-Liner In java.time
The java.time framework is built into Java 8 and later. These new classes supplant the old date-time classes bundled with the earliest versions of Java such as java.util.Date/.Calendar. See Tutorial. The java.time classes also supplant the highly successful Joda-Time library, being built by some of the same folks including being led by the same Stephen Colbourne.
An Instant is a moment on the timeline in UTC with a resolution of nanoseconds. You can ask it for a count of milliseconds from its epoch (first moment of 1970 in UTC). But remember that an Instant may have additional data, nanoseconds being finer than milliseconds. So you may be losing data in that tiny fraction of a fraction of a second.
The java.time classes use standard ISO 8601 formats when parsing/generating strings. No need to specify a formatting pattern. The Instant class can directly parse a string.
Instant.parse( "2014-10-23T00:35:14.800Z" )
You can convert that to a count of milliseconds since the epoch of first moment of 1970 in UTC by calling toEpochMilli
Be aware of possible data loss as the Instant class can hold nanoseconds. So extracting milliseconds will be truncating any microseconds or nanoseconds in any fractional second. Your example string has only three digits in the fractional second, so that is only milliseconds. But six or nine digits of decimal fraction would be truncated to three when converted to a count of milliseconds.
long millisFromEpoch = Instant.parse( "2014-10-23T00:35:14.800Z" ).toEpochMilli();
To get elapsed time in terms of hours-minutes-seconds, use the Duration class. Feed its between method a pair of moments in time.
Duration duration = Duration.between( Instant.parse( "2014-10-23T00:35:14.800Z" ) , Instant.now() );
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
One-Liner In Joda-Time
UPDATE: The Joda-Time project is in maintenance mode, with the team advising migration to the java.time classes.
With the Joda-Time 2.5 library:
long millisSinceEpoch = new DateTime( "2014-10-23T00:35:14.800Z" ).getMillis();
Joda-Time parses and generates ISO 8601 strings by default. Joda-Time works in Android. The java.util.Date/.Calendar classes are notoriously troublesome, confusing, and flawed. Avoid them.
So, turns out the answer was simpler than I would have imagined.
private void setTimestamp(String timeCreated) {
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
try {
Date timeCreatedDate = dateFormat.parse(timeCreated);
timeStamp = (String) DateUtils.getRelativeTimeSpanString(timeCreatedDate.getTime(),
System.currentTimeMillis(),
DateUtils.SECONDS_IN_MILLIS);
} catch ( ParseException e) {}
}
That'll work.
Related
I have extracted accerometer data from a android wearable. While looking at the data i realised the timestamp is not unix covertable. After research i saw the timestamp was actually nanoseconds in uptime. My question is the same as Accelerometer SensorEvent timestamp. However due to me not knowing Java i dont know how convert it using the solutions provided. Is there any python ways i can convert the nanoseconds in uptime into a readable date time format? An example of the timestamp would be "45900482044637".
tl;dr
Duration.ofNanos ( 45_900_482_044_637L )
PT12H45M0.482044637S
java.time
Java 8 and later has a Duration class for this purpose, as part of the new java.time framework (see Tutorial). These new classes have nanosecond resolution (nine decimal places in fractional second). A Duration represents a span of time as a number of hours, minutes, and seconds.
Android currently does not use Java 8 technology, but there is a back-port of java.time to Java 6 & 7. Further adapted to Android in the ThreeTenABP project.
Note the L appended to numeric literal for a long. Also, underscores make lengthy numbers easier for humans to decipher.
long input = 45_900_482_044_637L;
Let's convert that number to a Duration object.
Duration duration = Duration.ofNanos ( input );
When we generate a String representation of that Duration object, we get a String formatted using the ISO 8601 standard. That standard uses the pattern PnYnMnDTnHnMnS where the P marks the beginning and the T separates years-months-days from the hours-minutes-seconds.
System.out.println ( "duration: " + duration );
The answer is twelve hours, forty-five minutes, and a fraction of a second.
duration: PT12H45M0.482044637S
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android, the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
To get the uptime in human-readable format in Python:
>>> from datetime import timedelta
>>> ns = 45900482044637
>>> print(timedelta(microseconds=round(ns, -3) // 1000))
12:45:00.482045
Use:
long millis = TimeUnit.MILLISECONDS.convert(nanosecond, TimeUnit.NANOSECONDS);
Date date = new Date(millis );
DateFormat formatter = new SimpleDateFormat("yyyy/MM/dd hh:mm aaa");
String dateFormatted = formatter.format(date);
I have a date string
String s = "2014-09-01T19:22:43.000Z";
Date date = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ").parse(s);
But I get an exception:
Exception in thread "main" java.text.ParseException: Unparseable date: "2014-09-01T19:22:43.000Z"
How do I convert the above string to unix timestamp?
Thanks
tl;dr
How do I convert the above string to unix timestamp?
Instant.parse( "2014-09-01T19:22:43.000Z" )
.getEpochSecond()
java.time
The java.time.Instant class can parse your input string with its standard ISO 8601 format. No need to specify a formatting pattern.
Instant instant = Instant.parse( "2014-09-01T19:22:43.000Z" );
To get a count of milliseconds since the epoch of 1970:
long millisecondsSinceUnixEpoch = instant.toEpochMilli() ;
For whole seconds since epoch of 1970-01-01T00:00:00Z:
long secondsSinceUnixEpoch = instant.getEpochSecond() ;
Be aware of possible data loss when going to milliseconds or whole seconds. The java.time classes have nanosecond resolution, so any microseconds or nanoseconds present in the value will be truncated.
Joda-Time
Update The Joda-Time project is now in maintenance mode. The team advises migration to the java.time classes.
The Joda-Time library makes this work easier. Your ISO 8601 compliant string can be fed directly to a Joda-Time constructor. The built-in parser expects ISO 8601.
DateTime dateTime = new DateTime( "2014-09-01T19:22:43.000Z" ) ;
Unix Timestamp
What do you mean by a Unix timestamp? Some people mean a count of whole seconds since the first moment of 1970 UTC (the Unix epoch) while ignoring leap seconds (see Unix Time). Some people mean a count of milliseconds or other resolution.
Note the use of a long primitive rather than the more common int.
For milliseconds, call getMillis().
long millisecondsSinceUnixEpoch = dateTime.getMillis();
For whole seconds, divide by 1,000. Consider if you want rounding or truncation of the fractional seconds.
Normally I would suggest passing a DateTimeZone object along with your string to the DateTime constructor. But no need if all you want is a count since epoch.
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android, the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
X is used for ISO 8601 time zone in SimpleDateFormat, not Z
Correct format is "yyyy-MM-dd'T'HH:mm:ss.SSSX"
Is there any method en Date or Calendar class to know the milliseconds remaining from the time of the query to a particular Date object?
I'm using Alarmmanager for reschedule the alarms and would be important for me.
The solucion that I have at the moment is get the milliseconds of the existing object and deduct the current milliseconds.
Any better solution?
Thanks!
If you want how many milliseconds two Date values differ by, that's really easy using Date.getTime:
long millisLeft = target.getTime() - now.getTime();
Yes, Just use the Calenda, This class can give you time in miiliseconds (if that is what you want. So in your case you can just subtract two seperate Calanders. by the way you might also must likly nalso need GregorianCalendar;
ie that is
Calendar timeStamp = new GregorianCalendar();
hope this helps
you can also see one of my projects that uses this at
http://be.net/HARO
see the progague project in java, mostly used in the device,state device, numerical device classes.
tl;dr
ChronoUnit.MILLISECONDS.between( // This enum object offers a method for calculated elapsed time in a particular granularity.
myJavaUtilDateStart.toInstant() , // Convert from legacy class (`java.util.Date`) to modern class (`java.time.Instant`).
myJavaUtilDateStop.toInstant()
) // Returns a long integer.
java.time
The modern approach uses the java.time classes.
Instant
The Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds (up to nine (9) digits of a decimal fraction). This class replaces java.util.Date and java.sql.Timestamp.
Instant instant = Instant.now() ; // Capture current moment in UTC in up to nanosecond resolution.
ChronoUnit.MILLISECONDS
To calculate elapsed time as a count of milliseconds specifically, use ChronoUnit.MILLISECONDS enum object. Beware of data loss, as any microseconds or nanoseconds in the Instant objects will be ignored.
long millisElapsed = ChronoUnit.MILLISECONDS.between( startInstant , stopInstant ) ;
Duration
Java offers a couple classes for represent a span of time unattached to the timeline:
Period for years-months-days.
Duration for hours-minutes-seconds-fractionalSecond.
Example:
Duration d = Duration.between( startInstant , stopInstant ) ;
Generate a String in standard ISO 8601 format by calling Duration::toString.
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android, the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
I have one Calendar object which is as per the user's time zone which may be PST etc, now i want to convert the same to GMT and retain the time i.e. is the calendar initially was set # 00:00:00 at PST it should be converted to 08:00:00 after the conversion taking into consideration the time/date difference . Can someone provide me some help on this.
Appreciate the help in advance.
Thanks,
Vaibhav
Just create a new Calendar in GMT, set the time in that calendar to the same as the original calendar, and you're done:
gmtCalendar.setTime(userCalendar.getTime());
That should be fine, as the getTime() call returns the instant in time (i.e. a java.util.Date with no associated time zone).
As ever though, if you're doing any significant amount of date/time work in Java you should strongly consider using Joda Time instead.
tl;dr
( ( GregorianCalendar ) myCal ) // Cast from a general `Calendar` to specific subclass `GregorianCalendar`.
.toZonedDateTime() // Convert from troublesome legacy class to modern java.time class, `ZonedDateTime`.
.toInstant() // Extract a UTC-specific value, an `Instant` object.
java.time
The modern approach uses java.time classes.
Convert your legacy Calendar object (if GregorianCalendar) to a ZonedDateTime. Call new conversion methods added to the old classes.
GregorianCalendar gc = ( GregorianCalendar ) myCal ;
ZonedDateTime zdt = gc.toZonedDateTime() ;
Now extract an Instant, a value always in UTC. You can think of it this way conteptually: ZonedDateTime = ( Instant + ZoneId )
Instant instant = zdt.toInstant() ;
For more flexibility such as generating strings in various formats, convert to an OffsetDateTime object.
OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ;
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
Using a JDBC driver compliant with JDBC 4.2 or later, you may exchange java.time objects directly with your database. No need for strings nor java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android, the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
How to parse a String in ISO 8601 format with Zulu time?
javax.xml.bind.DatatypeConverter.parseDateTime("2010-12-16T13:33:50.513852Z")
returns
IllegalArgumentException: '2010-12-16T13:33:50.513852Z' weist ein falsches Format auf.
Which mean something like wrong format, anyone have a clue what iss wrong in here?
tl;dr
Instant.parse( "2010-12-16T13:33:50.513852Z" )
java.time
The newer java.time classes can handle this string input.
The Z on the end is short for Zulu and means UTC, an offset of zero +00:00.
Instant
The Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds (up to nine (9) digits of a decimal fraction).
Instant instant = Instant.parse( "2010-12-16T13:33:50.513852Z" );
Time zone
You may want to apply a time zone ZoneId to get a ZonedDateTime. Search Stack Overflow for those class names to learn more, as well as for classes OffsetDateTime and DateTimeFormatter.
Conversion
Best to avoid the troublesome old legacy class of java.util.Date. But if you insist, call the new conversion methods added to the old classes.
java.util.Date date = java.util.Date.from( instant );
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
Where to obtain the java.time classes?
Java SE 8 and SE 9 and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
The ThreeTenABP project adapts ThreeTen-Backport (mentioned above) for Android specifically.
See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
It works for me try ide online
Output is :
java.util.GregorianCalendar[time=?,areFieldsSet=false,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="GMT+00:00",offset=0,dstSavings=0,useDaylight=false,transitions=0,lastRule=null],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2010,MONTH=11,WEEK_OF_YEAR=1,WEEK_OF_MONTH=1,DAY_OF_MONTH=16,DAY_OF_YEAR=1,DAY_OF_WEEK=5,DAY_OF_WEEK_IN_MONTH=1,AM_PM=0,HOUR=0,HOUR_OF_DAY=13,MINUTE=33,SECOND=50,MILLISECOND=513,ZONE_OFFSET=0,DST_OFFSET=0]
If the target Data Type is "ZonedDateTime", you can use the date-formatter "yyyy-MM-dd'T'HH:mm:ss.SSSSSSX". Example code as follows:
public ZonedDateTime convertStringToZonedDateTime() {
String inputString = "2010-12-16T13:33:50.513852Z";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSSSSX");
ZonedDateTime zdt = ZonedDateTime.parse(inputString, formatter);
return zdt; //Output ZonedDateTime object is 2010-12-16T13:33:50.513852Z
}
Attention! If the input date-String has 0 as second and milli-second, for example "2010-12-16T13:00:00.000000Z", then the output ZonedDateTime object is "2010-12-16T13:00Z", even through it looks strange without second and milli-second, it is still a leagl ZonedDateTime.
If the target Data Type is "Instant":
public Instant convertStringToInstant() {
String inputString = "2010-12-16T13:33:50.513852Z";
Instant instant = Instant.parse(inputString);
return instant; //Output Instant object is 2010-12-16T13:33:50.513852Z
}
The code you posted works fine in my jre. Probably you defined your own DatatypeConverter (with german exception texts...!) and this specific DatatypeConverter cannot parse this date.
Do a codesearch for this code: DatatypeConverter.setDatatypeConverter( - there you will probably find your custom implementation of the "DatatypeConverterInterface" - which will then probably lead you to your bug.
Alternatively you can search for weist ein falsches Format auf. (because that exception text is not part of the jre)
Viel Erfolg ;)